eslint-linter-browserify 10.2.0 → 10.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/linter.cjs +307 -43
- package/linter.js +307 -43
- package/linter.min.js +3 -3
- package/linter.mjs +307 -43
- package/package.json +5 -5
package/linter.cjs
CHANGED
|
@@ -4216,7 +4216,7 @@ function requireEslintVisitorKeys$2 () {
|
|
|
4216
4216
|
return eslintVisitorKeys$2;
|
|
4217
4217
|
}
|
|
4218
4218
|
|
|
4219
|
-
var version = "10.
|
|
4219
|
+
var version = "10.3.0";
|
|
4220
4220
|
var require$$3$1 = {
|
|
4221
4221
|
version: version};
|
|
4222
4222
|
|
|
@@ -11523,11 +11523,10 @@ function requireCodePathState () {
|
|
|
11523
11523
|
this.position = "try";
|
|
11524
11524
|
|
|
11525
11525
|
/**
|
|
11526
|
-
* If the `try` statement has a `finally` block, this affects how
|
|
11527
|
-
*
|
|
11528
|
-
*
|
|
11529
|
-
* `
|
|
11530
|
-
* to track it.
|
|
11526
|
+
* If the `try` statement has a `finally` block, this affects how return-like
|
|
11527
|
+
* leaving paths behave in the `try` block. Without `finally`, they behave as
|
|
11528
|
+
* usual and don't require a fork; with `finally`, they fork into the
|
|
11529
|
+
* `finally` block, so we need a fork context to track them.
|
|
11531
11530
|
* @type {ForkContext|null}
|
|
11532
11531
|
*/
|
|
11533
11532
|
this.returnedForkContext = hasFinalizer
|
|
@@ -12709,6 +12708,23 @@ function requireCodePathState () {
|
|
|
12709
12708
|
this.forkContext.add(segments);
|
|
12710
12709
|
}
|
|
12711
12710
|
|
|
12711
|
+
/**
|
|
12712
|
+
* Records abrupt resumption paths from a suspended `yield` expression,
|
|
12713
|
+
* then splits normal post-`yield` continuation into a fresh segment.
|
|
12714
|
+
* @returns {void}
|
|
12715
|
+
*/
|
|
12716
|
+
makeYield() {
|
|
12717
|
+
const forkContext = this.forkContext;
|
|
12718
|
+
const leavingSegments = forkContext.head;
|
|
12719
|
+
|
|
12720
|
+
if (forkContext.reachable) {
|
|
12721
|
+
getReturnContext(this).returnedForkContext.add(leavingSegments);
|
|
12722
|
+
getThrowContext(this).thrownForkContext.add(leavingSegments);
|
|
12723
|
+
|
|
12724
|
+
forkContext.replaceHead(forkContext.makeNext(-1, -1));
|
|
12725
|
+
}
|
|
12726
|
+
}
|
|
12727
|
+
|
|
12712
12728
|
/**
|
|
12713
12729
|
* Makes a code path segment from the first throwable node to the `catch`
|
|
12714
12730
|
* block or the `finally` block.
|
|
@@ -13364,10 +13380,9 @@ function requireIdGenerator () {
|
|
|
13364
13380
|
next() {
|
|
13365
13381
|
this.n = (1 + this.n) | 0;
|
|
13366
13382
|
|
|
13367
|
-
/* c8 ignore start */
|
|
13368
13383
|
if (this.n < 0) {
|
|
13369
13384
|
this.n = 1;
|
|
13370
|
-
}
|
|
13385
|
+
}
|
|
13371
13386
|
|
|
13372
13387
|
return this.prefix + this.n;
|
|
13373
13388
|
}
|
|
@@ -13484,9 +13499,10 @@ function requireCodePath () {
|
|
|
13484
13499
|
* Final code path segments that represent normal completion of the code path.
|
|
13485
13500
|
* For functions, this means both explicit `return` statements and implicit returns,
|
|
13486
13501
|
* such as the last reachable segment in a function that does not have an
|
|
13487
|
-
* explicit `return` as this implicitly returns `undefined
|
|
13488
|
-
*
|
|
13489
|
-
*
|
|
13502
|
+
* explicit `return` as this implicitly returns `undefined`, as well as
|
|
13503
|
+
* return-like exits from suspended `yield` expressions. For scripts, modules,
|
|
13504
|
+
* class field initializers, and class static blocks, this means all lines of
|
|
13505
|
+
* code have been executed.
|
|
13490
13506
|
* These segments are also present in `finalSegments`.
|
|
13491
13507
|
* This is a passthrough to the underlying `CodePathState`.
|
|
13492
13508
|
* @type {CodePathSegment[]}
|
|
@@ -13496,7 +13512,8 @@ function requireCodePath () {
|
|
|
13496
13512
|
}
|
|
13497
13513
|
|
|
13498
13514
|
/**
|
|
13499
|
-
* Final code path segments that represent `throw` statements
|
|
13515
|
+
* Final code path segments that represent `throw` statements and throw-like
|
|
13516
|
+
* exits from suspended `yield` expressions.
|
|
13500
13517
|
* This is a passthrough to the underlying `CodePathState`.
|
|
13501
13518
|
* These segments are also present in `finalSegments`.
|
|
13502
13519
|
* @type {CodePathSegment[]}
|
|
@@ -13755,7 +13772,7 @@ function requireCodePathAnalyzer () {
|
|
|
13755
13772
|
|
|
13756
13773
|
/**
|
|
13757
13774
|
* Checks if a given node appears as the value of a PropertyDefinition node.
|
|
13758
|
-
* @param {ASTNode} node
|
|
13775
|
+
* @param {ASTNode} node The node to check.
|
|
13759
13776
|
* @returns {boolean} `true` if the node is a PropertyDefinition value,
|
|
13760
13777
|
* false if not.
|
|
13761
13778
|
*/
|
|
@@ -13801,8 +13818,8 @@ function requireCodePathAnalyzer () {
|
|
|
13801
13818
|
}
|
|
13802
13819
|
|
|
13803
13820
|
/**
|
|
13804
|
-
* Checks whether
|
|
13805
|
-
*
|
|
13821
|
+
* Checks whether a given logical expression node takes different paths for the
|
|
13822
|
+
* `true` and `false` cases.
|
|
13806
13823
|
* @param {ASTNode} node A node to check.
|
|
13807
13824
|
* @returns {boolean} `true` if the node is a test of a choice statement.
|
|
13808
13825
|
*/
|
|
@@ -13831,8 +13848,8 @@ function requireCodePathAnalyzer () {
|
|
|
13831
13848
|
/**
|
|
13832
13849
|
* Gets the boolean value of a given literal node.
|
|
13833
13850
|
*
|
|
13834
|
-
* This is used to detect
|
|
13835
|
-
* Statements preceded by an
|
|
13851
|
+
* This is used to detect infinite loops (e.g. `while (true) {}`).
|
|
13852
|
+
* Statements preceded by an infinite loop are unreachable if the loop didn't
|
|
13836
13853
|
* have any `break` statement.
|
|
13837
13854
|
* @param {ASTNode} node A node to get.
|
|
13838
13855
|
* @returns {boolean|undefined} a boolean value if the node is a Literal node,
|
|
@@ -13945,8 +13962,8 @@ function requireCodePathAnalyzer () {
|
|
|
13945
13962
|
}
|
|
13946
13963
|
|
|
13947
13964
|
/**
|
|
13948
|
-
* Updates the current segment with empty.
|
|
13949
|
-
* This is called
|
|
13965
|
+
* Updates the current segment with an empty array.
|
|
13966
|
+
* This is called when a code path ends.
|
|
13950
13967
|
* @param {CodePathAnalyzer} analyzer The instance.
|
|
13951
13968
|
* @param {ASTNode} node The current AST node.
|
|
13952
13969
|
* @returns {void}
|
|
@@ -14225,7 +14242,7 @@ function requireCodePathAnalyzer () {
|
|
|
14225
14242
|
|
|
14226
14243
|
case "SwitchCase":
|
|
14227
14244
|
/*
|
|
14228
|
-
* Fork if this node is after the
|
|
14245
|
+
* Fork if this node is after the 1st node in `cases`.
|
|
14229
14246
|
* It's similar to `else` blocks.
|
|
14230
14247
|
* The next `test` node is processed in this path.
|
|
14231
14248
|
*/
|
|
@@ -14344,10 +14361,13 @@ function requireCodePathAnalyzer () {
|
|
|
14344
14361
|
case "ImportExpression":
|
|
14345
14362
|
case "MemberExpression":
|
|
14346
14363
|
case "NewExpression":
|
|
14347
|
-
case "YieldExpression":
|
|
14348
14364
|
state.makeFirstThrowablePathInTryBlock();
|
|
14349
14365
|
break;
|
|
14350
14366
|
|
|
14367
|
+
case "YieldExpression":
|
|
14368
|
+
state.makeYield();
|
|
14369
|
+
break;
|
|
14370
|
+
|
|
14351
14371
|
case "WhileStatement":
|
|
14352
14372
|
case "DoWhileStatement":
|
|
14353
14373
|
case "ForStatement":
|
|
@@ -14436,7 +14456,7 @@ function requireCodePathAnalyzer () {
|
|
|
14436
14456
|
* a = () => {}
|
|
14437
14457
|
* }
|
|
14438
14458
|
*
|
|
14439
|
-
* In this case,
|
|
14459
|
+
* In this case, the ArrowFunctionExpression code path is closed first,
|
|
14440
14460
|
* and then we need to close the code path for the PropertyDefinition
|
|
14441
14461
|
* value.
|
|
14442
14462
|
*/
|
|
@@ -19283,15 +19303,16 @@ function requireFlatConfigSchema () {
|
|
|
19283
19303
|
}
|
|
19284
19304
|
|
|
19285
19305
|
/**
|
|
19286
|
-
* Validates that a given string
|
|
19306
|
+
* Validates that a given string matches the "pluginName/memberPlaceholder" pattern.
|
|
19287
19307
|
* @param {string} value The string to check.
|
|
19308
|
+
* @param {string} memberPlaceholder The placeholder for the member portion of the expected format in the error message.
|
|
19288
19309
|
* @returns {void}
|
|
19289
|
-
* @throws {TypeError} If the string
|
|
19310
|
+
* @throws {TypeError} If the string doesn't match the expected pattern.
|
|
19290
19311
|
*/
|
|
19291
|
-
function assertIsPluginMemberName(value) {
|
|
19312
|
+
function assertIsPluginMemberName(value, memberPlaceholder) {
|
|
19292
19313
|
if (!/[\w\-@$]+(?:\/[\w\-$]+)+$/iu.test(value)) {
|
|
19293
19314
|
throw new TypeError(
|
|
19294
|
-
`Expected string in the form "pluginName
|
|
19315
|
+
`Expected string in the form "pluginName/${memberPlaceholder}" but found "${value}".`,
|
|
19295
19316
|
);
|
|
19296
19317
|
}
|
|
19297
19318
|
}
|
|
@@ -19434,7 +19455,9 @@ function requireFlatConfigSchema () {
|
|
|
19434
19455
|
/** @type {ObjectPropertySchema} */
|
|
19435
19456
|
const languageSchema = {
|
|
19436
19457
|
merge: "replace",
|
|
19437
|
-
validate
|
|
19458
|
+
validate(value) {
|
|
19459
|
+
assertIsPluginMemberName(value, "languageName");
|
|
19460
|
+
},
|
|
19438
19461
|
};
|
|
19439
19462
|
|
|
19440
19463
|
/** @type {ObjectPropertySchema} */
|
|
@@ -19489,7 +19512,7 @@ function requireFlatConfigSchema () {
|
|
|
19489
19512
|
merge: "replace",
|
|
19490
19513
|
validate(value) {
|
|
19491
19514
|
if (typeof value === "string") {
|
|
19492
|
-
assertIsPluginMemberName(value);
|
|
19515
|
+
assertIsPluginMemberName(value, "processorName");
|
|
19493
19516
|
} else if (value && typeof value === "object") {
|
|
19494
19517
|
if (
|
|
19495
19518
|
typeof value.preprocess !== "function" ||
|
|
@@ -47402,12 +47425,31 @@ function requireAstUtils () {
|
|
|
47402
47425
|
}
|
|
47403
47426
|
|
|
47404
47427
|
/**
|
|
47405
|
-
*
|
|
47406
|
-
*
|
|
47407
|
-
*
|
|
47428
|
+
* Checks whether a token can cause continuation of a preceding expression
|
|
47429
|
+
* (for example, of a class field initializer expression) in a class body.
|
|
47430
|
+
* This function checks specifically for tokens that can appear at the start
|
|
47431
|
+
* of a class member: `[` (computed key), `*` (generator method), `in` or `instanceof` (valid keys)
|
|
47432
|
+
* Without a preceding semicolon, these tokens would be parsed as index access or operators.
|
|
47433
|
+
* @param {Token} token The token to check.
|
|
47434
|
+
* @returns {boolean} Whether the token can cause continuation of a preceding expression.
|
|
47435
|
+
*/
|
|
47436
|
+
function canContinueExpressionInClassBody(token) {
|
|
47437
|
+
return (
|
|
47438
|
+
(token.type === "Punctuator" &&
|
|
47439
|
+
(token.value === "[" || token.value === "*")) ||
|
|
47440
|
+
// Different parsers may return these tokens as either "Identifier" or "Keyword"
|
|
47441
|
+
((token.type === "Identifier" || token.type === "Keyword") &&
|
|
47442
|
+
(token.value === "in" || token.value === "instanceof"))
|
|
47443
|
+
);
|
|
47444
|
+
}
|
|
47445
|
+
|
|
47446
|
+
/**
|
|
47447
|
+
* Determines whether an opening parenthesis `(`, bracket `[`, asterisk `*`, or backtick ``` ` ``` needs to be preceded by a semicolon.
|
|
47448
|
+
* This opening parenthesis or bracket should be at the start of an `ExpressionStatement`, a `MethodDefinition`, a `PropertyDefinition`,
|
|
47449
|
+
* or at the start of the body of an `ArrowFunctionExpression`.
|
|
47408
47450
|
* @type {(sourceCode: SourceCode, node: ASTNode) => boolean}
|
|
47409
47451
|
* @param {SourceCode} sourceCode The source code object.
|
|
47410
|
-
* @param {ASTNode} node A node at the position where an opening parenthesis or
|
|
47452
|
+
* @param {ASTNode} node A node at the position where an opening parenthesis, bracket, or asterisk will be inserted.
|
|
47411
47453
|
* @returns {boolean} Whether a semicolon is required before the opening parenthesis or bracket.
|
|
47412
47454
|
*/
|
|
47413
47455
|
let needsPrecedingSemicolon;
|
|
@@ -47498,6 +47540,18 @@ function requireAstUtils () {
|
|
|
47498
47540
|
|
|
47499
47541
|
const prevNode = sourceCode.getNodeByRangeIndex(prevToken.range[0]);
|
|
47500
47542
|
|
|
47543
|
+
// Uninitialized class fields don't need a semicolon
|
|
47544
|
+
if (
|
|
47545
|
+
// Key
|
|
47546
|
+
(prevNode.parent.type === "PropertyDefinition" &&
|
|
47547
|
+
prevNode.parent.key === prevNode) ||
|
|
47548
|
+
// Closing bracket of a computed key
|
|
47549
|
+
(prevNode.type === "PropertyDefinition" &&
|
|
47550
|
+
isClosingBracketToken(prevToken))
|
|
47551
|
+
) {
|
|
47552
|
+
return false;
|
|
47553
|
+
}
|
|
47554
|
+
|
|
47501
47555
|
if (
|
|
47502
47556
|
prevNode.type === "TSDeclareFunction" ||
|
|
47503
47557
|
prevNode.parent.type === "TSImportEqualsDeclaration" ||
|
|
@@ -48986,6 +49040,7 @@ function requireAstUtils () {
|
|
|
48986
49040
|
isTopLevelExpressionStatement,
|
|
48987
49041
|
isDirective,
|
|
48988
49042
|
isStartOfExpressionStatement,
|
|
49043
|
+
canContinueExpressionInClassBody,
|
|
48989
49044
|
needsPrecedingSemicolon,
|
|
48990
49045
|
isImportAttributeKey,
|
|
48991
49046
|
getOpeningParenOfParams,
|
|
@@ -73973,12 +74028,18 @@ function requireNoAsyncPromiseExecutor () {
|
|
|
73973
74028
|
},
|
|
73974
74029
|
|
|
73975
74030
|
create(context) {
|
|
74031
|
+
const sourceCode = context.sourceCode;
|
|
74032
|
+
|
|
73976
74033
|
return {
|
|
73977
74034
|
"NewExpression[callee.name='Promise'][arguments.0.async=true]"(
|
|
73978
74035
|
node,
|
|
73979
74036
|
) {
|
|
74037
|
+
if (!sourceCode.isGlobalReference(node.callee)) {
|
|
74038
|
+
return;
|
|
74039
|
+
}
|
|
74040
|
+
|
|
73980
74041
|
context.report({
|
|
73981
|
-
node:
|
|
74042
|
+
node: sourceCode.getFirstToken(
|
|
73982
74043
|
node.arguments[0],
|
|
73983
74044
|
token => token.value === "async",
|
|
73984
74045
|
),
|
|
@@ -98974,7 +99035,7 @@ function requireNoShadow () {
|
|
|
98974
99035
|
|
|
98975
99036
|
/**
|
|
98976
99037
|
* Checks the current context for shadowed variables.
|
|
98977
|
-
* @param {Scope} scope
|
|
99038
|
+
* @param {Scope} scope The scope to check for shadowed variables.
|
|
98978
99039
|
* @returns {void}
|
|
98979
99040
|
*/
|
|
98980
99041
|
function checkForShadows(scope) {
|
|
@@ -103320,6 +103381,12 @@ function requireNoUnusedPrivateClassMembers () {
|
|
|
103320
103381
|
if (hasRequiredNoUnusedPrivateClassMembers) return noUnusedPrivateClassMembers;
|
|
103321
103382
|
hasRequiredNoUnusedPrivateClassMembers = 1;
|
|
103322
103383
|
|
|
103384
|
+
//------------------------------------------------------------------------------
|
|
103385
|
+
// Requirements
|
|
103386
|
+
//------------------------------------------------------------------------------
|
|
103387
|
+
|
|
103388
|
+
const astUtils = requireAstUtils();
|
|
103389
|
+
|
|
103323
103390
|
//------------------------------------------------------------------------------
|
|
103324
103391
|
// Rule Definition
|
|
103325
103392
|
//------------------------------------------------------------------------------
|
|
@@ -103328,6 +103395,7 @@ function requireNoUnusedPrivateClassMembers () {
|
|
|
103328
103395
|
noUnusedPrivateClassMembers = {
|
|
103329
103396
|
meta: {
|
|
103330
103397
|
type: "problem",
|
|
103398
|
+
hasSuggestions: true,
|
|
103331
103399
|
|
|
103332
103400
|
docs: {
|
|
103333
103401
|
description: "Disallow unused private class members",
|
|
@@ -103340,12 +103408,168 @@ function requireNoUnusedPrivateClassMembers () {
|
|
|
103340
103408
|
messages: {
|
|
103341
103409
|
unusedPrivateClassMember:
|
|
103342
103410
|
"'{{classMemberName}}' is defined but never used.",
|
|
103411
|
+
removeUnusedPrivateClassMember:
|
|
103412
|
+
"Remove unused private class member '{{classMemberName}}'.",
|
|
103343
103413
|
},
|
|
103344
103414
|
},
|
|
103345
103415
|
|
|
103346
103416
|
create(context) {
|
|
103417
|
+
const sourceCode = context.sourceCode;
|
|
103347
103418
|
const trackedClasses = [];
|
|
103348
103419
|
|
|
103420
|
+
/**
|
|
103421
|
+
* Gets the start index of the line that contains a given token or node.
|
|
103422
|
+
* @param {ASTNode|Token|Comment} nodeOrToken The token or node to check
|
|
103423
|
+
* @returns {number} The line start index
|
|
103424
|
+
*/
|
|
103425
|
+
function getLineStartIndex(nodeOrToken) {
|
|
103426
|
+
return nodeOrToken.range[0] - nodeOrToken.loc.start.column;
|
|
103427
|
+
}
|
|
103428
|
+
|
|
103429
|
+
/**
|
|
103430
|
+
* Checks whether a token or node starts on its own line, preceded only by whitespace.
|
|
103431
|
+
* @param {ASTNode|Token|Comment} nodeOrToken The token or node to check
|
|
103432
|
+
* @returns {boolean} Whether the token or node starts on its own line
|
|
103433
|
+
*/
|
|
103434
|
+
function startsOnOwnLine(nodeOrToken) {
|
|
103435
|
+
return (
|
|
103436
|
+
sourceCode.getTokenBefore(nodeOrToken, {
|
|
103437
|
+
includeComments: true,
|
|
103438
|
+
}).loc.end.line !== nodeOrToken.loc.start.line
|
|
103439
|
+
);
|
|
103440
|
+
}
|
|
103441
|
+
|
|
103442
|
+
/**
|
|
103443
|
+
* Gets leading comments that are directly attached to a class member.
|
|
103444
|
+
* @param {ASTNode} classMemberNode The class member node
|
|
103445
|
+
* @returns {Comment[]} Leading comments to remove with the member
|
|
103446
|
+
*/
|
|
103447
|
+
function getLeadingComments(classMemberNode) {
|
|
103448
|
+
const commentsBefore =
|
|
103449
|
+
sourceCode.getCommentsBefore(classMemberNode);
|
|
103450
|
+
const lastNonLeadingCommentIndex = commentsBefore.findLastIndex(
|
|
103451
|
+
(comment, index, self) => {
|
|
103452
|
+
const next =
|
|
103453
|
+
index < self.length - 1
|
|
103454
|
+
? self[index + 1]
|
|
103455
|
+
: classMemberNode;
|
|
103456
|
+
|
|
103457
|
+
return (
|
|
103458
|
+
!startsOnOwnLine(comment) ||
|
|
103459
|
+
next.loc.start.line - comment.loc.end.line > 1
|
|
103460
|
+
);
|
|
103461
|
+
},
|
|
103462
|
+
);
|
|
103463
|
+
|
|
103464
|
+
return commentsBefore.slice(lastNonLeadingCommentIndex + 1);
|
|
103465
|
+
}
|
|
103466
|
+
|
|
103467
|
+
/**
|
|
103468
|
+
* Checks whether a class member shares its line with another token.
|
|
103469
|
+
* @param {ASTNode} classMemberNode The class member node
|
|
103470
|
+
* @returns {boolean} Whether the member shares its line with another token
|
|
103471
|
+
*/
|
|
103472
|
+
function sharesLineWithAnotherToken(classMemberNode) {
|
|
103473
|
+
const previousToken = sourceCode.getTokenBefore(classMemberNode);
|
|
103474
|
+
const nextToken = sourceCode.getTokenAfter(classMemberNode);
|
|
103475
|
+
|
|
103476
|
+
return (
|
|
103477
|
+
previousToken.loc.end.line === classMemberNode.loc.start.line ||
|
|
103478
|
+
nextToken.loc.start.line === classMemberNode.loc.end.line
|
|
103479
|
+
);
|
|
103480
|
+
}
|
|
103481
|
+
|
|
103482
|
+
/**
|
|
103483
|
+
* Gets trailing comments that are directly attached to a class member.
|
|
103484
|
+
* Same-line trailing comments are preserved when another token shares
|
|
103485
|
+
* the line, because the comment might describe the remaining code rather
|
|
103486
|
+
* than the unused member alone.
|
|
103487
|
+
* @param {ASTNode} classMemberNode The class member node
|
|
103488
|
+
* @returns {Comment[]} Trailing comments to remove with the member
|
|
103489
|
+
*/
|
|
103490
|
+
function getTrailingComments(classMemberNode) {
|
|
103491
|
+
if (sharesLineWithAnotherToken(classMemberNode)) {
|
|
103492
|
+
return [];
|
|
103493
|
+
}
|
|
103494
|
+
|
|
103495
|
+
return sourceCode
|
|
103496
|
+
.getCommentsAfter(classMemberNode)
|
|
103497
|
+
.filter(
|
|
103498
|
+
comment =>
|
|
103499
|
+
comment.loc.start.line === classMemberNode.loc.end.line,
|
|
103500
|
+
);
|
|
103501
|
+
}
|
|
103502
|
+
|
|
103503
|
+
/**
|
|
103504
|
+
* Gets the token after which a semicolon should be inserted when removing a class member.
|
|
103505
|
+
* @param {ASTNode} classMemberNode The member that would be removed
|
|
103506
|
+
* @returns {Token|null} The token after which a semicolon should be inserted, or null if no semicolon is needed
|
|
103507
|
+
*/
|
|
103508
|
+
function getSemicolonInsertionToken(classMemberNode) {
|
|
103509
|
+
const nextToken = sourceCode.getTokenAfter(classMemberNode);
|
|
103510
|
+
|
|
103511
|
+
if (
|
|
103512
|
+
astUtils.canContinueExpressionInClassBody(nextToken) &&
|
|
103513
|
+
astUtils.needsPrecedingSemicolon(sourceCode, classMemberNode)
|
|
103514
|
+
) {
|
|
103515
|
+
return sourceCode.getTokenBefore(classMemberNode);
|
|
103516
|
+
}
|
|
103517
|
+
|
|
103518
|
+
return null;
|
|
103519
|
+
}
|
|
103520
|
+
|
|
103521
|
+
/**
|
|
103522
|
+
* Gets the replacement range for removing an unused class member.
|
|
103523
|
+
* @param {ASTNode} classMemberNode The member that would be removed
|
|
103524
|
+
* @returns {number[]} The text range to remove
|
|
103525
|
+
*/
|
|
103526
|
+
function getMemberRemovalRange(classMemberNode) {
|
|
103527
|
+
const leadingComments = getLeadingComments(classMemberNode);
|
|
103528
|
+
const trailingComments = getTrailingComments(classMemberNode);
|
|
103529
|
+
const shouldRemoveLeadingComments =
|
|
103530
|
+
leadingComments.length > 0 &&
|
|
103531
|
+
!sharesLineWithAnotherToken(classMemberNode);
|
|
103532
|
+
const lastItemToRemove =
|
|
103533
|
+
trailingComments.length > 0
|
|
103534
|
+
? trailingComments.at(-1)
|
|
103535
|
+
: classMemberNode;
|
|
103536
|
+
|
|
103537
|
+
const previousToken = sourceCode.getTokenBefore(classMemberNode);
|
|
103538
|
+
const nextToken = sourceCode.getTokenAfter(lastItemToRemove, {
|
|
103539
|
+
includeComments: true,
|
|
103540
|
+
});
|
|
103541
|
+
const nextTokenStartsOnNewLine =
|
|
103542
|
+
nextToken.loc.start.line > lastItemToRemove.loc.end.line;
|
|
103543
|
+
const shouldRemoveOwnLine =
|
|
103544
|
+
!shouldRemoveLeadingComments &&
|
|
103545
|
+
startsOnOwnLine(classMemberNode) &&
|
|
103546
|
+
nextTokenStartsOnNewLine;
|
|
103547
|
+
let start = classMemberNode.range[0];
|
|
103548
|
+
let end = lastItemToRemove.range[1];
|
|
103549
|
+
|
|
103550
|
+
if (shouldRemoveLeadingComments) {
|
|
103551
|
+
start = nextTokenStartsOnNewLine
|
|
103552
|
+
? getLineStartIndex(leadingComments[0])
|
|
103553
|
+
: leadingComments[0].range[0];
|
|
103554
|
+
end = nextTokenStartsOnNewLine
|
|
103555
|
+
? getLineStartIndex(nextToken)
|
|
103556
|
+
: nextToken.range[0];
|
|
103557
|
+
} else if (shouldRemoveOwnLine) {
|
|
103558
|
+
start = getLineStartIndex(classMemberNode);
|
|
103559
|
+
end = getLineStartIndex(nextToken);
|
|
103560
|
+
} else if (
|
|
103561
|
+
previousToken.loc.end.line === classMemberNode.loc.start.line
|
|
103562
|
+
) {
|
|
103563
|
+
start = previousToken.range[1];
|
|
103564
|
+
} else if (
|
|
103565
|
+
nextToken.loc.start.line === lastItemToRemove.loc.end.line
|
|
103566
|
+
) {
|
|
103567
|
+
end = nextToken.range[0];
|
|
103568
|
+
}
|
|
103569
|
+
|
|
103570
|
+
return [start, end];
|
|
103571
|
+
}
|
|
103572
|
+
|
|
103349
103573
|
/**
|
|
103350
103574
|
* Check whether the current node is in a write only assignment.
|
|
103351
103575
|
* @param {ASTNode} privateIdentifierNode Node referring to a private identifier
|
|
@@ -103401,6 +103625,7 @@ function requireNoUnusedPrivateClassMembers () {
|
|
|
103401
103625
|
if (bodyMember.key.type === "PrivateIdentifier") {
|
|
103402
103626
|
privateMembers.set(bodyMember.key.name, {
|
|
103403
103627
|
declaredNode: bodyMember,
|
|
103628
|
+
hasReference: false,
|
|
103404
103629
|
isAccessor:
|
|
103405
103630
|
bodyMember.type === "MethodDefinition" &&
|
|
103406
103631
|
(bodyMember.kind === "set" ||
|
|
@@ -103443,6 +103668,8 @@ function requireNoUnusedPrivateClassMembers () {
|
|
|
103443
103668
|
return;
|
|
103444
103669
|
}
|
|
103445
103670
|
|
|
103671
|
+
memberDefinition.hasReference = true;
|
|
103672
|
+
|
|
103446
103673
|
/*
|
|
103447
103674
|
* Any usage of an accessor is considered a read, as the getter/setter can have
|
|
103448
103675
|
* side-effects in its definition.
|
|
@@ -103514,11 +103741,12 @@ function requireNoUnusedPrivateClassMembers () {
|
|
|
103514
103741
|
|
|
103515
103742
|
for (const [
|
|
103516
103743
|
classMemberName,
|
|
103517
|
-
{ declaredNode, isUsed },
|
|
103744
|
+
{ declaredNode, hasReference, isUsed },
|
|
103518
103745
|
] of unusedPrivateMembers.entries()) {
|
|
103519
103746
|
if (isUsed) {
|
|
103520
103747
|
continue;
|
|
103521
103748
|
}
|
|
103749
|
+
|
|
103522
103750
|
context.report({
|
|
103523
103751
|
node: declaredNode,
|
|
103524
103752
|
loc: declaredNode.key.loc,
|
|
@@ -103526,6 +103754,39 @@ function requireNoUnusedPrivateClassMembers () {
|
|
|
103526
103754
|
data: {
|
|
103527
103755
|
classMemberName: `#${classMemberName}`,
|
|
103528
103756
|
},
|
|
103757
|
+
suggest: [
|
|
103758
|
+
{
|
|
103759
|
+
messageId: "removeUnusedPrivateClassMember",
|
|
103760
|
+
data: {
|
|
103761
|
+
classMemberName: `#${classMemberName}`,
|
|
103762
|
+
},
|
|
103763
|
+
*fix(fixer) {
|
|
103764
|
+
if (hasReference) {
|
|
103765
|
+
return;
|
|
103766
|
+
}
|
|
103767
|
+
|
|
103768
|
+
const removalRange =
|
|
103769
|
+
getMemberRemovalRange(declaredNode);
|
|
103770
|
+
const semicolonInsertionToken =
|
|
103771
|
+
getSemicolonInsertionToken(
|
|
103772
|
+
declaredNode,
|
|
103773
|
+
);
|
|
103774
|
+
const removalFix = fixer.replaceTextRange(
|
|
103775
|
+
removalRange,
|
|
103776
|
+
"",
|
|
103777
|
+
);
|
|
103778
|
+
|
|
103779
|
+
yield removalFix;
|
|
103780
|
+
|
|
103781
|
+
if (semicolonInsertionToken) {
|
|
103782
|
+
yield fixer.insertTextAfter(
|
|
103783
|
+
semicolonInsertionToken,
|
|
103784
|
+
";",
|
|
103785
|
+
);
|
|
103786
|
+
}
|
|
103787
|
+
},
|
|
103788
|
+
},
|
|
103789
|
+
],
|
|
103529
103790
|
});
|
|
103530
103791
|
}
|
|
103531
103792
|
},
|
|
@@ -107109,7 +107370,7 @@ function requireNoUselessConcat () {
|
|
|
107109
107370
|
}
|
|
107110
107371
|
|
|
107111
107372
|
/**
|
|
107112
|
-
*
|
|
107373
|
+
* Gets the right most node on the left side of a BinaryExpression with + operator.
|
|
107113
107374
|
* @param {ASTNode} node A BinaryExpression node to check.
|
|
107114
107375
|
* @returns {ASTNode} node
|
|
107115
107376
|
*/
|
|
@@ -107123,7 +107384,7 @@ function requireNoUselessConcat () {
|
|
|
107123
107384
|
}
|
|
107124
107385
|
|
|
107125
107386
|
/**
|
|
107126
|
-
*
|
|
107387
|
+
* Gets the left most node on the right side of a BinaryExpression with + operator.
|
|
107127
107388
|
* @param {ASTNode} node A BinaryExpression node to check.
|
|
107128
107389
|
* @returns {ASTNode} node
|
|
107129
107390
|
*/
|
|
@@ -107443,8 +107704,9 @@ function requireNoUselessConstructor () {
|
|
|
107443
107704
|
const nextToken =
|
|
107444
107705
|
sourceCode.getTokenAfter(node);
|
|
107445
107706
|
const addSemiColon =
|
|
107446
|
-
|
|
107447
|
-
|
|
107707
|
+
astUtils.canContinueExpressionInClassBody(
|
|
107708
|
+
nextToken,
|
|
107709
|
+
) &&
|
|
107448
107710
|
astUtils.needsPrecedingSemicolon(
|
|
107449
107711
|
sourceCode,
|
|
107450
107712
|
node,
|
|
@@ -119661,12 +119923,14 @@ function requireRequireAwait () {
|
|
|
119661
119923
|
*/
|
|
119662
119924
|
const nextToken = sourceCode.getTokenAfter(asyncToken);
|
|
119663
119925
|
const addSemiColon =
|
|
119664
|
-
nextToken
|
|
119665
|
-
(nextToken.value === "[" || nextToken.value === "(") &&
|
|
119666
|
-
(nodeWithAsyncKeyword.type === "MethodDefinition" ||
|
|
119926
|
+
((astUtils.isOpeningParenToken(nextToken) &&
|
|
119667
119927
|
astUtils.isStartOfExpressionStatement(
|
|
119668
119928
|
nodeWithAsyncKeyword,
|
|
119669
|
-
))
|
|
119929
|
+
)) ||
|
|
119930
|
+
(nodeWithAsyncKeyword.type === "MethodDefinition" &&
|
|
119931
|
+
astUtils.canContinueExpressionInClassBody(
|
|
119932
|
+
nextToken,
|
|
119933
|
+
))) &&
|
|
119670
119934
|
astUtils.needsPrecedingSemicolon(
|
|
119671
119935
|
sourceCode,
|
|
119672
119936
|
nodeWithAsyncKeyword,
|