Skip to content

Commit 409d4eb

Browse files
authored
Resolve nested scopes correctly by extracting correct template of… (#71)
1 parent fb75d12 commit 409d4eb

File tree

2 files changed

+67
-6
lines changed

2 files changed

+67
-6
lines changed

Diff for: lib/util/getUsedVariablesInPug.js

+12-6
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ const getUsedVariablesInPug = (template = '') => {
9191
codeStartsAt = relatedLine.indexOf(codeFragment)
9292
}
9393
}
94+
9495
traverse(ast, {
9596
Identifier(path) {
9697
const loc = buildLocation(
@@ -115,6 +116,13 @@ const getUsedVariablesInPug = (template = '') => {
115116
loc,
116117
{ isSpreadElement: true },
117118
))
119+
} else {
120+
usedVariables.push(buildVariable(
121+
path.node.name,
122+
getFullName(path),
123+
loc,
124+
{ isSpreadElement: false },
125+
))
118126
}
119127
},
120128

@@ -138,11 +146,7 @@ const getUsedVariablesInPug = (template = '') => {
138146
},
139147
})
140148

141-
const lastAddedVariable = usedVariables[usedVariables.length - 1]
142-
143-
// If we define a scope with a variable connected to props in that definition,
144-
// we also mark all vars in that scope as used
145-
if (token.type === 'each' && lastAddedVariable) {
149+
if (token.type === 'each') {
146150
const getLastTokenInScope = (all, start) => {
147151
const startIndex = all.findIndex(item => item === start)
148152
const lastToken = all.slice(startIndex).find(item => item.type === 'outdent' && item.loc.end.column <= start.loc.start.column)
@@ -154,7 +158,7 @@ const getUsedVariablesInPug = (template = '') => {
154158
const endToken = getLastTokenInScope(tokens, startToken)
155159

156160
const bodyLines = [''].concat(lines.slice(startToken.loc.start.line, endToken.loc.end.line - 1))
157-
const body = bodyLines.join('\n')
161+
const body = bodyLines.concat('\n').join('\n')
158162

159163
const variablesInScope = getUsedVariablesInPug(body)
160164
.filter(item => item.allNames.length > 1 || item.extra.isSpreadElement === true)
@@ -175,6 +179,8 @@ const getUsedVariablesInPug = (template = '') => {
175179
: item.allNames,
176180
}))
177181

182+
const lastAddedVariable = usedVariables[usedVariables.length - 1]
183+
178184
variablesInScope.forEach((item) => {
179185
const allNames = item.allNames[0] === '__COMPUTED_PROP__' && item.allNames.length > 1
180186
? lastAddedVariable.allNames.concat(item.allNames)

Diff for: tests/lib/rules/prop-types.js

+55
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,22 @@ const cases = [
603603
}
604604
`,
605605
},
606+
{
607+
code: `
608+
function Component(props) {
609+
return pug\`
610+
each item in props.list
611+
each inside in item
612+
= inside.a
613+
\`
614+
}
615+
Component.propTypes = {
616+
list: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.shape({
617+
a: PropTypes.test,
618+
})))
619+
}
620+
`,
621+
},
606622
],
607623
invalid: [
608624
{
@@ -727,6 +743,45 @@ const cases = [
727743
buildError([11, 25], [11, 41], buildUnusedMessage('list.*.anything')),
728744
],
729745
},
746+
{
747+
code: `
748+
function Component(props) {
749+
return pug\`
750+
each item in props.list
751+
each inside in item
752+
each second in inside
753+
= second.a
754+
\`
755+
}
756+
Component.propTypes = {
757+
list: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.shape({}))))
758+
}
759+
`,
760+
errors: [
761+
buildError([7, 30], [7, 31], buildMissingMessage('list[][][].a')),
762+
],
763+
},
764+
{
765+
code: `
766+
function Component(props) {
767+
return pug\`
768+
each item in props.list
769+
each inside in item
770+
each second in inside
771+
= second.a
772+
\`
773+
}
774+
Component.propTypes = {
775+
list: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.shape({
776+
a: PropTypes.string,
777+
b: PropTypes.string,
778+
}))))
779+
}
780+
`,
781+
errors: [
782+
buildError([13, 18], [13, 34], buildUnusedMessage('list.*.*.*.b')),
783+
],
784+
},
730785
],
731786
},
732787

0 commit comments

Comments
 (0)