eslint 5.0.0-alpha.4 → 5.1.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/CHANGELOG.md +60 -0
- package/README.md +143 -27
- package/conf/eslint-recommended.js +1 -0
- package/lib/code-path-analysis/code-path-analyzer.js +28 -4
- package/lib/config/config-file.js +5 -0
- package/lib/config/config-initializer.js +19 -10
- package/lib/config/config-validator.js +13 -6
- package/lib/config.js +4 -4
- package/lib/formatters/stylish.js +1 -1
- package/lib/ignored-paths.js +11 -7
- package/lib/rules/camelcase.js +33 -5
- package/lib/rules/func-name-matching.js +52 -4
- package/lib/rules/max-lines-per-function.js +218 -0
- package/lib/rules/no-catch-shadow.js +5 -2
- package/lib/rules/no-debugger.js +2 -10
- package/lib/rules/no-shadow-restricted-names.js +11 -37
- package/lib/rules/no-unneeded-ternary.js +1 -1
- package/lib/rules/no-use-before-define.js +4 -39
- package/lib/rules/no-warning-comments.js +19 -2
- package/lib/rules/prefer-const.js +1 -1
- package/lib/rules/prefer-object-spread.js +147 -196
- package/lib/rules/sort-keys.js +1 -1
- package/lib/rules/valid-jsdoc.js +6 -2
- package/lib/rules/wrap-regex.js +8 -4
- package/lib/util/npm-util.js +8 -2
- package/messages/failed-to-read-json.txt +3 -0
- package/package.json +6 -4
@@ -58,6 +58,9 @@ const alwaysOrNever = { enum: ["always", "never"] };
|
|
58
58
|
const optionsObject = {
|
59
59
|
type: "object",
|
60
60
|
properties: {
|
61
|
+
considerPropertyDescriptor: {
|
62
|
+
type: "boolean"
|
63
|
+
},
|
61
64
|
includeCommonJSModuleExports: {
|
62
65
|
type: "boolean"
|
63
66
|
}
|
@@ -90,9 +93,26 @@ module.exports = {
|
|
90
93
|
create(context) {
|
91
94
|
const options = (typeof context.options[0] === "object" ? context.options[0] : context.options[1]) || {};
|
92
95
|
const nameMatches = typeof context.options[0] === "string" ? context.options[0] : "always";
|
96
|
+
const considerPropertyDescriptor = options.considerPropertyDescriptor;
|
93
97
|
const includeModuleExports = options.includeCommonJSModuleExports;
|
94
98
|
const ecmaVersion = context.parserOptions && context.parserOptions.ecmaVersion ? context.parserOptions.ecmaVersion : 5;
|
95
99
|
|
100
|
+
/**
|
101
|
+
* Check whether node is a certain CallExpression.
|
102
|
+
* @param {string} objName object name
|
103
|
+
* @param {string} funcName function name
|
104
|
+
* @param {ASTNode} node The node to check
|
105
|
+
* @returns {boolean} `true` if node matches CallExpression
|
106
|
+
*/
|
107
|
+
function isPropertyCall(objName, funcName, node) {
|
108
|
+
if (!node) {
|
109
|
+
return false;
|
110
|
+
}
|
111
|
+
return node.type === "CallExpression" &&
|
112
|
+
node.callee.object.name === objName &&
|
113
|
+
node.callee.property.name === funcName;
|
114
|
+
}
|
115
|
+
|
96
116
|
/**
|
97
117
|
* Compares identifiers based on the nameMatches option
|
98
118
|
* @param {string} x the first identifier
|
@@ -147,7 +167,6 @@ module.exports = {
|
|
147
167
|
//--------------------------------------------------------------------------
|
148
168
|
|
149
169
|
return {
|
150
|
-
|
151
170
|
VariableDeclarator(node) {
|
152
171
|
if (!node.init || node.init.type !== "FunctionExpression" || node.id.type !== "Identifier") {
|
153
172
|
return;
|
@@ -179,9 +198,38 @@ module.exports = {
|
|
179
198
|
if (node.value.type !== "FunctionExpression" || !node.value.id || node.computed && !isStringLiteral(node.key)) {
|
180
199
|
return;
|
181
200
|
}
|
182
|
-
|
183
|
-
|
184
|
-
|
201
|
+
|
202
|
+
if (node.key.type === "Identifier") {
|
203
|
+
const functionName = node.value.id.name;
|
204
|
+
let propertyName = node.key.name;
|
205
|
+
|
206
|
+
if (considerPropertyDescriptor && propertyName === "value") {
|
207
|
+
if (isPropertyCall("Object", "defineProperty", node.parent.parent) || isPropertyCall("Reflect", "defineProperty", node.parent.parent)) {
|
208
|
+
const property = node.parent.parent.arguments[1];
|
209
|
+
|
210
|
+
if (isStringLiteral(property) && shouldWarn(property.value, functionName)) {
|
211
|
+
report(node, property.value, functionName, true);
|
212
|
+
}
|
213
|
+
} else if (isPropertyCall("Object", "defineProperties", node.parent.parent.parent.parent)) {
|
214
|
+
propertyName = node.parent.parent.key.name;
|
215
|
+
if (!node.parent.parent.computed && shouldWarn(propertyName, functionName)) {
|
216
|
+
report(node, propertyName, functionName, true);
|
217
|
+
}
|
218
|
+
} else if (isPropertyCall("Object", "create", node.parent.parent.parent.parent)) {
|
219
|
+
propertyName = node.parent.parent.key.name;
|
220
|
+
if (!node.parent.parent.computed && shouldWarn(propertyName, functionName)) {
|
221
|
+
report(node, propertyName, functionName, true);
|
222
|
+
}
|
223
|
+
} else if (shouldWarn(propertyName, functionName)) {
|
224
|
+
report(node, propertyName, functionName, true);
|
225
|
+
}
|
226
|
+
} else if (shouldWarn(propertyName, functionName)) {
|
227
|
+
report(node, propertyName, functionName, true);
|
228
|
+
}
|
229
|
+
return;
|
230
|
+
}
|
231
|
+
|
232
|
+
if (
|
185
233
|
isStringLiteral(node.key) &&
|
186
234
|
isIdentifier(node.key.value, ecmaVersion) &&
|
187
235
|
shouldWarn(node.key.value, node.value.id.name)
|
@@ -0,0 +1,218 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview A rule to set the maximum number of line of code in a function.
|
3
|
+
* @author Pete Ward <peteward44@gmail.com>
|
4
|
+
*/
|
5
|
+
"use strict";
|
6
|
+
|
7
|
+
//------------------------------------------------------------------------------
|
8
|
+
// Requirements
|
9
|
+
//------------------------------------------------------------------------------
|
10
|
+
|
11
|
+
const astUtils = require("../ast-utils");
|
12
|
+
|
13
|
+
//------------------------------------------------------------------------------
|
14
|
+
// Constants
|
15
|
+
//------------------------------------------------------------------------------
|
16
|
+
|
17
|
+
const OPTIONS_SCHEMA = {
|
18
|
+
type: "object",
|
19
|
+
properties: {
|
20
|
+
max: {
|
21
|
+
type: "integer",
|
22
|
+
minimum: 0
|
23
|
+
},
|
24
|
+
skipComments: {
|
25
|
+
type: "boolean"
|
26
|
+
},
|
27
|
+
skipBlankLines: {
|
28
|
+
type: "boolean"
|
29
|
+
},
|
30
|
+
IIFEs: {
|
31
|
+
type: "boolean"
|
32
|
+
}
|
33
|
+
},
|
34
|
+
additionalProperties: false
|
35
|
+
};
|
36
|
+
|
37
|
+
const OPTIONS_OR_INTEGER_SCHEMA = {
|
38
|
+
oneOf: [
|
39
|
+
OPTIONS_SCHEMA,
|
40
|
+
{
|
41
|
+
type: "integer",
|
42
|
+
minimum: 1
|
43
|
+
}
|
44
|
+
]
|
45
|
+
};
|
46
|
+
|
47
|
+
/**
|
48
|
+
* Given a list of comment nodes, return a map with numeric keys (source code line numbers) and comment token values.
|
49
|
+
* @param {Array} comments An array of comment nodes.
|
50
|
+
* @returns {Map.<string,Node>} A map with numeric keys (source code line numbers) and comment token values.
|
51
|
+
*/
|
52
|
+
function getCommentLineNumbers(comments) {
|
53
|
+
const map = new Map();
|
54
|
+
|
55
|
+
if (!comments) {
|
56
|
+
return map;
|
57
|
+
}
|
58
|
+
comments.forEach(comment => {
|
59
|
+
for (let i = comment.loc.start.line; i <= comment.loc.end.line; i++) {
|
60
|
+
map.set(i, comment);
|
61
|
+
}
|
62
|
+
});
|
63
|
+
return map;
|
64
|
+
}
|
65
|
+
|
66
|
+
//------------------------------------------------------------------------------
|
67
|
+
// Rule Definition
|
68
|
+
//------------------------------------------------------------------------------
|
69
|
+
|
70
|
+
module.exports = {
|
71
|
+
meta: {
|
72
|
+
docs: {
|
73
|
+
description: "enforce a maximum number of line of code in a function",
|
74
|
+
category: "Stylistic Issues",
|
75
|
+
recommended: false,
|
76
|
+
url: "https://eslint.org/docs/rules/max-lines-per-function"
|
77
|
+
},
|
78
|
+
|
79
|
+
schema: [
|
80
|
+
OPTIONS_OR_INTEGER_SCHEMA
|
81
|
+
]
|
82
|
+
},
|
83
|
+
|
84
|
+
create(context) {
|
85
|
+
const sourceCode = context.getSourceCode();
|
86
|
+
const lines = sourceCode.lines;
|
87
|
+
|
88
|
+
const option = context.options[0];
|
89
|
+
let maxLines = 50;
|
90
|
+
let skipComments = false;
|
91
|
+
let skipBlankLines = false;
|
92
|
+
let IIFEs = false;
|
93
|
+
|
94
|
+
if (typeof option === "object") {
|
95
|
+
if (typeof option.max === "number") {
|
96
|
+
maxLines = option.max;
|
97
|
+
}
|
98
|
+
if (typeof option.skipComments === "boolean") {
|
99
|
+
skipComments = option.skipComments;
|
100
|
+
}
|
101
|
+
if (typeof option.skipBlankLines === "boolean") {
|
102
|
+
skipBlankLines = option.skipBlankLines;
|
103
|
+
}
|
104
|
+
if (typeof option.IIFEs === "boolean") {
|
105
|
+
IIFEs = option.IIFEs;
|
106
|
+
}
|
107
|
+
} else if (typeof option === "number") {
|
108
|
+
maxLines = option;
|
109
|
+
}
|
110
|
+
|
111
|
+
const commentLineNumbers = getCommentLineNumbers(sourceCode.getAllComments());
|
112
|
+
|
113
|
+
//--------------------------------------------------------------------------
|
114
|
+
// Helpers
|
115
|
+
//--------------------------------------------------------------------------
|
116
|
+
|
117
|
+
/**
|
118
|
+
* Tells if a comment encompasses the entire line.
|
119
|
+
* @param {string} line The source line with a trailing comment
|
120
|
+
* @param {number} lineNumber The one-indexed line number this is on
|
121
|
+
* @param {ASTNode} comment The comment to remove
|
122
|
+
* @returns {boolean} If the comment covers the entire line
|
123
|
+
*/
|
124
|
+
function isFullLineComment(line, lineNumber, comment) {
|
125
|
+
const start = comment.loc.start,
|
126
|
+
end = comment.loc.end,
|
127
|
+
isFirstTokenOnLine = start.line === lineNumber && !line.slice(0, start.column).trim(),
|
128
|
+
isLastTokenOnLine = end.line === lineNumber && !line.slice(end.column).trim();
|
129
|
+
|
130
|
+
return comment &&
|
131
|
+
(start.line < lineNumber || isFirstTokenOnLine) &&
|
132
|
+
(end.line > lineNumber || isLastTokenOnLine);
|
133
|
+
}
|
134
|
+
|
135
|
+
/**
|
136
|
+
* Identifies is a node is a FunctionExpression which is part of an IIFE
|
137
|
+
* @param {ASTNode} node Node to test
|
138
|
+
* @returns {boolean} True if it's an IIFE
|
139
|
+
*/
|
140
|
+
function isIIFE(node) {
|
141
|
+
return node.type === "FunctionExpression" && node.parent && node.parent.type === "CallExpression" && node.parent.callee === node;
|
142
|
+
}
|
143
|
+
|
144
|
+
/**
|
145
|
+
* Identifies is a node is a FunctionExpression which is embedded within a MethodDefinition or Property
|
146
|
+
* @param {ASTNode} node Node to test
|
147
|
+
* @returns {boolean} True if it's a FunctionExpression embedded within a MethodDefinition or Property
|
148
|
+
*/
|
149
|
+
function isEmbedded(node) {
|
150
|
+
if (!node.parent) {
|
151
|
+
return false;
|
152
|
+
}
|
153
|
+
if (node !== node.parent.value) {
|
154
|
+
return false;
|
155
|
+
}
|
156
|
+
if (node.parent.type === "MethodDefinition") {
|
157
|
+
return true;
|
158
|
+
}
|
159
|
+
if (node.parent.type === "Property") {
|
160
|
+
return node.parent.method === true || node.parent.kind === "get" || node.parent.kind === "set";
|
161
|
+
}
|
162
|
+
return false;
|
163
|
+
}
|
164
|
+
|
165
|
+
/**
|
166
|
+
* Count the lines in the function
|
167
|
+
* @param {ASTNode} funcNode Function AST node
|
168
|
+
* @returns {void}
|
169
|
+
* @private
|
170
|
+
*/
|
171
|
+
function processFunction(funcNode) {
|
172
|
+
const node = isEmbedded(funcNode) ? funcNode.parent : funcNode;
|
173
|
+
|
174
|
+
if (!IIFEs && isIIFE(node)) {
|
175
|
+
return;
|
176
|
+
}
|
177
|
+
let lineCount = 0;
|
178
|
+
|
179
|
+
for (let i = node.loc.start.line - 1; i < node.loc.end.line; ++i) {
|
180
|
+
const line = lines[i];
|
181
|
+
|
182
|
+
if (skipComments) {
|
183
|
+
if (commentLineNumbers.has(i + 1) && isFullLineComment(line, i + 1, commentLineNumbers.get(i + 1))) {
|
184
|
+
continue;
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
if (skipBlankLines) {
|
189
|
+
if (line.match(/^\s*$/)) {
|
190
|
+
continue;
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
194
|
+
lineCount++;
|
195
|
+
}
|
196
|
+
|
197
|
+
if (lineCount > maxLines) {
|
198
|
+
const name = astUtils.getFunctionNameWithKind(funcNode);
|
199
|
+
|
200
|
+
context.report({
|
201
|
+
node,
|
202
|
+
message: "{{name}} has too many lines ({{lineCount}}). Maximum allowed is {{maxLines}}.",
|
203
|
+
data: { name, lineCount, maxLines }
|
204
|
+
});
|
205
|
+
}
|
206
|
+
}
|
207
|
+
|
208
|
+
//--------------------------------------------------------------------------
|
209
|
+
// Public API
|
210
|
+
//--------------------------------------------------------------------------
|
211
|
+
|
212
|
+
return {
|
213
|
+
FunctionDeclaration: processFunction,
|
214
|
+
FunctionExpression: processFunction,
|
215
|
+
ArrowFunctionExpression: processFunction
|
216
|
+
};
|
217
|
+
}
|
218
|
+
};
|
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview Rule to flag variable leak in CatchClauses in IE 8 and earlier
|
3
3
|
* @author Ian Christian Myers
|
4
|
+
* @deprecated in ESLint v5.1.0
|
4
5
|
*/
|
5
6
|
|
6
7
|
"use strict";
|
@@ -21,8 +22,10 @@ module.exports = {
|
|
21
22
|
description: "disallow `catch` clause parameters from shadowing variables in the outer scope",
|
22
23
|
category: "Variables",
|
23
24
|
recommended: false,
|
24
|
-
url: "https://eslint.org/docs/rules/no-catch-shadow"
|
25
|
+
url: "https://eslint.org/docs/rules/no-catch-shadow",
|
26
|
+
replacedBy: ["no-shadow"]
|
25
27
|
},
|
28
|
+
deprecated: true,
|
26
29
|
|
27
30
|
schema: [],
|
28
31
|
|
@@ -53,7 +56,7 @@ module.exports = {
|
|
53
56
|
|
54
57
|
return {
|
55
58
|
|
56
|
-
CatchClause(node) {
|
59
|
+
"CatchClause[param!=null]"(node) {
|
57
60
|
let scope = context.getScope();
|
58
61
|
|
59
62
|
/*
|
package/lib/rules/no-debugger.js
CHANGED
@@ -5,8 +5,6 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
-
const astUtils = require("../ast-utils");
|
9
|
-
|
10
8
|
//------------------------------------------------------------------------------
|
11
9
|
// Rule Definition
|
12
10
|
//------------------------------------------------------------------------------
|
@@ -19,7 +17,7 @@ module.exports = {
|
|
19
17
|
recommended: true,
|
20
18
|
url: "https://eslint.org/docs/rules/no-debugger"
|
21
19
|
},
|
22
|
-
fixable:
|
20
|
+
fixable: null,
|
23
21
|
schema: [],
|
24
22
|
messages: {
|
25
23
|
unexpected: "Unexpected 'debugger' statement."
|
@@ -32,13 +30,7 @@ module.exports = {
|
|
32
30
|
DebuggerStatement(node) {
|
33
31
|
context.report({
|
34
32
|
node,
|
35
|
-
messageId: "unexpected"
|
36
|
-
fix(fixer) {
|
37
|
-
if (astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) {
|
38
|
-
return fixer.remove(node);
|
39
|
-
}
|
40
|
-
return null;
|
41
|
-
}
|
33
|
+
messageId: "unexpected"
|
42
34
|
});
|
43
35
|
}
|
44
36
|
};
|
@@ -24,45 +24,19 @@ module.exports = {
|
|
24
24
|
|
25
25
|
const RESTRICTED = ["undefined", "NaN", "Infinity", "arguments", "eval"];
|
26
26
|
|
27
|
-
/**
|
28
|
-
* Check if the node name is present inside the restricted list
|
29
|
-
* @param {ASTNode} id id to evaluate
|
30
|
-
* @returns {void}
|
31
|
-
* @private
|
32
|
-
*/
|
33
|
-
function checkForViolation(id) {
|
34
|
-
if (RESTRICTED.indexOf(id.name) > -1) {
|
35
|
-
context.report({
|
36
|
-
node: id,
|
37
|
-
message: "Shadowing of global property '{{idName}}'.",
|
38
|
-
data: {
|
39
|
-
idName: id.name
|
40
|
-
}
|
41
|
-
});
|
42
|
-
}
|
43
|
-
}
|
44
|
-
|
45
27
|
return {
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
},
|
58
|
-
FunctionDeclaration(node) {
|
59
|
-
if (node.id) {
|
60
|
-
checkForViolation(node.id);
|
61
|
-
[].map.call(node.params, checkForViolation);
|
28
|
+
"VariableDeclaration, :function, CatchClause"(node) {
|
29
|
+
for (const variable of context.getDeclaredVariables(node)) {
|
30
|
+
if (variable.defs.length > 0 && RESTRICTED.includes(variable.name)) {
|
31
|
+
context.report({
|
32
|
+
node: variable.defs[0].name,
|
33
|
+
message: "Shadowing of global property '{{idName}}'.",
|
34
|
+
data: {
|
35
|
+
idName: variable.name
|
36
|
+
}
|
37
|
+
});
|
38
|
+
}
|
62
39
|
}
|
63
|
-
},
|
64
|
-
CatchClause(node) {
|
65
|
-
checkForViolation(node.param);
|
66
40
|
}
|
67
41
|
};
|
68
42
|
|
@@ -140,7 +140,7 @@ module.exports = {
|
|
140
140
|
fix: fixer => {
|
141
141
|
let nodeAlternate = astUtils.getParenthesisedText(sourceCode, node.alternate);
|
142
142
|
|
143
|
-
if (node.alternate.type === "ConditionalExpression") {
|
143
|
+
if (node.alternate.type === "ConditionalExpression" || node.alternate.type === "YieldExpression") {
|
144
144
|
const isAlternateParenthesised = astUtils.isParenthesised(sourceCode, node.alternate);
|
145
145
|
|
146
146
|
nodeAlternate = isAlternateParenthesised ? nodeAlternate : `(${nodeAlternate})`;
|
@@ -219,49 +219,14 @@ module.exports = {
|
|
219
219
|
data: reference.identifier
|
220
220
|
});
|
221
221
|
});
|
222
|
-
}
|
223
222
|
|
224
|
-
|
225
|
-
* Validates variables inside of a node's scope.
|
226
|
-
* @param {ASTNode} node The node to check.
|
227
|
-
* @returns {void}
|
228
|
-
* @private
|
229
|
-
*/
|
230
|
-
function findVariables() {
|
231
|
-
const scope = context.getScope();
|
232
|
-
|
233
|
-
findVariablesInScope(scope);
|
223
|
+
scope.childScopes.forEach(findVariablesInScope);
|
234
224
|
}
|
235
225
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
ecmaFeatures = context.parserOptions.ecmaFeatures || {};
|
240
|
-
|
241
|
-
findVariablesInScope(scope);
|
242
|
-
|
243
|
-
// both Node.js and Modules have an extra scope
|
244
|
-
if (ecmaFeatures.globalReturn || node.sourceType === "module") {
|
245
|
-
findVariablesInScope(scope.childScopes[0]);
|
246
|
-
}
|
226
|
+
return {
|
227
|
+
Program() {
|
228
|
+
findVariablesInScope(context.getScope());
|
247
229
|
}
|
248
230
|
};
|
249
|
-
|
250
|
-
if (context.parserOptions.ecmaVersion >= 6) {
|
251
|
-
ruleDefinition["BlockStatement:exit"] =
|
252
|
-
ruleDefinition["SwitchStatement:exit"] = findVariables;
|
253
|
-
|
254
|
-
ruleDefinition["ArrowFunctionExpression:exit"] = function(node) {
|
255
|
-
if (node.body.type !== "BlockStatement") {
|
256
|
-
findVariables();
|
257
|
-
}
|
258
|
-
};
|
259
|
-
} else {
|
260
|
-
ruleDefinition["FunctionExpression:exit"] =
|
261
|
-
ruleDefinition["FunctionDeclaration:exit"] =
|
262
|
-
ruleDefinition["ArrowFunctionExpression:exit"] = findVariables;
|
263
|
-
}
|
264
|
-
|
265
|
-
return ruleDefinition;
|
266
231
|
}
|
267
232
|
};
|
@@ -57,6 +57,8 @@ module.exports = {
|
|
57
57
|
*/
|
58
58
|
function convertToRegExp(term) {
|
59
59
|
const escaped = term.replace(/[-/\\$^*+?.()|[\]{}]/g, "\\$&");
|
60
|
+
const wordBoundary = "\\b";
|
61
|
+
const eitherOrWordBoundary = `|${wordBoundary}`;
|
60
62
|
let prefix;
|
61
63
|
|
62
64
|
/*
|
@@ -79,12 +81,27 @@ module.exports = {
|
|
79
81
|
*/
|
80
82
|
prefix = "^\\s*";
|
81
83
|
} else if (/^\w/.test(term)) {
|
82
|
-
prefix =
|
84
|
+
prefix = wordBoundary;
|
83
85
|
} else {
|
84
86
|
prefix = "";
|
85
87
|
}
|
86
88
|
|
87
|
-
|
89
|
+
if (location === "start") {
|
90
|
+
|
91
|
+
/*
|
92
|
+
* For location "start" the regex should be
|
93
|
+
* ^\s*TERM\b. This checks the word boundary
|
94
|
+
* at the beginning of the comment.
|
95
|
+
*/
|
96
|
+
return new RegExp(prefix + escaped + suffix, "i");
|
97
|
+
}
|
98
|
+
|
99
|
+
/*
|
100
|
+
* For location "anywhere" the regex should be
|
101
|
+
* \bTERM\b|\bTERM\b, this checks the entire comment
|
102
|
+
* for the term.
|
103
|
+
*/
|
104
|
+
return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "i");
|
88
105
|
}
|
89
106
|
|
90
107
|
const warningRegExps = warningTerms.map(convertToRegExp);
|
@@ -170,7 +170,7 @@ function getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign) {
|
|
170
170
|
const elements = leftNode.elements;
|
171
171
|
|
172
172
|
hasOuterVariables = elements
|
173
|
-
.map(element => element.name)
|
173
|
+
.map(element => element && element.name)
|
174
174
|
.some(name => isOuterVariableInDestructing(name, variable.scope));
|
175
175
|
}
|
176
176
|
if (hasOuterVariables) {
|