eslint 9.0.0-alpha.0 → 9.0.0-alpha.1
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 +5 -0
- package/conf/ecma-version.js +16 -0
- package/lib/cli-engine/cli-engine.js +1 -1
- package/lib/cli-engine/lint-result-cache.js +2 -2
- package/lib/cli.js +14 -16
- package/lib/linter/apply-disable-directives.js +2 -2
- package/lib/linter/code-path-analysis/code-path.js +5 -19
- package/lib/linter/code-path-analysis/fork-context.js +1 -1
- package/lib/linter/config-comment-parser.js +7 -10
- package/lib/linter/linter.js +105 -4
- package/lib/linter/report-translator.js +2 -2
- package/lib/linter/source-code-fixer.js +1 -1
- package/lib/rule-tester/rule-tester.js +1 -26
- package/lib/rules/array-bracket-newline.js +1 -1
- package/lib/rules/array-bracket-spacing.js +1 -1
- package/lib/rules/block-scoped-var.js +1 -1
- package/lib/rules/callback-return.js +2 -2
- package/lib/rules/comma-dangle.js +1 -1
- package/lib/rules/comma-style.js +2 -2
- package/lib/rules/complexity.js +1 -1
- package/lib/rules/constructor-super.js +1 -1
- package/lib/rules/default-case.js +1 -1
- package/lib/rules/eol-last.js +2 -2
- package/lib/rules/function-paren-newline.js +2 -2
- package/lib/rules/indent-legacy.js +5 -5
- package/lib/rules/indent.js +5 -5
- package/lib/rules/index.js +1 -0
- package/lib/rules/key-spacing.js +2 -2
- package/lib/rules/line-comment-position.js +1 -1
- package/lib/rules/lines-around-directive.js +2 -2
- package/lib/rules/max-depth.js +1 -1
- package/lib/rules/max-len.js +3 -3
- package/lib/rules/max-lines.js +3 -3
- package/lib/rules/max-nested-callbacks.js +1 -1
- package/lib/rules/max-params.js +1 -1
- package/lib/rules/max-statements.js +1 -1
- package/lib/rules/multiline-comment-style.js +7 -7
- package/lib/rules/new-cap.js +1 -1
- package/lib/rules/newline-after-var.js +1 -1
- package/lib/rules/newline-before-return.js +1 -1
- package/lib/rules/no-constant-binary-expression.js +5 -5
- package/lib/rules/no-constructor-return.js +1 -1
- package/lib/rules/no-dupe-class-members.js +2 -2
- package/lib/rules/no-else-return.js +1 -1
- package/lib/rules/no-empty-function.js +2 -2
- package/lib/rules/no-fallthrough.js +1 -1
- package/lib/rules/no-inner-declarations.js +22 -1
- package/lib/rules/no-invalid-this.js +1 -1
- package/lib/rules/no-lone-blocks.js +2 -2
- package/lib/rules/no-loss-of-precision.js +1 -1
- package/lib/rules/no-misleading-character-class.js +174 -65
- package/lib/rules/no-multiple-empty-lines.js +1 -1
- package/lib/rules/no-restricted-globals.js +1 -1
- package/lib/rules/no-restricted-imports.js +2 -2
- package/lib/rules/no-restricted-modules.js +2 -2
- package/lib/rules/no-return-await.js +1 -1
- package/lib/rules/no-trailing-spaces.js +2 -3
- package/lib/rules/no-unneeded-ternary.js +1 -1
- package/lib/rules/no-unsafe-optional-chaining.js +1 -1
- package/lib/rules/no-unused-vars.js +6 -8
- package/lib/rules/no-useless-assignment.js +566 -0
- package/lib/rules/no-useless-backreference.js +1 -1
- package/lib/rules/object-curly-spacing.js +3 -3
- package/lib/rules/object-property-newline.js +1 -1
- package/lib/rules/one-var.js +5 -5
- package/lib/rules/padded-blocks.js +7 -7
- package/lib/rules/prefer-arrow-callback.js +3 -3
- package/lib/rules/prefer-reflect.js +1 -1
- package/lib/rules/prefer-regex-literals.js +1 -1
- package/lib/rules/prefer-template.js +1 -1
- package/lib/rules/radix.js +2 -2
- package/lib/rules/semi-style.js +1 -1
- package/lib/rules/sort-imports.js +1 -1
- package/lib/rules/sort-keys.js +1 -1
- package/lib/rules/sort-vars.js +1 -1
- package/lib/rules/space-unary-ops.js +1 -1
- package/lib/rules/strict.js +1 -1
- package/lib/rules/utils/ast-utils.js +7 -7
- package/lib/rules/yield-star-spacing.js +1 -1
- package/lib/source-code/source-code.js +4 -4
- package/lib/source-code/token-store/index.js +2 -2
- package/package.json +4 -4
- package/conf/config-schema.js +0 -93
- package/lib/shared/config-validator.js +0 -380
- package/lib/shared/relative-module-resolver.js +0 -50
package/lib/rules/indent.js
CHANGED
@@ -1077,7 +1077,7 @@ module.exports = {
|
|
1077
1077
|
"ObjectExpression, ObjectPattern"(node) {
|
1078
1078
|
const openingCurly = sourceCode.getFirstToken(node);
|
1079
1079
|
const closingCurly = sourceCode.getTokenAfter(
|
1080
|
-
node.properties.length ? node.properties
|
1080
|
+
node.properties.length ? node.properties.at(-1) : openingCurly,
|
1081
1081
|
astUtils.isClosingBraceToken
|
1082
1082
|
);
|
1083
1083
|
|
@@ -1407,7 +1407,7 @@ module.exports = {
|
|
1407
1407
|
PropertyDefinition(node) {
|
1408
1408
|
const firstToken = sourceCode.getFirstToken(node);
|
1409
1409
|
const maybeSemicolonToken = sourceCode.getLastToken(node);
|
1410
|
-
let keyLastToken
|
1410
|
+
let keyLastToken;
|
1411
1411
|
|
1412
1412
|
// Indent key.
|
1413
1413
|
if (node.computed) {
|
@@ -1458,7 +1458,7 @@ module.exports = {
|
|
1458
1458
|
|
1459
1459
|
if (node.cases.length) {
|
1460
1460
|
sourceCode.getTokensBetween(
|
1461
|
-
node.cases
|
1461
|
+
node.cases.at(-1),
|
1462
1462
|
closingCurly,
|
1463
1463
|
{ includeComments: true, filter: astUtils.isCommentToken }
|
1464
1464
|
).forEach(token => offsets.ignoreToken(token));
|
@@ -1488,7 +1488,7 @@ module.exports = {
|
|
1488
1488
|
},
|
1489
1489
|
|
1490
1490
|
VariableDeclaration(node) {
|
1491
|
-
let variableIndent = Object.
|
1491
|
+
let variableIndent = Object.hasOwn(options.VariableDeclarator, node.kind)
|
1492
1492
|
? options.VariableDeclarator[node.kind]
|
1493
1493
|
: DEFAULT_VARIABLE_INDENT;
|
1494
1494
|
|
@@ -1509,7 +1509,7 @@ module.exports = {
|
|
1509
1509
|
variableIndent = DEFAULT_VARIABLE_INDENT;
|
1510
1510
|
}
|
1511
1511
|
|
1512
|
-
if (node.declarations
|
1512
|
+
if (node.declarations.at(-1).loc.start.line > node.loc.start.line) {
|
1513
1513
|
|
1514
1514
|
/*
|
1515
1515
|
* VariableDeclarator indentation is a bit different from other forms of indentation, in that the
|
package/lib/rules/index.js
CHANGED
@@ -229,6 +229,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
|
|
229
229
|
"no-unused-private-class-members": () => require("./no-unused-private-class-members"),
|
230
230
|
"no-unused-vars": () => require("./no-unused-vars"),
|
231
231
|
"no-use-before-define": () => require("./no-use-before-define"),
|
232
|
+
"no-useless-assignment": () => require("./no-useless-assignment"),
|
232
233
|
"no-useless-backreference": () => require("./no-useless-backreference"),
|
233
234
|
"no-useless-call": () => require("./no-useless-call"),
|
234
235
|
"no-useless-catch": () => require("./no-useless-catch"),
|
package/lib/rules/key-spacing.js
CHANGED
@@ -28,7 +28,7 @@ function containsLineTerminator(str) {
|
|
28
28
|
* @returns {any} Last element of arr.
|
29
29
|
*/
|
30
30
|
function last(arr) {
|
31
|
-
return arr
|
31
|
+
return arr.at(-1);
|
32
32
|
}
|
33
33
|
|
34
34
|
/**
|
@@ -489,7 +489,7 @@ module.exports = {
|
|
489
489
|
}
|
490
490
|
}
|
491
491
|
|
492
|
-
let messageId
|
492
|
+
let messageId;
|
493
493
|
|
494
494
|
if (isExtra) {
|
495
495
|
messageId = side === "key" ? "extraKey" : "extraValue";
|
@@ -68,7 +68,7 @@ module.exports = {
|
|
68
68
|
above = !options.position || options.position === "above";
|
69
69
|
ignorePattern = options.ignorePattern;
|
70
70
|
|
71
|
-
if (Object.
|
71
|
+
if (Object.hasOwn(options, "applyDefaultIgnorePatterns")) {
|
72
72
|
applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns;
|
73
73
|
} else {
|
74
74
|
applyDefaultIgnorePatterns = options.applyDefaultPatterns !== false;
|
@@ -166,7 +166,7 @@ module.exports = {
|
|
166
166
|
reportError(firstDirective, "before", false);
|
167
167
|
}
|
168
168
|
|
169
|
-
const lastDirective = directives
|
169
|
+
const lastDirective = directives.at(-1);
|
170
170
|
const statements = node.type === "Program" ? node.body : node.body.body;
|
171
171
|
|
172
172
|
/*
|
@@ -174,7 +174,7 @@ module.exports = {
|
|
174
174
|
* contains a directive prologue and isn't followed by a comment to ensure
|
175
175
|
* this rule behaves well with padded-blocks.
|
176
176
|
*/
|
177
|
-
if (lastDirective === statements
|
177
|
+
if (lastDirective === statements.at(-1) && !lastDirective.trailingComments) {
|
178
178
|
return;
|
179
179
|
}
|
180
180
|
|
package/lib/rules/max-depth.js
CHANGED
@@ -61,7 +61,7 @@ module.exports = {
|
|
61
61
|
|
62
62
|
if (
|
63
63
|
typeof option === "object" &&
|
64
|
-
(Object.
|
64
|
+
(Object.hasOwn(option, "maximum") || Object.hasOwn(option, "max"))
|
65
65
|
) {
|
66
66
|
maxDepth = option.maximum || option.max;
|
67
67
|
}
|
package/lib/rules/max-len.js
CHANGED
@@ -124,7 +124,7 @@ module.exports = {
|
|
124
124
|
}
|
125
125
|
|
126
126
|
// The options object must be the last option specified…
|
127
|
-
const options = Object.assign({}, context.options
|
127
|
+
const options = Object.assign({}, context.options.at(-1));
|
128
128
|
|
129
129
|
// …but max code length…
|
130
130
|
if (typeof context.options[0] === "number") {
|
@@ -290,7 +290,7 @@ module.exports = {
|
|
290
290
|
if (isJSXEmptyExpressionInSingleLineContainer(containingNode)) {
|
291
291
|
|
292
292
|
// push a unique node only
|
293
|
-
if (comments
|
293
|
+
if (comments.at(-1) !== containingNode.parent) {
|
294
294
|
comments.push(containingNode.parent);
|
295
295
|
}
|
296
296
|
} else {
|
@@ -344,7 +344,7 @@ module.exports = {
|
|
344
344
|
* comments to check.
|
345
345
|
*/
|
346
346
|
if (commentsIndex < comments.length) {
|
347
|
-
let comment
|
347
|
+
let comment;
|
348
348
|
|
349
349
|
// iterate over comments until we find one past the current line
|
350
350
|
do {
|
package/lib/rules/max-lines.js
CHANGED
@@ -77,7 +77,7 @@ module.exports = {
|
|
77
77
|
|
78
78
|
if (
|
79
79
|
typeof option === "object" &&
|
80
|
-
Object.
|
80
|
+
Object.hasOwn(option, "max")
|
81
81
|
) {
|
82
82
|
max = option.max;
|
83
83
|
} else if (typeof option === "number") {
|
@@ -148,7 +148,7 @@ module.exports = {
|
|
148
148
|
* If file ends with a linebreak, `sourceCode.lines` will have one extra empty line at the end.
|
149
149
|
* That isn't a real line, so we shouldn't count it.
|
150
150
|
*/
|
151
|
-
if (lines.length > 1 && lines
|
151
|
+
if (lines.length > 1 && lines.at(-1).text === "") {
|
152
152
|
lines.pop();
|
153
153
|
}
|
154
154
|
|
@@ -174,7 +174,7 @@ module.exports = {
|
|
174
174
|
},
|
175
175
|
end: {
|
176
176
|
line: sourceCode.lines.length,
|
177
|
-
column: sourceCode.lines
|
177
|
+
column: sourceCode.lines.at(-1).length
|
178
178
|
}
|
179
179
|
};
|
180
180
|
|
@@ -59,7 +59,7 @@ module.exports = {
|
|
59
59
|
|
60
60
|
if (
|
61
61
|
typeof option === "object" &&
|
62
|
-
(Object.
|
62
|
+
(Object.hasOwn(option, "maximum") || Object.hasOwn(option, "max"))
|
63
63
|
) {
|
64
64
|
THRESHOLD = option.maximum || option.max;
|
65
65
|
} else if (typeof option === "number") {
|
package/lib/rules/max-params.js
CHANGED
@@ -63,7 +63,7 @@ module.exports = {
|
|
63
63
|
|
64
64
|
if (
|
65
65
|
typeof option === "object" &&
|
66
|
-
(Object.
|
66
|
+
(Object.hasOwn(option, "maximum") || Object.hasOwn(option, "max"))
|
67
67
|
) {
|
68
68
|
numParams = option.maximum || option.max;
|
69
69
|
}
|
@@ -79,7 +79,7 @@ module.exports = {
|
|
79
79
|
|
80
80
|
if (
|
81
81
|
typeof option === "object" &&
|
82
|
-
(Object.
|
82
|
+
(Object.hasOwn(option, "maximum") || Object.hasOwn(option, "max"))
|
83
83
|
) {
|
84
84
|
maxStatements = option.maximum || option.max;
|
85
85
|
} else if (typeof option === "number") {
|
@@ -113,7 +113,7 @@ module.exports = {
|
|
113
113
|
|
114
114
|
return /^\*\s*$/u.test(lines[0]) &&
|
115
115
|
lines.slice(1, -1).every(line => /^\s* /u.test(line)) &&
|
116
|
-
/^\s*$/u.test(lines
|
116
|
+
/^\s*$/u.test(lines.at(-1));
|
117
117
|
}
|
118
118
|
|
119
119
|
/**
|
@@ -272,11 +272,11 @@ module.exports = {
|
|
272
272
|
context.report({
|
273
273
|
loc: {
|
274
274
|
start: firstComment.loc.start,
|
275
|
-
end: commentGroup
|
275
|
+
end: commentGroup.at(-1).loc.end
|
276
276
|
},
|
277
277
|
messageId: "expectedBlock",
|
278
278
|
fix(fixer) {
|
279
|
-
const range = [firstComment.range[0], commentGroup
|
279
|
+
const range = [firstComment.range[0], commentGroup.at(-1).range[1]];
|
280
280
|
|
281
281
|
return commentLines.some(value => value.startsWith("/"))
|
282
282
|
? null
|
@@ -301,7 +301,7 @@ module.exports = {
|
|
301
301
|
});
|
302
302
|
}
|
303
303
|
|
304
|
-
if (!/^\s*$/u.test(lines
|
304
|
+
if (!/^\s*$/u.test(lines.at(-1))) {
|
305
305
|
context.report({
|
306
306
|
loc: {
|
307
307
|
start: { line: firstComment.loc.end.line, column: firstComment.loc.end.column - 2 },
|
@@ -408,12 +408,12 @@ module.exports = {
|
|
408
408
|
context.report({
|
409
409
|
loc: {
|
410
410
|
start: firstComment.loc.start,
|
411
|
-
end: commentGroup
|
411
|
+
end: commentGroup.at(-1).loc.end
|
412
412
|
},
|
413
413
|
messageId: "expectedBlock",
|
414
414
|
fix(fixer) {
|
415
415
|
return fixer.replaceTextRange(
|
416
|
-
[firstComment.range[0], commentGroup
|
416
|
+
[firstComment.range[0], commentGroup.at(-1).range[1]],
|
417
417
|
convertToBlock(firstComment, commentLines)
|
418
418
|
);
|
419
419
|
}
|
@@ -459,7 +459,7 @@ module.exports = {
|
|
459
459
|
tokenBefore && tokenBefore.loc.end.line === comment.loc.start.line - 1 &&
|
460
460
|
tokenBefore === commentList[index - 1]
|
461
461
|
) {
|
462
|
-
commentGroups
|
462
|
+
commentGroups.at(-1).push(comment);
|
463
463
|
} else {
|
464
464
|
commentGroups.push([comment]);
|
465
465
|
}
|
package/lib/rules/new-cap.js
CHANGED
@@ -40,7 +40,7 @@ const CAPS_ALLOWED = [
|
|
40
40
|
function checkArray(obj, key, fallback) {
|
41
41
|
|
42
42
|
/* c8 ignore start */
|
43
|
-
if (Object.
|
43
|
+
if (Object.hasOwn(obj, key) && !Array.isArray(obj[key])) {
|
44
44
|
throw new TypeError(`${key}, if provided, must be an Array`);
|
45
45
|
}/* c8 ignore stop */
|
46
46
|
return obj[key] || fallback;
|
@@ -215,7 +215,7 @@ module.exports = {
|
|
215
215
|
fix(fixer) {
|
216
216
|
const linesBetween = sourceCode.getText().slice(lastToken.range[1], nextToken.range[0]).split(astUtils.LINEBREAK_MATCHER);
|
217
217
|
|
218
|
-
return fixer.replaceTextRange([lastToken.range[1], nextToken.range[0]], `${linesBetween.slice(0, -1).join("")}\n${linesBetween
|
218
|
+
return fixer.replaceTextRange([lastToken.range[1], nextToken.range[0]], `${linesBetween.slice(0, -1).join("")}\n${linesBetween.at(-1)}`);
|
219
219
|
}
|
220
220
|
});
|
221
221
|
}
|
@@ -166,7 +166,7 @@ module.exports = {
|
|
166
166
|
*/
|
167
167
|
function canFix(node) {
|
168
168
|
const leadingComments = sourceCode.getCommentsBefore(node);
|
169
|
-
const lastLeadingComment = leadingComments
|
169
|
+
const lastLeadingComment = leadingComments.at(-1);
|
170
170
|
const tokenBefore = sourceCode.getTokenBefore(node);
|
171
171
|
|
172
172
|
if (leadingComments.length === 0) {
|
@@ -103,7 +103,7 @@ function hasConstantNullishness(scope, node, nonNullish) {
|
|
103
103
|
|
104
104
|
return true;
|
105
105
|
case "SequenceExpression": {
|
106
|
-
const last = node.expressions
|
106
|
+
const last = node.expressions.at(-1);
|
107
107
|
|
108
108
|
return hasConstantNullishness(scope, last, nonNullish);
|
109
109
|
}
|
@@ -248,7 +248,7 @@ function hasConstantLooseBooleanComparison(scope, node) {
|
|
248
248
|
*/
|
249
249
|
return false;
|
250
250
|
case "SequenceExpression": {
|
251
|
-
const last = node.expressions
|
251
|
+
const last = node.expressions.at(-1);
|
252
252
|
|
253
253
|
return hasConstantLooseBooleanComparison(scope, last);
|
254
254
|
}
|
@@ -299,7 +299,7 @@ function hasConstantStrictBooleanComparison(scope, node) {
|
|
299
299
|
return true;
|
300
300
|
}
|
301
301
|
case "SequenceExpression": {
|
302
|
-
const last = node.expressions
|
302
|
+
const last = node.expressions.at(-1);
|
303
303
|
|
304
304
|
return hasConstantStrictBooleanComparison(scope, last);
|
305
305
|
}
|
@@ -376,7 +376,7 @@ function isAlwaysNew(scope, node) {
|
|
376
376
|
* Catching these is especially useful for primitive constructors
|
377
377
|
* which return boxed values, a surprising gotcha' in JavaScript.
|
378
378
|
*/
|
379
|
-
return Object.
|
379
|
+
return Object.hasOwn(globals.builtin, node.callee.name) &&
|
380
380
|
isReferenceToGlobalVariable(scope, node.callee);
|
381
381
|
}
|
382
382
|
case "Literal":
|
@@ -384,7 +384,7 @@ function isAlwaysNew(scope, node) {
|
|
384
384
|
// Regular expressions are objects, and thus always new
|
385
385
|
return typeof node.regex === "object";
|
386
386
|
case "SequenceExpression": {
|
387
|
-
const last = node.expressions
|
387
|
+
const last = node.expressions.at(-1);
|
388
388
|
|
389
389
|
return isAlwaysNew(scope, last);
|
390
390
|
}
|
@@ -42,7 +42,7 @@ module.exports = {
|
|
42
42
|
* - retv.set {boolean} A flag which shows the name is declared as setter.
|
43
43
|
*/
|
44
44
|
function getState(name, isStatic) {
|
45
|
-
const stateMap = stack
|
45
|
+
const stateMap = stack.at(-1);
|
46
46
|
const key = `$${name}`; // to avoid "__proto__".
|
47
47
|
|
48
48
|
if (!stateMap[key]) {
|
@@ -82,7 +82,7 @@ module.exports = {
|
|
82
82
|
}
|
83
83
|
|
84
84
|
const state = getState(name, node.static);
|
85
|
-
let isDuplicate
|
85
|
+
let isDuplicate;
|
86
86
|
|
87
87
|
if (kind === "get") {
|
88
88
|
isDuplicate = (state.init || state.get);
|
@@ -270,7 +270,7 @@ module.exports = {
|
|
270
270
|
function naiveHasReturn(node) {
|
271
271
|
if (node.type === "BlockStatement") {
|
272
272
|
const body = node.body,
|
273
|
-
lastChildNode = body
|
273
|
+
lastChildNode = body.at(-1);
|
274
274
|
|
275
275
|
return lastChildNode && checkForReturn(lastChildNode);
|
276
276
|
}
|
@@ -40,7 +40,7 @@ const ALLOW_OPTIONS = Object.freeze([
|
|
40
40
|
*/
|
41
41
|
function getKind(node) {
|
42
42
|
const parent = node.parent;
|
43
|
-
let kind
|
43
|
+
let kind;
|
44
44
|
|
45
45
|
if (node.type === "ArrowFunctionExpression") {
|
46
46
|
return "arrowFunctions";
|
@@ -73,7 +73,7 @@ function getKind(node) {
|
|
73
73
|
}
|
74
74
|
|
75
75
|
// Detects prefix.
|
76
|
-
let prefix
|
76
|
+
let prefix;
|
77
77
|
|
78
78
|
if (node.generator) {
|
79
79
|
prefix = "generator";
|
@@ -187,7 +187,7 @@ module.exports = {
|
|
187
187
|
*/
|
188
188
|
if (isAnySegmentReachable(currentCodePathSegments) &&
|
189
189
|
(node.consequent.length > 0 || (!allowEmptyCase && hasBlankLinesBetween(node, nextToken))) &&
|
190
|
-
node.parent.cases
|
190
|
+
node.parent.cases.at(-1) !== node) {
|
191
191
|
fallthroughCase = node;
|
192
192
|
}
|
193
193
|
}
|
@@ -56,6 +56,15 @@ module.exports = {
|
|
56
56
|
schema: [
|
57
57
|
{
|
58
58
|
enum: ["functions", "both"]
|
59
|
+
},
|
60
|
+
{
|
61
|
+
type: "object",
|
62
|
+
properties: {
|
63
|
+
blockScopedFunctions: {
|
64
|
+
enum: ["allow", "disallow"]
|
65
|
+
}
|
66
|
+
},
|
67
|
+
additionalProperties: false
|
59
68
|
}
|
60
69
|
],
|
61
70
|
|
@@ -66,6 +75,10 @@ module.exports = {
|
|
66
75
|
|
67
76
|
create(context) {
|
68
77
|
|
78
|
+
const sourceCode = context.sourceCode;
|
79
|
+
const ecmaVersion = context.languageOptions.ecmaVersion;
|
80
|
+
const blockScopedFunctions = context.options[1]?.blockScopedFunctions ?? "allow";
|
81
|
+
|
69
82
|
/**
|
70
83
|
* Ensure that a given node is at a program or function body's root.
|
71
84
|
* @param {ASTNode} node Declaration node to check.
|
@@ -97,7 +110,15 @@ module.exports = {
|
|
97
110
|
|
98
111
|
return {
|
99
112
|
|
100
|
-
FunctionDeclaration
|
113
|
+
FunctionDeclaration(node) {
|
114
|
+
const isInStrictCode = sourceCode.getScope(node).upper.isStrict;
|
115
|
+
|
116
|
+
if (blockScopedFunctions === "allow" && ecmaVersion >= 2015 && isInStrictCode) {
|
117
|
+
return;
|
118
|
+
}
|
119
|
+
|
120
|
+
check(node);
|
121
|
+
},
|
101
122
|
VariableDeclaration(node) {
|
102
123
|
if (context.options[0] === "both" && node.kind === "var") {
|
103
124
|
check(node);
|
@@ -74,7 +74,7 @@ module.exports = {
|
|
74
74
|
* an object which has a flag that whether or not `this` keyword is valid.
|
75
75
|
*/
|
76
76
|
stack.getCurrent = function() {
|
77
|
-
const current = this
|
77
|
+
const current = this.at(-1);
|
78
78
|
|
79
79
|
if (!current.init) {
|
80
80
|
current.init = true;
|
@@ -78,7 +78,7 @@ module.exports = {
|
|
78
78
|
|
79
79
|
const block = node.parent;
|
80
80
|
|
81
|
-
if (loneBlocks
|
81
|
+
if (loneBlocks.at(-1) === block) {
|
82
82
|
loneBlocks.pop();
|
83
83
|
}
|
84
84
|
}
|
@@ -101,7 +101,7 @@ module.exports = {
|
|
101
101
|
}
|
102
102
|
},
|
103
103
|
"BlockStatement:exit"(node) {
|
104
|
-
if (loneBlocks.length > 0 && loneBlocks
|
104
|
+
if (loneBlocks.length > 0 && loneBlocks.at(-1) === node) {
|
105
105
|
loneBlocks.pop();
|
106
106
|
report(node);
|
107
107
|
} else if (
|