eslint 8.0.0 → 8.3.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 +8 -2
- package/lib/cli-engine/cli-engine.js +10 -21
- package/lib/eslint/eslint.js +2 -15
- package/lib/linter/code-path-analysis/code-path-analyzer.js +6 -1
- package/lib/linter/code-path-analysis/code-path.js +1 -1
- package/lib/linter/config-comment-parser.js +1 -1
- package/lib/linter/linter.js +2 -2
- package/lib/linter/node-event-generator.js +7 -0
- package/lib/rule-tester/rule-tester.js +5 -2
- package/lib/rules/block-scoped-var.js +2 -0
- package/lib/rules/block-spacing.js +10 -3
- package/lib/rules/brace-style.js +6 -0
- package/lib/rules/class-methods-use-this.js +10 -1
- package/lib/rules/complexity.js +14 -6
- package/lib/rules/indent.js +21 -0
- package/lib/rules/index.js +1 -0
- package/lib/rules/key-spacing.js +14 -13
- package/lib/rules/keyword-spacing.js +15 -1
- package/lib/rules/lines-around-comment.js +54 -7
- package/lib/rules/max-depth.js +2 -0
- package/lib/rules/max-statements.js +10 -0
- package/lib/rules/no-eval.js +2 -0
- package/lib/rules/no-extra-semi.js +1 -1
- package/lib/rules/no-inner-declarations.js +26 -4
- package/lib/rules/no-invalid-this.js +4 -0
- package/lib/rules/no-lone-blocks.js +8 -2
- package/lib/rules/no-redeclare.js +2 -0
- package/lib/rules/no-unused-expressions.js +6 -0
- package/lib/rules/no-unused-private-class-members.js +194 -0
- package/lib/rules/no-use-before-define.js +175 -74
- package/lib/rules/one-var.js +5 -1
- package/lib/rules/padded-blocks.js +8 -0
- package/lib/rules/padding-line-between-statements.js +2 -0
- package/lib/rules/prefer-const.js +1 -1
- package/lib/rules/require-atomic-updates.js +14 -2
- package/lib/rules/semi-style.js +8 -2
- package/lib/rules/semi.js +18 -9
- package/lib/rules/utils/ast-utils.js +15 -3
- package/lib/rules/vars-on-top.js +25 -12
- package/lib/shared/types.js +1 -1
- package/package.json +9 -9
package/README.md
CHANGED
@@ -206,6 +206,9 @@ This means:
|
|
206
206
|
These folks keep the project moving and are resources for help.
|
207
207
|
|
208
208
|
<!-- NOTE: This section is autogenerated. Do not manually edit.-->
|
209
|
+
|
210
|
+
|
211
|
+
|
209
212
|
<!--teamstart-->
|
210
213
|
|
211
214
|
### Technical Steering Committee (TSC)
|
@@ -242,7 +245,7 @@ Toru Nagashima
|
|
242
245
|
</td><td align="center" valign="top" width="11%">
|
243
246
|
<a href="https://github.com/aladdin-add">
|
244
247
|
<img src="https://github.com/aladdin-add.png?s=75" width="75" height="75"><br />
|
245
|
-
|
248
|
+
唯然
|
246
249
|
</a>
|
247
250
|
</td></tr></tbody></table>
|
248
251
|
|
@@ -288,6 +291,9 @@ Nitin Kumar
|
|
288
291
|
|
289
292
|
<!--teamend-->
|
290
293
|
|
294
|
+
|
295
|
+
|
296
|
+
|
291
297
|
## <a name="sponsors"></a>Sponsors
|
292
298
|
|
293
299
|
The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://opencollective.com/eslint) to get your logo on our README and website.
|
@@ -298,7 +304,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
|
|
298
304
|
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/photomatt/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
|
299
305
|
<p><a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" height="96"></a> <a href="https://google.com/chrome"><img src="https://images.opencollective.com/chrome/dc55bd4/logo.png" alt="Chrome's Web Framework & Tools Performance Fund" height="96"></a> <a href="https://www.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a> <a href="https://coinbase.com"><img src="https://avatars.githubusercontent.com/u/1885080?v=4" alt="Coinbase" height="96"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="96"></a> <a href="https://substack.com/"><img src="https://avatars.githubusercontent.com/u/53023767?v=4" alt="Substack" height="96"></a></p><h3>Silver Sponsors</h3>
|
300
306
|
<p><a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a></p><h3>Bronze Sponsors</h3>
|
301
|
-
<p><a href="https://launchdarkly.com"><img src="https://images.opencollective.com/launchdarkly/574bb9e/logo.png" alt="launchdarkly" height="32"></a> <a href="https://troypoint.com"><img src="https://images.opencollective.com/troypoint/080f96f/avatar.png" alt="TROYPOINT" height="32"></a> <a href="https://
|
307
|
+
<p><a href="https://launchdarkly.com"><img src="https://images.opencollective.com/launchdarkly/574bb9e/logo.png" alt="launchdarkly" height="32"></a> <a href="https://troypoint.com"><img src="https://images.opencollective.com/troypoint/080f96f/avatar.png" alt="TROYPOINT" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a> <a href="https://www.practiceignition.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Practice Ignition" height="32"></a></p>
|
302
308
|
<!--sponsorsend-->
|
303
309
|
|
304
310
|
## <a name="technology-sponsors"></a>Technology Sponsors
|
@@ -570,8 +570,10 @@ class CLIEngine {
|
|
570
570
|
/**
|
571
571
|
* Creates a new instance of the core CLI engine.
|
572
572
|
* @param {CLIEngineOptions} providedOptions The options for this instance.
|
573
|
+
* @param {Object} [additionalData] Additional settings that are not CLIEngineOptions.
|
574
|
+
* @param {Record<string,Plugin>|null} [additionalData.preloadedPlugins] Preloaded plugins.
|
573
575
|
*/
|
574
|
-
constructor(providedOptions) {
|
576
|
+
constructor(providedOptions, { preloadedPlugins } = {}) {
|
575
577
|
const options = Object.assign(
|
576
578
|
Object.create(null),
|
577
579
|
defaultOptions,
|
@@ -584,6 +586,13 @@ class CLIEngine {
|
|
584
586
|
}
|
585
587
|
|
586
588
|
const additionalPluginPool = new Map();
|
589
|
+
|
590
|
+
if (preloadedPlugins) {
|
591
|
+
for (const [id, plugin] of Object.entries(preloadedPlugins)) {
|
592
|
+
additionalPluginPool.set(id, plugin);
|
593
|
+
}
|
594
|
+
}
|
595
|
+
|
587
596
|
const cacheFilePath = getCacheFile(
|
588
597
|
options.cacheLocation || options.cacheFile,
|
589
598
|
options.cwd
|
@@ -698,26 +707,6 @@ class CLIEngine {
|
|
698
707
|
});
|
699
708
|
}
|
700
709
|
|
701
|
-
|
702
|
-
/**
|
703
|
-
* Add a plugin by passing its configuration
|
704
|
-
* @param {string} name Name of the plugin.
|
705
|
-
* @param {Plugin} pluginObject Plugin configuration object.
|
706
|
-
* @returns {void}
|
707
|
-
*/
|
708
|
-
addPlugin(name, pluginObject) {
|
709
|
-
const {
|
710
|
-
additionalPluginPool,
|
711
|
-
configArrayFactory,
|
712
|
-
lastConfigArrays
|
713
|
-
} = internalSlotsMap.get(this);
|
714
|
-
|
715
|
-
additionalPluginPool.set(name, pluginObject);
|
716
|
-
configArrayFactory.clearCache();
|
717
|
-
lastConfigArrays.length = 1;
|
718
|
-
lastConfigArrays[0] = configArrayFactory.getConfigArrayForFile();
|
719
|
-
}
|
720
|
-
|
721
710
|
/**
|
722
711
|
* Resolves the patterns passed into executeOnFiles() into glob-based patterns
|
723
712
|
* for easier handling.
|
package/lib/eslint/eslint.js
CHANGED
@@ -54,7 +54,7 @@ const { version } = require("../../package.json");
|
|
54
54
|
* @property {string} [ignorePath] The ignore file to use instead of .eslintignore.
|
55
55
|
* @property {ConfigData} [overrideConfig] Override config object, overrides all configs used with this instance
|
56
56
|
* @property {string} [overrideConfigFile] The configuration file to use.
|
57
|
-
* @property {Record<string,Plugin
|
57
|
+
* @property {Record<string,Plugin>|null} [plugins] Preloaded plugins. This is a map-like object, keys are plugin IDs and each value is implementation.
|
58
58
|
* @property {"error" | "warn" | "off"} [reportUnusedDisableDirectives] the severity to report unused eslint-disable directives.
|
59
59
|
* @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD.
|
60
60
|
* @property {string[]} [rulePaths] An array of directories to load custom rules from.
|
@@ -433,26 +433,13 @@ class ESLint {
|
|
433
433
|
*/
|
434
434
|
constructor(options = {}) {
|
435
435
|
const processedOptions = processOptions(options);
|
436
|
-
const cliEngine = new CLIEngine(processedOptions);
|
436
|
+
const cliEngine = new CLIEngine(processedOptions, { preloadedPlugins: options.plugins });
|
437
437
|
const {
|
438
|
-
additionalPluginPool,
|
439
438
|
configArrayFactory,
|
440
439
|
lastConfigArrays
|
441
440
|
} = getCLIEngineInternalSlots(cliEngine);
|
442
441
|
let updated = false;
|
443
442
|
|
444
|
-
/*
|
445
|
-
* Address `plugins` to add plugin implementations.
|
446
|
-
* Operate the `additionalPluginPool` internal slot directly to avoid
|
447
|
-
* using `addPlugin(id, plugin)` method that resets cache everytime.
|
448
|
-
*/
|
449
|
-
if (options.plugins) {
|
450
|
-
for (const [id, plugin] of Object.entries(options.plugins)) {
|
451
|
-
additionalPluginPool.set(id, plugin);
|
452
|
-
updated = true;
|
453
|
-
}
|
454
|
-
}
|
455
|
-
|
456
443
|
/*
|
457
444
|
* Address `overrideConfig` to set override config.
|
458
445
|
* Operate the `configArrayFactory` internal slot directly because this
|
@@ -461,6 +461,10 @@ function processCodePathToEnter(analyzer, node) {
|
|
461
461
|
startCodePath("function");
|
462
462
|
break;
|
463
463
|
|
464
|
+
case "StaticBlock":
|
465
|
+
startCodePath("class-static-block");
|
466
|
+
break;
|
467
|
+
|
464
468
|
case "ChainExpression":
|
465
469
|
state.pushChainContext();
|
466
470
|
break;
|
@@ -706,7 +710,8 @@ function postprocess(analyzer, node) {
|
|
706
710
|
case "Program":
|
707
711
|
case "FunctionDeclaration":
|
708
712
|
case "FunctionExpression":
|
709
|
-
case "ArrowFunctionExpression":
|
713
|
+
case "ArrowFunctionExpression":
|
714
|
+
case "StaticBlock": {
|
710
715
|
endCodePath();
|
711
716
|
break;
|
712
717
|
}
|
@@ -40,7 +40,7 @@ class CodePath {
|
|
40
40
|
|
41
41
|
/**
|
42
42
|
* The reason that this code path was started. May be "program",
|
43
|
-
* "function",
|
43
|
+
* "function", "class-field-initializer", or "class-static-block".
|
44
44
|
* @type {string}
|
45
45
|
*/
|
46
46
|
this.origin = origin;
|
@@ -15,7 +15,7 @@ const levn = require("levn"),
|
|
15
15
|
Legacy: {
|
16
16
|
ConfigOps
|
17
17
|
}
|
18
|
-
} = require("@eslint/eslintrc/universal");
|
18
|
+
} = require("@eslint/eslintrc/universal");
|
19
19
|
|
20
20
|
const debug = require("debug")("eslint:config-comment-parser");
|
21
21
|
|
package/lib/linter/linter.js
CHANGED
@@ -24,7 +24,7 @@ const
|
|
24
24
|
ConfigValidator,
|
25
25
|
environments: BuiltInEnvironments
|
26
26
|
}
|
27
|
-
} = require("@eslint/eslintrc/universal"),
|
27
|
+
} = require("@eslint/eslintrc/universal"),
|
28
28
|
Traverser = require("../shared/traverser"),
|
29
29
|
{ SourceCode } = require("../source-code"),
|
30
30
|
CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"),
|
@@ -626,7 +626,7 @@ function analyzeScope(ast, parserOptions, visitorKeys) {
|
|
626
626
|
ignoreEval: true,
|
627
627
|
nodejsScope: ecmaFeatures.globalReturn,
|
628
628
|
impliedStrict: ecmaFeatures.impliedStrict,
|
629
|
-
ecmaVersion,
|
629
|
+
ecmaVersion: typeof ecmaVersion === "number" ? ecmaVersion : 6,
|
630
630
|
sourceType: parserOptions.sourceType || "script",
|
631
631
|
childVisitorKeys: visitorKeys || evk.KEYS,
|
632
632
|
fallback: Traverser.getKeys
|
@@ -98,6 +98,13 @@ function getPossibleTypes(parsedSelector) {
|
|
98
98
|
case "adjacent":
|
99
99
|
return getPossibleTypes(parsedSelector.right);
|
100
100
|
|
101
|
+
case "class":
|
102
|
+
if (parsedSelector.name === "function") {
|
103
|
+
return ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"];
|
104
|
+
}
|
105
|
+
|
106
|
+
return null;
|
107
|
+
|
101
108
|
default:
|
102
109
|
return null;
|
103
110
|
|
@@ -67,6 +67,7 @@ const { SourceCode } = require("../source-code");
|
|
67
67
|
/**
|
68
68
|
* A test case that is expected to pass lint.
|
69
69
|
* @typedef {Object} ValidTestCase
|
70
|
+
* @property {string} [name] Name for the test case.
|
70
71
|
* @property {string} code Code for the test case.
|
71
72
|
* @property {any[]} [options] Options for the test case.
|
72
73
|
* @property {{ [name: string]: any }} [settings] Settings for the test case.
|
@@ -81,6 +82,7 @@ const { SourceCode } = require("../source-code");
|
|
81
82
|
/**
|
82
83
|
* A test case that is expected to fail lint.
|
83
84
|
* @typedef {Object} InvalidTestCase
|
85
|
+
* @property {string} [name] Name for the test case.
|
84
86
|
* @property {string} code Code for the test case.
|
85
87
|
* @property {number | Array<TestCaseError | string | RegExp>} errors Expected errors.
|
86
88
|
* @property {string | null} [output] The expected code after autofixes are applied. If set to `null`, the test runner will assert that no autofix is suggested.
|
@@ -124,6 +126,7 @@ let defaultConfig = { rules: {} };
|
|
124
126
|
* configuration
|
125
127
|
*/
|
126
128
|
const RuleTesterParameters = [
|
129
|
+
"name",
|
127
130
|
"code",
|
128
131
|
"filename",
|
129
132
|
"options",
|
@@ -964,7 +967,7 @@ class RuleTester {
|
|
964
967
|
RuleTester.describe("valid", () => {
|
965
968
|
test.valid.forEach(valid => {
|
966
969
|
RuleTester[valid.only ? "itOnly" : "it"](
|
967
|
-
sanitize(typeof valid === "object" ? valid.code : valid),
|
970
|
+
sanitize(typeof valid === "object" ? valid.name || valid.code : valid),
|
968
971
|
() => {
|
969
972
|
testValidTemplate(valid);
|
970
973
|
}
|
@@ -975,7 +978,7 @@ class RuleTester {
|
|
975
978
|
RuleTester.describe("invalid", () => {
|
976
979
|
test.invalid.forEach(invalid => {
|
977
980
|
RuleTester[invalid.only ? "itOnly" : "it"](
|
978
|
-
sanitize(invalid.code),
|
981
|
+
sanitize(invalid.name || invalid.code),
|
979
982
|
() => {
|
980
983
|
testInvalidTemplate(invalid);
|
981
984
|
}
|
@@ -112,6 +112,8 @@ module.exports = {
|
|
112
112
|
"SwitchStatement:exit": exitScope,
|
113
113
|
CatchClause: enterScope,
|
114
114
|
"CatchClause:exit": exitScope,
|
115
|
+
StaticBlock: enterScope,
|
116
|
+
"StaticBlock:exit": exitScope,
|
115
117
|
|
116
118
|
// Finds and reports references which are outside of valid scope.
|
117
119
|
VariableDeclaration: checkForVariables
|
@@ -40,7 +40,7 @@ module.exports = {
|
|
40
40
|
|
41
41
|
/**
|
42
42
|
* Gets the open brace token from a given node.
|
43
|
-
* @param {ASTNode} node A BlockStatement/SwitchStatement node to get.
|
43
|
+
* @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to get.
|
44
44
|
* @returns {Token} The token of the open brace.
|
45
45
|
*/
|
46
46
|
function getOpenBrace(node) {
|
@@ -50,6 +50,12 @@ module.exports = {
|
|
50
50
|
}
|
51
51
|
return sourceCode.getLastToken(node, 1);
|
52
52
|
}
|
53
|
+
|
54
|
+
if (node.type === "StaticBlock") {
|
55
|
+
return sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token
|
56
|
+
}
|
57
|
+
|
58
|
+
// "BlockStatement"
|
53
59
|
return sourceCode.getFirstToken(node);
|
54
60
|
}
|
55
61
|
|
@@ -72,8 +78,8 @@ module.exports = {
|
|
72
78
|
}
|
73
79
|
|
74
80
|
/**
|
75
|
-
*
|
76
|
-
* @param {ASTNode} node A BlockStatement/SwitchStatement node to
|
81
|
+
* Checks and reports invalid spacing style inside braces.
|
82
|
+
* @param {ASTNode} node A BlockStatement/StaticBlock/SwitchStatement node to check.
|
77
83
|
* @returns {void}
|
78
84
|
*/
|
79
85
|
function checkSpacingInsideBraces(node) {
|
@@ -157,6 +163,7 @@ module.exports = {
|
|
157
163
|
|
158
164
|
return {
|
159
165
|
BlockStatement: checkSpacingInsideBraces,
|
166
|
+
StaticBlock: checkSpacingInsideBraces,
|
160
167
|
SwitchStatement: checkSpacingInsideBraces
|
161
168
|
};
|
162
169
|
}
|
package/lib/rules/brace-style.js
CHANGED
@@ -155,6 +155,12 @@ module.exports = {
|
|
155
155
|
validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node));
|
156
156
|
}
|
157
157
|
},
|
158
|
+
StaticBlock(node) {
|
159
|
+
validateCurlyPair(
|
160
|
+
sourceCode.getFirstToken(node, { skip: 1 }), // skip the `static` token
|
161
|
+
sourceCode.getLastToken(node)
|
162
|
+
);
|
163
|
+
},
|
158
164
|
ClassBody(node) {
|
159
165
|
validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node));
|
160
166
|
},
|
@@ -161,8 +161,17 @@ module.exports = {
|
|
161
161
|
/*
|
162
162
|
* Class field value are implicit functions.
|
163
163
|
*/
|
164
|
-
"PropertyDefinition:exit": popContext,
|
165
164
|
"PropertyDefinition > *.key:exit": pushContext,
|
165
|
+
"PropertyDefinition:exit": popContext,
|
166
|
+
|
167
|
+
/*
|
168
|
+
* Class static blocks are implicit functions. They aren't required to use `this`,
|
169
|
+
* but we have to push context so that it captures any use of `this` in the static block
|
170
|
+
* separately from enclosing contexts, because static blocks have their own `this` and it
|
171
|
+
* shouldn't count as used `this` in enclosing contexts.
|
172
|
+
*/
|
173
|
+
StaticBlock: pushContext,
|
174
|
+
"StaticBlock:exit": popContext,
|
166
175
|
|
167
176
|
ThisExpression: markThisUsed,
|
168
177
|
Super: markThisUsed,
|
package/lib/rules/complexity.js
CHANGED
@@ -124,20 +124,28 @@ module.exports = {
|
|
124
124
|
|
125
125
|
/*
|
126
126
|
* This rule only evaluates complexity of functions, so "program" is excluded.
|
127
|
-
* Class field initializers are implicit functions. Therefore,
|
128
|
-
* to the enclosing function's complexity, but their
|
127
|
+
* Class field initializers and class static blocks are implicit functions. Therefore,
|
128
|
+
* they shouldn't contribute to the enclosing function's complexity, but their
|
129
|
+
* own complexity should be evaluated.
|
129
130
|
*/
|
130
131
|
if (
|
131
132
|
codePath.origin !== "function" &&
|
132
|
-
codePath.origin !== "class-field-initializer"
|
133
|
+
codePath.origin !== "class-field-initializer" &&
|
134
|
+
codePath.origin !== "class-static-block"
|
133
135
|
) {
|
134
136
|
return;
|
135
137
|
}
|
136
138
|
|
137
139
|
if (complexity > THRESHOLD) {
|
138
|
-
|
139
|
-
|
140
|
-
|
140
|
+
let name;
|
141
|
+
|
142
|
+
if (codePath.origin === "class-field-initializer") {
|
143
|
+
name = "class field initializer";
|
144
|
+
} else if (codePath.origin === "class-static-block") {
|
145
|
+
name = "class static block";
|
146
|
+
} else {
|
147
|
+
name = astUtils.getFunctionNameWithKind(node);
|
148
|
+
}
|
141
149
|
|
142
150
|
context.report({
|
143
151
|
node,
|
package/lib/rules/indent.js
CHANGED
@@ -68,6 +68,7 @@ const KNOWN_NODES = new Set([
|
|
68
68
|
"ReturnStatement",
|
69
69
|
"SequenceExpression",
|
70
70
|
"SpreadElement",
|
71
|
+
"StaticBlock",
|
71
72
|
"Super",
|
72
73
|
"SwitchCase",
|
73
74
|
"SwitchStatement",
|
@@ -583,6 +584,16 @@ module.exports = {
|
|
583
584
|
},
|
584
585
|
additionalProperties: false
|
585
586
|
},
|
587
|
+
StaticBlock: {
|
588
|
+
type: "object",
|
589
|
+
properties: {
|
590
|
+
body: {
|
591
|
+
type: "integer",
|
592
|
+
minimum: 0
|
593
|
+
}
|
594
|
+
},
|
595
|
+
additionalProperties: false
|
596
|
+
},
|
586
597
|
CallExpression: {
|
587
598
|
type: "object",
|
588
599
|
properties: {
|
@@ -646,6 +657,9 @@ module.exports = {
|
|
646
657
|
parameters: DEFAULT_PARAMETER_INDENT,
|
647
658
|
body: DEFAULT_FUNCTION_BODY_INDENT
|
648
659
|
},
|
660
|
+
StaticBlock: {
|
661
|
+
body: DEFAULT_FUNCTION_BODY_INDENT
|
662
|
+
},
|
649
663
|
CallExpression: {
|
650
664
|
arguments: DEFAULT_PARAMETER_INDENT
|
651
665
|
},
|
@@ -1397,6 +1411,13 @@ module.exports = {
|
|
1397
1411
|
}
|
1398
1412
|
},
|
1399
1413
|
|
1414
|
+
StaticBlock(node) {
|
1415
|
+
const openingCurly = sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token
|
1416
|
+
const closingCurly = sourceCode.getLastToken(node);
|
1417
|
+
|
1418
|
+
addElementListIndent(node.body, openingCurly, closingCurly, options.StaticBlock.body);
|
1419
|
+
},
|
1420
|
+
|
1400
1421
|
SwitchStatement(node) {
|
1401
1422
|
const openingCurly = sourceCode.getTokenAfter(node.discriminant, astUtils.isOpeningBraceToken);
|
1402
1423
|
const closingCurly = sourceCode.getLastToken(node);
|
package/lib/rules/index.js
CHANGED
@@ -221,6 +221,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
|
|
221
221
|
"no-unsafe-optional-chaining": () => require("./no-unsafe-optional-chaining"),
|
222
222
|
"no-unused-expressions": () => require("./no-unused-expressions"),
|
223
223
|
"no-unused-labels": () => require("./no-unused-labels"),
|
224
|
+
"no-unused-private-class-members": () => require("./no-unused-private-class-members"),
|
224
225
|
"no-unused-vars": () => require("./no-unused-vars"),
|
225
226
|
"no-use-before-define": () => require("./no-use-before-define"),
|
226
227
|
"no-useless-backreference": () => require("./no-useless-backreference"),
|
package/lib/rules/key-spacing.js
CHANGED
@@ -427,19 +427,7 @@ module.exports = {
|
|
427
427
|
* @returns {void}
|
428
428
|
*/
|
429
429
|
function report(property, side, whitespace, expected, mode) {
|
430
|
-
const diff = whitespace.length - expected
|
431
|
-
nextColon = getNextColon(property.key),
|
432
|
-
tokenBeforeColon = sourceCode.getTokenBefore(nextColon, { includeComments: true }),
|
433
|
-
tokenAfterColon = sourceCode.getTokenAfter(nextColon, { includeComments: true }),
|
434
|
-
isKeySide = side === "key",
|
435
|
-
isExtra = diff > 0,
|
436
|
-
diffAbs = Math.abs(diff),
|
437
|
-
spaces = Array(diffAbs + 1).join(" ");
|
438
|
-
|
439
|
-
const locStart = isKeySide ? tokenBeforeColon.loc.end : nextColon.loc.start;
|
440
|
-
const locEnd = isKeySide ? nextColon.loc.start : tokenAfterColon.loc.start;
|
441
|
-
const missingLoc = isKeySide ? tokenBeforeColon.loc : tokenAfterColon.loc;
|
442
|
-
const loc = isExtra ? { start: locStart, end: locEnd } : missingLoc;
|
430
|
+
const diff = whitespace.length - expected;
|
443
431
|
|
444
432
|
if ((
|
445
433
|
diff && mode === "strict" ||
|
@@ -447,6 +435,19 @@ module.exports = {
|
|
447
435
|
diff > 0 && !expected && mode === "minimum") &&
|
448
436
|
!(expected && containsLineTerminator(whitespace))
|
449
437
|
) {
|
438
|
+
const nextColon = getNextColon(property.key),
|
439
|
+
tokenBeforeColon = sourceCode.getTokenBefore(nextColon, { includeComments: true }),
|
440
|
+
tokenAfterColon = sourceCode.getTokenAfter(nextColon, { includeComments: true }),
|
441
|
+
isKeySide = side === "key",
|
442
|
+
isExtra = diff > 0,
|
443
|
+
diffAbs = Math.abs(diff),
|
444
|
+
spaces = Array(diffAbs + 1).join(" ");
|
445
|
+
|
446
|
+
const locStart = isKeySide ? tokenBeforeColon.loc.end : nextColon.loc.start;
|
447
|
+
const locEnd = isKeySide ? nextColon.loc.start : tokenAfterColon.loc.start;
|
448
|
+
const missingLoc = isKeySide ? tokenBeforeColon.loc : tokenAfterColon.loc;
|
449
|
+
const loc = isExtra ? { start: locStart, end: locEnd } : missingLoc;
|
450
|
+
|
450
451
|
let fix;
|
451
452
|
|
452
453
|
if (isExtra) {
|
@@ -109,6 +109,8 @@ module.exports = {
|
|
109
109
|
create(context) {
|
110
110
|
const sourceCode = context.getSourceCode();
|
111
111
|
|
112
|
+
const tokensToIgnore = new WeakSet();
|
113
|
+
|
112
114
|
/**
|
113
115
|
* Reports a given token if there are not space(s) before the token.
|
114
116
|
* @param {Token} token A token to report.
|
@@ -121,6 +123,7 @@ module.exports = {
|
|
121
123
|
if (prevToken &&
|
122
124
|
(CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) &&
|
123
125
|
!isOpenParenOfTemplate(prevToken) &&
|
126
|
+
!tokensToIgnore.has(prevToken) &&
|
124
127
|
astUtils.isTokenOnSameLine(prevToken, token) &&
|
125
128
|
!sourceCode.isSpaceBetweenTokens(prevToken, token)
|
126
129
|
) {
|
@@ -147,6 +150,7 @@ module.exports = {
|
|
147
150
|
if (prevToken &&
|
148
151
|
(CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) &&
|
149
152
|
!isOpenParenOfTemplate(prevToken) &&
|
153
|
+
!tokensToIgnore.has(prevToken) &&
|
150
154
|
astUtils.isTokenOnSameLine(prevToken, token) &&
|
151
155
|
sourceCode.isSpaceBetweenTokens(prevToken, token)
|
152
156
|
) {
|
@@ -173,6 +177,7 @@ module.exports = {
|
|
173
177
|
if (nextToken &&
|
174
178
|
(CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) &&
|
175
179
|
!isCloseParenOfTemplate(nextToken) &&
|
180
|
+
!tokensToIgnore.has(nextToken) &&
|
176
181
|
astUtils.isTokenOnSameLine(token, nextToken) &&
|
177
182
|
!sourceCode.isSpaceBetweenTokens(token, nextToken)
|
178
183
|
) {
|
@@ -199,6 +204,7 @@ module.exports = {
|
|
199
204
|
if (nextToken &&
|
200
205
|
(CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) &&
|
201
206
|
!isCloseParenOfTemplate(nextToken) &&
|
207
|
+
!tokensToIgnore.has(nextToken) &&
|
202
208
|
astUtils.isTokenOnSameLine(token, nextToken) &&
|
203
209
|
sourceCode.isSpaceBetweenTokens(token, nextToken)
|
204
210
|
) {
|
@@ -584,7 +590,15 @@ module.exports = {
|
|
584
590
|
ImportNamespaceSpecifier: checkSpacingForImportNamespaceSpecifier,
|
585
591
|
MethodDefinition: checkSpacingForProperty,
|
586
592
|
PropertyDefinition: checkSpacingForProperty,
|
587
|
-
|
593
|
+
StaticBlock: checkSpacingAroundFirstToken,
|
594
|
+
Property: checkSpacingForProperty,
|
595
|
+
|
596
|
+
// To avoid conflicts with `space-infix-ops`, e.g. `a > this.b`
|
597
|
+
"BinaryExpression[operator='>']"(node) {
|
598
|
+
const operatorToken = sourceCode.getTokenBefore(node.right, astUtils.isNotOpeningParenToken);
|
599
|
+
|
600
|
+
tokensToIgnore.add(operatorToken);
|
601
|
+
}
|
588
602
|
};
|
589
603
|
}
|
590
604
|
};
|
@@ -185,10 +185,39 @@ module.exports = {
|
|
185
185
|
/**
|
186
186
|
* Returns the parent node that contains the given token.
|
187
187
|
* @param {token} token The token to check.
|
188
|
-
* @returns {ASTNode} The parent node that contains the given token.
|
188
|
+
* @returns {ASTNode|null} The parent node that contains the given token.
|
189
189
|
*/
|
190
190
|
function getParentNodeOfToken(token) {
|
191
|
-
|
191
|
+
const node = sourceCode.getNodeByRangeIndex(token.range[0]);
|
192
|
+
|
193
|
+
/*
|
194
|
+
* For the purpose of this rule, the comment token is in a `StaticBlock` node only
|
195
|
+
* if it's inside the braces of that `StaticBlock` node.
|
196
|
+
*
|
197
|
+
* Example where this function returns `null`:
|
198
|
+
*
|
199
|
+
* static
|
200
|
+
* // comment
|
201
|
+
* {
|
202
|
+
* }
|
203
|
+
*
|
204
|
+
* Example where this function returns `StaticBlock` node:
|
205
|
+
*
|
206
|
+
* static
|
207
|
+
* {
|
208
|
+
* // comment
|
209
|
+
* }
|
210
|
+
*
|
211
|
+
*/
|
212
|
+
if (node && node.type === "StaticBlock") {
|
213
|
+
const openingBrace = sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token
|
214
|
+
|
215
|
+
return token.range[0] >= openingBrace.range[0]
|
216
|
+
? node
|
217
|
+
: null;
|
218
|
+
}
|
219
|
+
|
220
|
+
return node;
|
192
221
|
}
|
193
222
|
|
194
223
|
/**
|
@@ -200,8 +229,15 @@ module.exports = {
|
|
200
229
|
function isCommentAtParentStart(token, nodeType) {
|
201
230
|
const parent = getParentNodeOfToken(token);
|
202
231
|
|
203
|
-
|
204
|
-
|
232
|
+
if (parent && isParentNodeType(parent, nodeType)) {
|
233
|
+
const parentStartNodeOrToken = parent.type === "StaticBlock"
|
234
|
+
? sourceCode.getFirstToken(parent, { skip: 1 }) // opening brace of the static block
|
235
|
+
: parent;
|
236
|
+
|
237
|
+
return token.loc.start.line - parentStartNodeOrToken.loc.start.line === 1;
|
238
|
+
}
|
239
|
+
|
240
|
+
return false;
|
205
241
|
}
|
206
242
|
|
207
243
|
/**
|
@@ -213,7 +249,7 @@ module.exports = {
|
|
213
249
|
function isCommentAtParentEnd(token, nodeType) {
|
214
250
|
const parent = getParentNodeOfToken(token);
|
215
251
|
|
216
|
-
return parent && isParentNodeType(parent, nodeType) &&
|
252
|
+
return !!parent && isParentNodeType(parent, nodeType) &&
|
217
253
|
parent.loc.end.line - token.loc.end.line === 1;
|
218
254
|
}
|
219
255
|
|
@@ -223,7 +259,12 @@ module.exports = {
|
|
223
259
|
* @returns {boolean} True if the comment is at block start.
|
224
260
|
*/
|
225
261
|
function isCommentAtBlockStart(token) {
|
226
|
-
return
|
262
|
+
return (
|
263
|
+
isCommentAtParentStart(token, "ClassBody") ||
|
264
|
+
isCommentAtParentStart(token, "BlockStatement") ||
|
265
|
+
isCommentAtParentStart(token, "StaticBlock") ||
|
266
|
+
isCommentAtParentStart(token, "SwitchCase")
|
267
|
+
);
|
227
268
|
}
|
228
269
|
|
229
270
|
/**
|
@@ -232,7 +273,13 @@ module.exports = {
|
|
232
273
|
* @returns {boolean} True if the comment is at block end.
|
233
274
|
*/
|
234
275
|
function isCommentAtBlockEnd(token) {
|
235
|
-
return
|
276
|
+
return (
|
277
|
+
isCommentAtParentEnd(token, "ClassBody") ||
|
278
|
+
isCommentAtParentEnd(token, "BlockStatement") ||
|
279
|
+
isCommentAtParentEnd(token, "StaticBlock") ||
|
280
|
+
isCommentAtParentEnd(token, "SwitchCase") ||
|
281
|
+
isCommentAtParentEnd(token, "SwitchStatement")
|
282
|
+
);
|
236
283
|
}
|
237
284
|
|
238
285
|
/**
|
package/lib/rules/max-depth.js
CHANGED
@@ -118,6 +118,7 @@ module.exports = {
|
|
118
118
|
FunctionDeclaration: startFunction,
|
119
119
|
FunctionExpression: startFunction,
|
120
120
|
ArrowFunctionExpression: startFunction,
|
121
|
+
StaticBlock: startFunction,
|
121
122
|
|
122
123
|
IfStatement(node) {
|
123
124
|
if (node.parent.type !== "IfStatement") {
|
@@ -146,6 +147,7 @@ module.exports = {
|
|
146
147
|
"FunctionDeclaration:exit": endFunction,
|
147
148
|
"FunctionExpression:exit": endFunction,
|
148
149
|
"ArrowFunctionExpression:exit": endFunction,
|
150
|
+
"StaticBlock:exit": endFunction,
|
149
151
|
"Program:exit": endFunction
|
150
152
|
};
|
151
153
|
|