Skip to content

Commit 05205be

Browse files
authored
Add support for destructuring to no-nonstandard-*-properties rules (#220)
1 parent ab5bbd7 commit 05205be

File tree

2 files changed

+87
-19
lines changed

2 files changed

+87
-19
lines changed

lib/util/define-nonstandard-properties-handler/index.js

Lines changed: 79 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,35 +36,95 @@ function defineNonstandardPropertiesHandler(
3636
}
3737
map[READ] = true
3838
}
39+
const sourceCode = getSourceCode(context)
40+
41+
/**
42+
* @param {import("estree").ObjectPattern} node
43+
*/
44+
function* extractNonstandardProperties(node) {
45+
for (const prop of node.properties) {
46+
if (prop.type !== "Property") {
47+
continue
48+
}
49+
const propertyName = getPropertyName(
50+
prop,
51+
sourceCode.getScope(node),
52+
)
53+
if (propertyName == null || propertyNamesSet.has(propertyName)) {
54+
continue
55+
}
56+
yield { node: prop, propertyName }
57+
}
58+
}
59+
60+
/**
61+
* @param {import("estree").Node} node
62+
* @param {string[]} path
63+
* @param {string} propertyName
64+
*/
65+
function report(node, path, propertyName) {
66+
context.report({
67+
node,
68+
messageId: "forbidden",
69+
data: { name: [...path, propertyName].join(".") },
70+
})
71+
}
72+
3973
return {
4074
"Program:exit"(program) {
41-
const sourceCode = getSourceCode(context)
4275
const tracker = new ReferenceTracker(sourceCode.getScope(program))
4376
for (const { node, path } of tracker.iterateGlobalReferences(
4477
traceMap,
4578
)) {
46-
if (
47-
node.parent.type !== "MemberExpression" ||
48-
node.parent.object !== node
49-
) {
79+
/** @type {import("estree").Node | null} */
80+
const parent = node.parent
81+
if (!parent) {
5082
continue
5183
}
52-
const propertyName = getPropertyName(
53-
node.parent,
54-
sourceCode.getScope(node),
55-
)
56-
if (
57-
propertyName == null ||
58-
propertyNamesSet.has(propertyName)
59-
) {
84+
if (parent.type === "MemberExpression") {
85+
if (parent.object !== node) {
86+
continue
87+
}
88+
const propertyName = getPropertyName(
89+
parent,
90+
sourceCode.getScope(node),
91+
)
92+
if (
93+
propertyName == null ||
94+
propertyNamesSet.has(propertyName)
95+
) {
96+
continue
97+
}
98+
report(parent, path, propertyName)
99+
} else if (parent.type === "VariableDeclarator") {
100+
if (
101+
parent.init !== node ||
102+
parent.id.type !== "ObjectPattern"
103+
) {
104+
continue
105+
}
106+
for (const {
107+
node: reportNode,
108+
propertyName,
109+
} of extractNonstandardProperties(parent.id)) {
110+
report(reportNode, path, propertyName)
111+
}
112+
} else if (parent.type === "AssignmentExpression") {
113+
if (
114+
parent.right !== node ||
115+
parent.left.type !== "ObjectPattern"
116+
) {
117+
continue
118+
}
119+
for (const {
120+
node: reportNode,
121+
propertyName,
122+
} of extractNonstandardProperties(parent.left)) {
123+
report(reportNode, path, propertyName)
124+
}
125+
} else {
60126
continue
61127
}
62-
63-
context.report({
64-
node,
65-
messageId: "forbidden",
66-
data: { name: [...path, propertyName].join(".") },
67-
})
68128
}
69129
},
70130
}

tests/lib/rules/no-nonstandard-array-properties.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,13 @@ new RuleTester().run("no-nonstandard-array-properties", rule, {
2222
code: "Array.bar",
2323
errors: ["Non-standard 'Array.bar' property is forbidden."],
2424
},
25+
{
26+
code: "const { foo } = Array;",
27+
errors: ["Non-standard 'Array.foo' property is forbidden."],
28+
},
29+
{
30+
code: ";({ foo } = Array);",
31+
errors: ["Non-standard 'Array.foo' property is forbidden."],
32+
},
2533
],
2634
})

0 commit comments

Comments
 (0)