Skip to content

Commit 214e668

Browse files
committed
fix: handle suggestions in helper function outside rule or inside nested spread/ternary in require-meta-has-suggestions rule
1 parent 9b8b29f commit 214e668

File tree

4 files changed

+81
-26
lines changed

4 files changed

+81
-26
lines changed

lib/rules/require-meta-fixable.js

+3-7
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,9 @@ module.exports = {
5353
let contextIdentifiers;
5454
let usesFixFunctions;
5555

56-
// ----------------------------------------------------------------------
57-
// Helpers
58-
// ----------------------------------------------------------------------
59-
60-
// ----------------------------------------------------------------------
61-
// Public
62-
// ----------------------------------------------------------------------
56+
if (!ruleInfo) {
57+
return {};
58+
}
6359

6460
return {
6561
Program(ast) {

lib/rules/require-meta-has-suggestions.js

+40-19
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,33 @@ module.exports = {
3535
let contextIdentifiers;
3636
let ruleReportsSuggestions;
3737

38+
/**
39+
* Check if a "suggest" object property from a rule violation report should be considered to contain suggestions.
40+
* @param {Node} node - the "suggest" object property to check
41+
* @returns {boolean} whether this property should be considered to contain suggestions
42+
*/
43+
function doesPropertyContainSuggestions(node) {
44+
const staticValue = getStaticValue(node.value, context.getScope());
45+
if (
46+
!staticValue ||
47+
(Array.isArray(staticValue.value) && staticValue.value.length > 0) ||
48+
(Array.isArray(staticValue.value) &&
49+
staticValue.value.length === 0 &&
50+
node.value.type === 'Identifier') // Array variable can have suggestions pushed to it.
51+
) {
52+
// These are all considered reporting suggestions:
53+
// suggest: [{...}]
54+
// suggest: getSuggestions()
55+
// suggest: MY_SUGGESTIONS
56+
return true;
57+
}
58+
return false;
59+
}
60+
61+
if (!ruleInfo) {
62+
return {};
63+
}
64+
3865
return {
3966
Program(ast) {
4067
contextIdentifiers = utils.getContextIdentifiers(scopeManager, ast);
@@ -52,28 +79,22 @@ module.exports = {
5279
const suggestProp = utils
5380
.evaluateObjectProperties(node.arguments[0], scopeManager)
5481
.find((prop) => utils.getKeyName(prop) === 'suggest');
55-
if (suggestProp) {
56-
const staticValue = getStaticValue(
57-
suggestProp.value,
58-
context.getScope()
59-
);
60-
if (
61-
!staticValue ||
62-
(Array.isArray(staticValue.value) &&
63-
staticValue.value.length > 0) ||
64-
(Array.isArray(staticValue.value) &&
65-
staticValue.value.length === 0 &&
66-
suggestProp.value.type === 'Identifier') // Array variable can have suggestions pushed to it.
67-
) {
68-
// These are all considered reporting suggestions:
69-
// suggest: [{...}]
70-
// suggest: getSuggestions()
71-
// suggest: MY_SUGGESTIONS
72-
ruleReportsSuggestions = true;
73-
}
82+
if (suggestProp && doesPropertyContainSuggestions(suggestProp)) {
83+
ruleReportsSuggestions = true;
7484
}
7585
}
7686
},
87+
Property(node) {
88+
// In order to reduce false positives, we will also check for a `suggest` property anywhere in the file.
89+
// This is helpful especially in the event that helper functions are used for reporting violations.
90+
if (
91+
node.key.type === 'Identifier' &&
92+
node.key.name === 'suggest' &&
93+
doesPropertyContainSuggestions(node)
94+
) {
95+
ruleReportsSuggestions = true;
96+
}
97+
},
7798
'Program:exit'() {
7899
const metaNode = ruleInfo && ruleInfo.meta;
79100
const hasSuggestionsProperty = utils

tests/lib/rules/require-meta-fixable.js

+2
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ ruleTester.run('require-meta-fixable', rule, {
212212
`,
213213
options: [{ catchNoFixerButFixableProperty: true }],
214214
},
215+
// No rule present.
216+
`const foo = { fix: [{}]}; context.report({node,message,fix});`,
215217
],
216218

217219
invalid: [

tests/lib/rules/require-meta-has-suggestions.js

+36
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,40 @@ ruleTester.run('require-meta-has-suggestions', rule, {
134134
}
135135
};
136136
`,
137+
// Provides suggestions, helper function outside rule.
138+
`
139+
function report() {
140+
context.report({ node, message, suggest: [{}] });
141+
}
142+
module.exports = {
143+
meta: { hasSuggestions: true },
144+
create(context) {
145+
report();
146+
}
147+
};
148+
`,
149+
// Provides suggestions, with complex spread/ternary in reporting.
150+
`
151+
module.exports = {
152+
meta: { hasSuggestions: true },
153+
create(context) {
154+
context.report({
155+
node: node.id,
156+
messageId: 'noEmptyWithSuper',
157+
...(useAutoFix
158+
? { fix }
159+
: {
160+
suggest: [
161+
{
162+
messageId: 'noEmptyWithSuper',
163+
fix,
164+
},
165+
],
166+
}),
167+
});
168+
}
169+
};
170+
`,
137171
// Provides *dynamic* suggestions, has hasSuggestions property.
138172
`
139173
module.exports = {
@@ -205,6 +239,8 @@ ruleTester.run('require-meta-has-suggestions', rule, {
205239
}
206240
};
207241
`,
242+
// No rule present.
243+
`const foo = { suggest: [{}]}; context.report({node,message,suggest});`,
208244
],
209245

210246
invalid: [

0 commit comments

Comments
 (0)