eslint 8.49.0 → 8.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/config/flat-config-schema.js +11 -1
- package/lib/linter/linter.js +172 -57
- package/lib/rule-tester/flat-rule-tester.js +50 -5
- package/lib/rule-tester/rule-tester.js +78 -20
- package/lib/rules/array-callback-return.js +139 -14
- package/lib/rules/index.js +1 -0
- package/lib/rules/no-misleading-character-class.js +65 -15
- package/lib/rules/no-new-object.js +7 -0
- package/lib/rules/no-object-constructor.js +118 -0
- package/lib/source-code/source-code.js +350 -3
- package/package.json +2 -2
@@ -136,6 +136,76 @@ function getArrayMethodName(node) {
|
|
136
136
|
return null;
|
137
137
|
}
|
138
138
|
|
139
|
+
/**
|
140
|
+
* Checks if the given node is a void expression.
|
141
|
+
* @param {ASTNode} node The node to check.
|
142
|
+
* @returns {boolean} - `true` if the node is a void expression
|
143
|
+
*/
|
144
|
+
function isExpressionVoid(node) {
|
145
|
+
return node.type === "UnaryExpression" && node.operator === "void";
|
146
|
+
}
|
147
|
+
|
148
|
+
/**
|
149
|
+
* Fixes the linting error by prepending "void " to the given node
|
150
|
+
* @param {Object} sourceCode context given by context.sourceCode
|
151
|
+
* @param {ASTNode} node The node to fix.
|
152
|
+
* @param {Object} fixer The fixer object provided by ESLint.
|
153
|
+
* @returns {Array<Object>} - An array of fix objects to apply to the node.
|
154
|
+
*/
|
155
|
+
function voidPrependFixer(sourceCode, node, fixer) {
|
156
|
+
|
157
|
+
const requiresParens =
|
158
|
+
|
159
|
+
// prepending `void ` will fail if the node has a lower precedence than void
|
160
|
+
astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression", operator: "void" }) &&
|
161
|
+
|
162
|
+
// check if there are parentheses around the node to avoid redundant parentheses
|
163
|
+
!astUtils.isParenthesised(sourceCode, node);
|
164
|
+
|
165
|
+
// avoid parentheses issues
|
166
|
+
const returnOrArrowToken = sourceCode.getTokenBefore(
|
167
|
+
node,
|
168
|
+
node.parent.type === "ArrowFunctionExpression"
|
169
|
+
? astUtils.isArrowToken
|
170
|
+
|
171
|
+
// isReturnToken
|
172
|
+
: token => token.type === "Keyword" && token.value === "return"
|
173
|
+
);
|
174
|
+
|
175
|
+
const firstToken = sourceCode.getTokenAfter(returnOrArrowToken);
|
176
|
+
|
177
|
+
const prependSpace =
|
178
|
+
|
179
|
+
// is return token, as => allows void to be adjacent
|
180
|
+
returnOrArrowToken.value === "return" &&
|
181
|
+
|
182
|
+
// If two tokens (return and "(") are adjacent
|
183
|
+
returnOrArrowToken.range[1] === firstToken.range[0];
|
184
|
+
|
185
|
+
return [
|
186
|
+
fixer.insertTextBefore(firstToken, `${prependSpace ? " " : ""}void ${requiresParens ? "(" : ""}`),
|
187
|
+
fixer.insertTextAfter(node, requiresParens ? ")" : "")
|
188
|
+
];
|
189
|
+
}
|
190
|
+
|
191
|
+
/**
|
192
|
+
* Fixes the linting error by `wrapping {}` around the given node's body.
|
193
|
+
* @param {Object} sourceCode context given by context.sourceCode
|
194
|
+
* @param {ASTNode} node The node to fix.
|
195
|
+
* @param {Object} fixer The fixer object provided by ESLint.
|
196
|
+
* @returns {Array<Object>} - An array of fix objects to apply to the node.
|
197
|
+
*/
|
198
|
+
function curlyWrapFixer(sourceCode, node, fixer) {
|
199
|
+
const arrowToken = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken);
|
200
|
+
const firstToken = sourceCode.getTokenAfter(arrowToken);
|
201
|
+
const lastToken = sourceCode.getLastToken(node);
|
202
|
+
|
203
|
+
return [
|
204
|
+
fixer.insertTextBefore(firstToken, "{"),
|
205
|
+
fixer.insertTextAfter(lastToken, "}")
|
206
|
+
];
|
207
|
+
}
|
208
|
+
|
139
209
|
//------------------------------------------------------------------------------
|
140
210
|
// Rule Definition
|
141
211
|
//------------------------------------------------------------------------------
|
@@ -151,6 +221,9 @@ module.exports = {
|
|
151
221
|
url: "https://eslint.org/docs/latest/rules/array-callback-return"
|
152
222
|
},
|
153
223
|
|
224
|
+
// eslint-disable-next-line eslint-plugin/require-meta-has-suggestions -- false positive
|
225
|
+
hasSuggestions: true,
|
226
|
+
|
154
227
|
schema: [
|
155
228
|
{
|
156
229
|
type: "object",
|
@@ -162,6 +235,10 @@ module.exports = {
|
|
162
235
|
checkForEach: {
|
163
236
|
type: "boolean",
|
164
237
|
default: false
|
238
|
+
},
|
239
|
+
allowVoid: {
|
240
|
+
type: "boolean",
|
241
|
+
default: false
|
165
242
|
}
|
166
243
|
},
|
167
244
|
additionalProperties: false
|
@@ -172,13 +249,15 @@ module.exports = {
|
|
172
249
|
expectedAtEnd: "{{arrayMethodName}}() expects a value to be returned at the end of {{name}}.",
|
173
250
|
expectedInside: "{{arrayMethodName}}() expects a return value from {{name}}.",
|
174
251
|
expectedReturnValue: "{{arrayMethodName}}() expects a return value from {{name}}.",
|
175
|
-
expectedNoReturnValue: "{{arrayMethodName}}() expects no useless return value from {{name}}."
|
252
|
+
expectedNoReturnValue: "{{arrayMethodName}}() expects no useless return value from {{name}}.",
|
253
|
+
wrapBraces: "Wrap the expression in `{}`.",
|
254
|
+
prependVoid: "Prepend `void` to the expression."
|
176
255
|
}
|
177
256
|
},
|
178
257
|
|
179
258
|
create(context) {
|
180
259
|
|
181
|
-
const options = context.options[0] || { allowImplicit: false, checkForEach: false };
|
260
|
+
const options = context.options[0] || { allowImplicit: false, checkForEach: false, allowVoid: false };
|
182
261
|
const sourceCode = context.sourceCode;
|
183
262
|
|
184
263
|
let funcInfo = {
|
@@ -205,26 +284,56 @@ module.exports = {
|
|
205
284
|
return;
|
206
285
|
}
|
207
286
|
|
208
|
-
|
287
|
+
const messageAndSuggestions = { messageId: "", suggest: [] };
|
209
288
|
|
210
289
|
if (funcInfo.arrayMethodName === "forEach") {
|
211
290
|
if (options.checkForEach && node.type === "ArrowFunctionExpression" && node.expression) {
|
212
|
-
|
291
|
+
|
292
|
+
if (options.allowVoid) {
|
293
|
+
if (isExpressionVoid(node.body)) {
|
294
|
+
return;
|
295
|
+
}
|
296
|
+
|
297
|
+
messageAndSuggestions.messageId = "expectedNoReturnValue";
|
298
|
+
messageAndSuggestions.suggest = [
|
299
|
+
{
|
300
|
+
messageId: "wrapBraces",
|
301
|
+
fix(fixer) {
|
302
|
+
return curlyWrapFixer(sourceCode, node, fixer);
|
303
|
+
}
|
304
|
+
},
|
305
|
+
{
|
306
|
+
messageId: "prependVoid",
|
307
|
+
fix(fixer) {
|
308
|
+
return voidPrependFixer(sourceCode, node.body, fixer);
|
309
|
+
}
|
310
|
+
}
|
311
|
+
];
|
312
|
+
} else {
|
313
|
+
messageAndSuggestions.messageId = "expectedNoReturnValue";
|
314
|
+
messageAndSuggestions.suggest = [{
|
315
|
+
messageId: "wrapBraces",
|
316
|
+
fix(fixer) {
|
317
|
+
return curlyWrapFixer(sourceCode, node, fixer);
|
318
|
+
}
|
319
|
+
}];
|
320
|
+
}
|
213
321
|
}
|
214
322
|
} else {
|
215
323
|
if (node.body.type === "BlockStatement" && isAnySegmentReachable(funcInfo.currentSegments)) {
|
216
|
-
messageId = funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside";
|
324
|
+
messageAndSuggestions.messageId = funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside";
|
217
325
|
}
|
218
326
|
}
|
219
327
|
|
220
|
-
if (messageId) {
|
328
|
+
if (messageAndSuggestions.messageId) {
|
221
329
|
const name = astUtils.getFunctionNameWithKind(node);
|
222
330
|
|
223
331
|
context.report({
|
224
332
|
node,
|
225
333
|
loc: astUtils.getFunctionHeadLoc(node, sourceCode),
|
226
|
-
messageId,
|
227
|
-
data: { name, arrayMethodName: fullMethodName(funcInfo.arrayMethodName) }
|
334
|
+
messageId: messageAndSuggestions.messageId,
|
335
|
+
data: { name, arrayMethodName: fullMethodName(funcInfo.arrayMethodName) },
|
336
|
+
suggest: messageAndSuggestions.suggest.length !== 0 ? messageAndSuggestions.suggest : null
|
228
337
|
});
|
229
338
|
}
|
230
339
|
}
|
@@ -285,30 +394,46 @@ module.exports = {
|
|
285
394
|
|
286
395
|
funcInfo.hasReturn = true;
|
287
396
|
|
288
|
-
|
397
|
+
const messageAndSuggestions = { messageId: "", suggest: [] };
|
289
398
|
|
290
399
|
if (funcInfo.arrayMethodName === "forEach") {
|
291
400
|
|
292
401
|
// if checkForEach: true, returning a value at any path inside a forEach is not allowed
|
293
402
|
if (options.checkForEach && node.argument) {
|
294
|
-
|
403
|
+
|
404
|
+
if (options.allowVoid) {
|
405
|
+
if (isExpressionVoid(node.argument)) {
|
406
|
+
return;
|
407
|
+
}
|
408
|
+
|
409
|
+
messageAndSuggestions.messageId = "expectedNoReturnValue";
|
410
|
+
messageAndSuggestions.suggest = [{
|
411
|
+
messageId: "prependVoid",
|
412
|
+
fix(fixer) {
|
413
|
+
return voidPrependFixer(sourceCode, node.argument, fixer);
|
414
|
+
}
|
415
|
+
}];
|
416
|
+
} else {
|
417
|
+
messageAndSuggestions.messageId = "expectedNoReturnValue";
|
418
|
+
}
|
295
419
|
}
|
296
420
|
} else {
|
297
421
|
|
298
422
|
// if allowImplicit: false, should also check node.argument
|
299
423
|
if (!options.allowImplicit && !node.argument) {
|
300
|
-
messageId = "expectedReturnValue";
|
424
|
+
messageAndSuggestions.messageId = "expectedReturnValue";
|
301
425
|
}
|
302
426
|
}
|
303
427
|
|
304
|
-
if (messageId) {
|
428
|
+
if (messageAndSuggestions.messageId) {
|
305
429
|
context.report({
|
306
430
|
node,
|
307
|
-
messageId,
|
431
|
+
messageId: messageAndSuggestions.messageId,
|
308
432
|
data: {
|
309
433
|
name: astUtils.getFunctionNameWithKind(funcInfo.node),
|
310
434
|
arrayMethodName: fullMethodName(funcInfo.arrayMethodName)
|
311
|
-
}
|
435
|
+
},
|
436
|
+
suggest: messageAndSuggestions.suggest.length !== 0 ? messageAndSuggestions.suggest : null
|
312
437
|
});
|
313
438
|
}
|
314
439
|
},
|
package/lib/rules/index.js
CHANGED
@@ -175,6 +175,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
|
|
175
175
|
"no-new-wrappers": () => require("./no-new-wrappers"),
|
176
176
|
"no-nonoctal-decimal-escape": () => require("./no-nonoctal-decimal-escape"),
|
177
177
|
"no-obj-calls": () => require("./no-obj-calls"),
|
178
|
+
"no-object-constructor": () => require("./no-object-constructor"),
|
178
179
|
"no-octal": () => require("./no-octal"),
|
179
180
|
"no-octal-escape": () => require("./no-octal-escape"),
|
180
181
|
"no-param-reassign": () => require("./no-param-reassign"),
|
@@ -13,27 +13,34 @@ const { isValidWithUnicodeFlag } = require("./utils/regular-expressions");
|
|
13
13
|
// Helpers
|
14
14
|
//------------------------------------------------------------------------------
|
15
15
|
|
16
|
+
/**
|
17
|
+
* @typedef {import('@eslint-community/regexpp').AST.Character} Character
|
18
|
+
* @typedef {import('@eslint-community/regexpp').AST.CharacterClassElement} CharacterClassElement
|
19
|
+
*/
|
20
|
+
|
16
21
|
/**
|
17
22
|
* Iterate character sequences of a given nodes.
|
18
23
|
*
|
19
24
|
* CharacterClassRange syntax can steal a part of character sequence,
|
20
25
|
* so this function reverts CharacterClassRange syntax and restore the sequence.
|
21
|
-
* @param {
|
22
|
-
* @returns {IterableIterator<
|
26
|
+
* @param {CharacterClassElement[]} nodes The node list to iterate character sequences.
|
27
|
+
* @returns {IterableIterator<Character[]>} The list of character sequences.
|
23
28
|
*/
|
24
29
|
function *iterateCharacterSequence(nodes) {
|
30
|
+
|
31
|
+
/** @type {Character[]} */
|
25
32
|
let seq = [];
|
26
33
|
|
27
34
|
for (const node of nodes) {
|
28
35
|
switch (node.type) {
|
29
36
|
case "Character":
|
30
|
-
seq.push(node
|
37
|
+
seq.push(node);
|
31
38
|
break;
|
32
39
|
|
33
40
|
case "CharacterClassRange":
|
34
|
-
seq.push(node.min
|
41
|
+
seq.push(node.min);
|
35
42
|
yield seq;
|
36
|
-
seq = [node.max
|
43
|
+
seq = [node.max];
|
37
44
|
break;
|
38
45
|
|
39
46
|
case "CharacterSet":
|
@@ -55,32 +62,74 @@ function *iterateCharacterSequence(nodes) {
|
|
55
62
|
}
|
56
63
|
}
|
57
64
|
|
65
|
+
|
66
|
+
/**
|
67
|
+
* Checks whether the given character node is a Unicode code point escape or not.
|
68
|
+
* @param {Character} char the character node to check.
|
69
|
+
* @returns {boolean} `true` if the character node is a Unicode code point escape.
|
70
|
+
*/
|
71
|
+
function isUnicodeCodePointEscape(char) {
|
72
|
+
return /^\\u\{[\da-f]+\}$/iu.test(char.raw);
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* Each function returns `true` if it detects that kind of problem.
|
77
|
+
* @type {Record<string, (chars: Character[]) => boolean>}
|
78
|
+
*/
|
58
79
|
const hasCharacterSequence = {
|
59
80
|
surrogatePairWithoutUFlag(chars) {
|
60
|
-
return chars.some((c, i) =>
|
81
|
+
return chars.some((c, i) => {
|
82
|
+
if (i === 0) {
|
83
|
+
return false;
|
84
|
+
}
|
85
|
+
const c1 = chars[i - 1];
|
86
|
+
|
87
|
+
return (
|
88
|
+
isSurrogatePair(c1.value, c.value) &&
|
89
|
+
!isUnicodeCodePointEscape(c1) &&
|
90
|
+
!isUnicodeCodePointEscape(c)
|
91
|
+
);
|
92
|
+
});
|
93
|
+
},
|
94
|
+
|
95
|
+
surrogatePair(chars) {
|
96
|
+
return chars.some((c, i) => {
|
97
|
+
if (i === 0) {
|
98
|
+
return false;
|
99
|
+
}
|
100
|
+
const c1 = chars[i - 1];
|
101
|
+
|
102
|
+
return (
|
103
|
+
isSurrogatePair(c1.value, c.value) &&
|
104
|
+
(
|
105
|
+
isUnicodeCodePointEscape(c1) ||
|
106
|
+
isUnicodeCodePointEscape(c)
|
107
|
+
)
|
108
|
+
);
|
109
|
+
});
|
61
110
|
},
|
62
111
|
|
63
112
|
combiningClass(chars) {
|
64
113
|
return chars.some((c, i) => (
|
65
114
|
i !== 0 &&
|
66
|
-
isCombiningCharacter(c) &&
|
67
|
-
!isCombiningCharacter(chars[i - 1])
|
115
|
+
isCombiningCharacter(c.value) &&
|
116
|
+
!isCombiningCharacter(chars[i - 1].value)
|
68
117
|
));
|
69
118
|
},
|
70
119
|
|
71
120
|
emojiModifier(chars) {
|
72
121
|
return chars.some((c, i) => (
|
73
122
|
i !== 0 &&
|
74
|
-
isEmojiModifier(c) &&
|
75
|
-
!isEmojiModifier(chars[i - 1])
|
123
|
+
isEmojiModifier(c.value) &&
|
124
|
+
!isEmojiModifier(chars[i - 1].value)
|
76
125
|
));
|
77
126
|
},
|
78
127
|
|
79
128
|
regionalIndicatorSymbol(chars) {
|
80
129
|
return chars.some((c, i) => (
|
81
130
|
i !== 0 &&
|
82
|
-
isRegionalIndicatorSymbol(c) &&
|
83
|
-
isRegionalIndicatorSymbol(chars[i - 1])
|
131
|
+
isRegionalIndicatorSymbol(c.value) &&
|
132
|
+
isRegionalIndicatorSymbol(chars[i - 1].value)
|
84
133
|
));
|
85
134
|
},
|
86
135
|
|
@@ -90,9 +139,9 @@ const hasCharacterSequence = {
|
|
90
139
|
return chars.some((c, i) => (
|
91
140
|
i !== 0 &&
|
92
141
|
i !== lastIndex &&
|
93
|
-
c === 0x200d &&
|
94
|
-
chars[i - 1] !== 0x200d &&
|
95
|
-
chars[i + 1] !== 0x200d
|
142
|
+
c.value === 0x200d &&
|
143
|
+
chars[i - 1].value !== 0x200d &&
|
144
|
+
chars[i + 1].value !== 0x200d
|
96
145
|
));
|
97
146
|
}
|
98
147
|
};
|
@@ -120,6 +169,7 @@ module.exports = {
|
|
120
169
|
|
121
170
|
messages: {
|
122
171
|
surrogatePairWithoutUFlag: "Unexpected surrogate pair in character class. Use 'u' flag.",
|
172
|
+
surrogatePair: "Unexpected surrogate pair in character class.",
|
123
173
|
combiningClass: "Unexpected combined character in character class.",
|
124
174
|
emojiModifier: "Unexpected modified Emoji in character class.",
|
125
175
|
regionalIndicatorSymbol: "Unexpected national flag in character class.",
|
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview A rule to disallow calls to the Object constructor
|
3
3
|
* @author Matt DuVall <http://www.mattduvall.com/>
|
4
|
+
* @deprecated in ESLint v8.50.0
|
4
5
|
*/
|
5
6
|
|
6
7
|
"use strict";
|
@@ -26,6 +27,12 @@ module.exports = {
|
|
26
27
|
url: "https://eslint.org/docs/latest/rules/no-new-object"
|
27
28
|
},
|
28
29
|
|
30
|
+
deprecated: true,
|
31
|
+
|
32
|
+
replacedBy: [
|
33
|
+
"no-object-constructor"
|
34
|
+
],
|
35
|
+
|
29
36
|
schema: [],
|
30
37
|
|
31
38
|
messages: {
|
@@ -0,0 +1,118 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Rule to disallow calls to the `Object` constructor without an argument
|
3
|
+
* @author Francesco Trotta
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Requirements
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
const { getVariableByName, isArrowToken } = require("./utils/ast-utils");
|
13
|
+
|
14
|
+
//------------------------------------------------------------------------------
|
15
|
+
// Helpers
|
16
|
+
//------------------------------------------------------------------------------
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Tests if a node appears at the beginning of an ancestor ExpressionStatement node.
|
20
|
+
* @param {ASTNode} node The node to check.
|
21
|
+
* @returns {boolean} Whether the node appears at the beginning of an ancestor ExpressionStatement node.
|
22
|
+
*/
|
23
|
+
function isStartOfExpressionStatement(node) {
|
24
|
+
const start = node.range[0];
|
25
|
+
let ancestor = node;
|
26
|
+
|
27
|
+
while ((ancestor = ancestor.parent) && ancestor.range[0] === start) {
|
28
|
+
if (ancestor.type === "ExpressionStatement") {
|
29
|
+
return true;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
return false;
|
33
|
+
}
|
34
|
+
|
35
|
+
//------------------------------------------------------------------------------
|
36
|
+
// Rule Definition
|
37
|
+
//------------------------------------------------------------------------------
|
38
|
+
|
39
|
+
/** @type {import('../shared/types').Rule} */
|
40
|
+
module.exports = {
|
41
|
+
meta: {
|
42
|
+
type: "suggestion",
|
43
|
+
|
44
|
+
docs: {
|
45
|
+
description: "Disallow calls to the `Object` constructor without an argument",
|
46
|
+
recommended: false,
|
47
|
+
url: "https://eslint.org/docs/latest/rules/no-object-constructor"
|
48
|
+
},
|
49
|
+
|
50
|
+
hasSuggestions: true,
|
51
|
+
|
52
|
+
schema: [],
|
53
|
+
|
54
|
+
messages: {
|
55
|
+
preferLiteral: "The object literal notation {} is preferable.",
|
56
|
+
useLiteral: "Replace with '{{replacement}}'."
|
57
|
+
}
|
58
|
+
},
|
59
|
+
|
60
|
+
create(context) {
|
61
|
+
|
62
|
+
const sourceCode = context.sourceCode;
|
63
|
+
|
64
|
+
/**
|
65
|
+
* Determines whether or not an object literal that replaces a specified node needs to be enclosed in parentheses.
|
66
|
+
* @param {ASTNode} node The node to be replaced.
|
67
|
+
* @returns {boolean} Whether or not parentheses around the object literal are required.
|
68
|
+
*/
|
69
|
+
function needsParentheses(node) {
|
70
|
+
if (isStartOfExpressionStatement(node)) {
|
71
|
+
return true;
|
72
|
+
}
|
73
|
+
|
74
|
+
const prevToken = sourceCode.getTokenBefore(node);
|
75
|
+
|
76
|
+
if (prevToken && isArrowToken(prevToken)) {
|
77
|
+
return true;
|
78
|
+
}
|
79
|
+
|
80
|
+
return false;
|
81
|
+
}
|
82
|
+
|
83
|
+
/**
|
84
|
+
* Reports on nodes where the `Object` constructor is called without arguments.
|
85
|
+
* @param {ASTNode} node The node to evaluate.
|
86
|
+
* @returns {void}
|
87
|
+
*/
|
88
|
+
function check(node) {
|
89
|
+
if (node.callee.type !== "Identifier" || node.callee.name !== "Object" || node.arguments.length) {
|
90
|
+
return;
|
91
|
+
}
|
92
|
+
|
93
|
+
const variable = getVariableByName(sourceCode.getScope(node), "Object");
|
94
|
+
|
95
|
+
if (variable && variable.identifiers.length === 0) {
|
96
|
+
const replacement = needsParentheses(node) ? "({})" : "{}";
|
97
|
+
|
98
|
+
context.report({
|
99
|
+
node,
|
100
|
+
messageId: "preferLiteral",
|
101
|
+
suggest: [
|
102
|
+
{
|
103
|
+
messageId: "useLiteral",
|
104
|
+
data: { replacement },
|
105
|
+
fix: fixer => fixer.replaceText(node, replacement)
|
106
|
+
}
|
107
|
+
]
|
108
|
+
});
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
return {
|
113
|
+
CallExpression: check,
|
114
|
+
NewExpression: check
|
115
|
+
};
|
116
|
+
|
117
|
+
}
|
118
|
+
};
|