oxlint-plugin-eslint 1.61.0 → 1.62.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/common/ast-utils.cjs +434 -0
- package/common/eslint-utils.cjs +40 -0
- package/package.json +1 -1
- package/rules/constructor-super.cjs +38 -0
- package/rules/no-extra-semi.cjs +15 -0
- package/rules/no-this-before-super.cjs +47 -0
- package/rules/no-useless-assignment.cjs +13 -0
- package/rules/padding-line-between-statements.cjs +20 -0
package/common/ast-utils.cjs
CHANGED
|
@@ -4199,6 +4199,14 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
4199
4199
|
}
|
|
4200
4200
|
TokenTranslator.prototype = {
|
|
4201
4201
|
constructor: TokenTranslator,
|
|
4202
|
+
/**
|
|
4203
|
+
* Translates a single Esprima token to a single Acorn token. This may be
|
|
4204
|
+
* inaccurate due to how templates are handled differently in Esprima and
|
|
4205
|
+
* Acorn, but should be accurate for all other tokens.
|
|
4206
|
+
* @param {AcornToken} token The Acorn token to translate.
|
|
4207
|
+
* @param {Object} extra Espree extra object.
|
|
4208
|
+
* @returns {EsprimaToken} The Esprima version of the token.
|
|
4209
|
+
*/
|
|
4202
4210
|
translate(token, extra) {
|
|
4203
4211
|
let type = token.type, tt = this._acornTokTypes;
|
|
4204
4212
|
if (type === tt.name) token.type = Token.Identifier, token.value === "static" && (token.type = Token.Keyword), extra.ecmaVersion > 5 && (token.value === "yield" || token.value === "let") && (token.type = Token.Keyword);
|
|
@@ -4219,6 +4227,12 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
4219
4227
|
}
|
|
4220
4228
|
return token;
|
|
4221
4229
|
},
|
|
4230
|
+
/**
|
|
4231
|
+
* Function to call during Acorn's onToken handler.
|
|
4232
|
+
* @param {AcornToken} token The Acorn token.
|
|
4233
|
+
* @param {Object} extra The Espree extra object.
|
|
4234
|
+
* @returns {void}
|
|
4235
|
+
*/
|
|
4222
4236
|
onToken(token, extra) {
|
|
4223
4237
|
let tt = this._acornTokTypes, tokens = extra.tokens, templateTokens = this._tokens, translateTemplateTokens = () => {
|
|
4224
4238
|
tokens.push(convertTemplatePart(this._tokens, this._code)), this._tokens = [];
|
|
@@ -5392,6 +5406,13 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
5392
5406
|
SHEBANG_MATCHER: shebangPattern,
|
|
5393
5407
|
STATEMENT_LIST_PARENTS,
|
|
5394
5408
|
ECMASCRIPT_GLOBALS,
|
|
5409
|
+
/**
|
|
5410
|
+
* Determines whether two adjacent tokens are on the same line.
|
|
5411
|
+
* @param {Object} left The left token object.
|
|
5412
|
+
* @param {Object} right The right token object.
|
|
5413
|
+
* @returns {boolean} Whether or not the tokens are on the same line.
|
|
5414
|
+
* @public
|
|
5415
|
+
*/
|
|
5395
5416
|
isTokenOnSameLine(left, right) {
|
|
5396
5417
|
return left.loc.end.line === right.loc.start.line;
|
|
5397
5418
|
},
|
|
@@ -5432,23 +5453,75 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
5432
5453
|
isOpeningParenToken,
|
|
5433
5454
|
isSemicolonToken,
|
|
5434
5455
|
isEqToken,
|
|
5456
|
+
/**
|
|
5457
|
+
* Checks whether or not a given node is a string literal.
|
|
5458
|
+
* @param {ASTNode} node A node to check.
|
|
5459
|
+
* @returns {boolean} `true` if the node is a string literal.
|
|
5460
|
+
*/
|
|
5435
5461
|
isStringLiteral(node) {
|
|
5436
5462
|
return node.type === "Literal" && typeof node.value == "string" || node.type === "TemplateLiteral";
|
|
5437
5463
|
},
|
|
5464
|
+
/**
|
|
5465
|
+
* Checks whether a given node is a breakable statement or not.
|
|
5466
|
+
* The node is breakable if the node is one of the following type:
|
|
5467
|
+
*
|
|
5468
|
+
* - DoWhileStatement
|
|
5469
|
+
* - ForInStatement
|
|
5470
|
+
* - ForOfStatement
|
|
5471
|
+
* - ForStatement
|
|
5472
|
+
* - SwitchStatement
|
|
5473
|
+
* - WhileStatement
|
|
5474
|
+
* @param {ASTNode} node A node to check.
|
|
5475
|
+
* @returns {boolean} `true` if the node is breakable.
|
|
5476
|
+
*/
|
|
5438
5477
|
isBreakableStatement(node) {
|
|
5439
5478
|
return breakableTypePattern.test(node.type);
|
|
5440
5479
|
},
|
|
5480
|
+
/**
|
|
5481
|
+
* Gets references which are non initializer and writable.
|
|
5482
|
+
* @param {Reference[]} references An array of references.
|
|
5483
|
+
* @returns {Reference[]} An array of only references which are non initializer and writable.
|
|
5484
|
+
* @public
|
|
5485
|
+
*/
|
|
5441
5486
|
getModifyingReferences(references) {
|
|
5442
5487
|
return references.filter(isModifyingReference);
|
|
5443
5488
|
},
|
|
5489
|
+
/**
|
|
5490
|
+
* Validate that a string passed in is surrounded by the specified character
|
|
5491
|
+
* @param {string} val The text to check.
|
|
5492
|
+
* @param {string} character The character to see if it's surrounded by.
|
|
5493
|
+
* @returns {boolean} True if the text is surrounded by the character, false if not.
|
|
5494
|
+
* @private
|
|
5495
|
+
*/
|
|
5444
5496
|
isSurroundedBy(val, character) {
|
|
5445
5497
|
return val[0] === character && val.at(-1) === character;
|
|
5446
5498
|
},
|
|
5499
|
+
/**
|
|
5500
|
+
* Returns whether the provided node is an ESLint directive comment or not
|
|
5501
|
+
* @param {Line|Block} node The comment token to be checked
|
|
5502
|
+
* @returns {boolean} `true` if the node is an ESLint directive comment
|
|
5503
|
+
*/
|
|
5447
5504
|
isDirectiveComment(node) {
|
|
5448
5505
|
let comment = node.value.trim();
|
|
5449
5506
|
return node.type === "Line" && comment.startsWith("eslint-") || node.type === "Block" && ESLINT_DIRECTIVE_PATTERN.test(comment);
|
|
5450
5507
|
},
|
|
5508
|
+
/**
|
|
5509
|
+
* Gets the trailing statement of a given node.
|
|
5510
|
+
*
|
|
5511
|
+
* if (code)
|
|
5512
|
+
* consequent;
|
|
5513
|
+
*
|
|
5514
|
+
* When taking this `IfStatement`, returns `consequent;` statement.
|
|
5515
|
+
* @param {ASTNode} A node to get.
|
|
5516
|
+
* @returns {ASTNode|null} The trailing statement's node.
|
|
5517
|
+
*/
|
|
5451
5518
|
getTrailingStatement: esutils.ast.trailingStatement,
|
|
5519
|
+
/**
|
|
5520
|
+
* Finds the variable by a given name in a given scope and its upper scopes.
|
|
5521
|
+
* @param {eslint-scope.Scope} initScope A scope to start find.
|
|
5522
|
+
* @param {string} name A variable name to find.
|
|
5523
|
+
* @returns {eslint-scope.Variable|null} A found variable or `null`.
|
|
5524
|
+
*/
|
|
5452
5525
|
getVariableByName(initScope, name) {
|
|
5453
5526
|
let scope = initScope;
|
|
5454
5527
|
for (; scope;) {
|
|
@@ -5458,6 +5531,34 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
5458
5531
|
}
|
|
5459
5532
|
return null;
|
|
5460
5533
|
},
|
|
5534
|
+
/**
|
|
5535
|
+
* Checks whether or not a given function node is the default `this` binding.
|
|
5536
|
+
*
|
|
5537
|
+
* First, this checks the node:
|
|
5538
|
+
*
|
|
5539
|
+
* - The given node is not in `PropertyDefinition#value` position.
|
|
5540
|
+
* - The given node is not `StaticBlock`.
|
|
5541
|
+
* - The function name does not start with uppercase. It's a convention to capitalize the names
|
|
5542
|
+
* of constructor functions. This check is not performed if `capIsConstructor` is set to `false`.
|
|
5543
|
+
* - The function does not have a JSDoc comment that has a @this tag.
|
|
5544
|
+
*
|
|
5545
|
+
* Next, this checks the location of the node.
|
|
5546
|
+
* If the location is below, this judges `this` is valid.
|
|
5547
|
+
*
|
|
5548
|
+
* - The location is not on an object literal.
|
|
5549
|
+
* - The location is not assigned to a variable which starts with an uppercase letter. Applies to anonymous
|
|
5550
|
+
* functions only, as the name of the variable is considered to be the name of the function in this case.
|
|
5551
|
+
* This check is not performed if `capIsConstructor` is set to `false`.
|
|
5552
|
+
* - The location is not on an ES2015 class.
|
|
5553
|
+
* - Its `bind`/`call`/`apply` method is not called directly.
|
|
5554
|
+
* - The function is not a callback of array methods (such as `.forEach()`) if `thisArg` is given.
|
|
5555
|
+
* @param {ASTNode} node A function node to check. It also can be an implicit function, like `StaticBlock`
|
|
5556
|
+
* or any expression that is `PropertyDefinition#value` node.
|
|
5557
|
+
* @param {SourceCode} sourceCode A SourceCode instance to get comments.
|
|
5558
|
+
* @param {boolean} [capIsConstructor = true] `false` disables the assumption that functions which name starts
|
|
5559
|
+
* with an uppercase or are assigned to a variable which name starts with an uppercase are constructors.
|
|
5560
|
+
* @returns {boolean} The function node is the default `this` binding.
|
|
5561
|
+
*/
|
|
5461
5562
|
isDefaultThisBinding(node, sourceCode, { capIsConstructor = !0 } = {}) {
|
|
5462
5563
|
if (node.parent.type === "PropertyDefinition" && node.parent.value === node || node.type === "StaticBlock" || (node.type === "FunctionDeclaration" || node.type === "FunctionExpression") && node.params.some((param) => param.type === "Identifier" && param.name === "this") || capIsConstructor && isES5Constructor(node) || hasJSDocThisTag(node, sourceCode)) return !1;
|
|
5463
5564
|
let isAnonymous = node.id === null, currentNode = node;
|
|
@@ -5498,6 +5599,12 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
5498
5599
|
/* c8 ignore next */
|
|
5499
5600
|
return !0;
|
|
5500
5601
|
},
|
|
5602
|
+
/**
|
|
5603
|
+
* Get the precedence level based on the node type
|
|
5604
|
+
* @param {ASTNode} node node to evaluate
|
|
5605
|
+
* @returns {number} precedence level
|
|
5606
|
+
* @private
|
|
5607
|
+
*/
|
|
5501
5608
|
getPrecedence(node) {
|
|
5502
5609
|
switch (node.type) {
|
|
5503
5610
|
case "SequenceExpression": return 0;
|
|
@@ -5544,12 +5651,27 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
5544
5651
|
default: return node.type in eslintVisitorKeys ? 20 : -1;
|
|
5545
5652
|
}
|
|
5546
5653
|
},
|
|
5654
|
+
/**
|
|
5655
|
+
* Checks whether the given node is an empty block node or not.
|
|
5656
|
+
* @param {ASTNode|null} node The node to check.
|
|
5657
|
+
* @returns {boolean} `true` if the node is an empty block.
|
|
5658
|
+
*/
|
|
5547
5659
|
isEmptyBlock(node) {
|
|
5548
5660
|
return !!(node && node.type === "BlockStatement" && node.body.length === 0);
|
|
5549
5661
|
},
|
|
5662
|
+
/**
|
|
5663
|
+
* Checks whether the given node is an empty function node or not.
|
|
5664
|
+
* @param {ASTNode|null} node The node to check.
|
|
5665
|
+
* @returns {boolean} `true` if the node is an empty function.
|
|
5666
|
+
*/
|
|
5550
5667
|
isEmptyFunction(node) {
|
|
5551
5668
|
return isFunction(node) && module.exports.isEmptyBlock(node.body);
|
|
5552
5669
|
},
|
|
5670
|
+
/**
|
|
5671
|
+
* Get directives from directive prologue of a Program or Function node.
|
|
5672
|
+
* @param {ASTNode} node The node to check.
|
|
5673
|
+
* @returns {ASTNode[]} The directives found in the directive prologue.
|
|
5674
|
+
*/
|
|
5553
5675
|
getDirectivePrologue(node) {
|
|
5554
5676
|
let directives = [];
|
|
5555
5677
|
if (node.type === "Program" || node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression" && node.body.type === "BlockStatement") {
|
|
@@ -5559,12 +5681,106 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
5559
5681
|
}
|
|
5560
5682
|
return directives;
|
|
5561
5683
|
},
|
|
5684
|
+
/**
|
|
5685
|
+
* Determines whether this node is a decimal integer literal. If a node is a decimal integer literal, a dot added
|
|
5686
|
+
* after the node will be parsed as a decimal point, rather than a property-access dot.
|
|
5687
|
+
* @param {ASTNode} node The node to check.
|
|
5688
|
+
* @returns {boolean} `true` if this node is a decimal integer.
|
|
5689
|
+
* @example
|
|
5690
|
+
*
|
|
5691
|
+
* 0 // true
|
|
5692
|
+
* 5 // true
|
|
5693
|
+
* 50 // true
|
|
5694
|
+
* 5_000 // true
|
|
5695
|
+
* 1_234_56 // true
|
|
5696
|
+
* 08 // true
|
|
5697
|
+
* 0192 // true
|
|
5698
|
+
* 5. // false
|
|
5699
|
+
* .5 // false
|
|
5700
|
+
* 5.0 // false
|
|
5701
|
+
* 5.00_00 // false
|
|
5702
|
+
* 05 // false
|
|
5703
|
+
* 0x5 // false
|
|
5704
|
+
* 0b101 // false
|
|
5705
|
+
* 0b11_01 // false
|
|
5706
|
+
* 0o5 // false
|
|
5707
|
+
* 5e0 // false
|
|
5708
|
+
* 5e1_000 // false
|
|
5709
|
+
* 5n // false
|
|
5710
|
+
* 1_000n // false
|
|
5711
|
+
* "5" // false
|
|
5712
|
+
*
|
|
5713
|
+
*/
|
|
5562
5714
|
isDecimalInteger(node) {
|
|
5563
5715
|
return node.type === "Literal" && typeof node.value == "number" && DECIMAL_INTEGER_PATTERN.test(node.raw);
|
|
5564
5716
|
},
|
|
5717
|
+
/**
|
|
5718
|
+
* Determines whether this token is a decimal integer numeric token.
|
|
5719
|
+
* This is similar to isDecimalInteger(), but for tokens.
|
|
5720
|
+
* @param {Token} token The token to check.
|
|
5721
|
+
* @returns {boolean} `true` if this token is a decimal integer.
|
|
5722
|
+
*/
|
|
5565
5723
|
isDecimalIntegerNumericToken(token) {
|
|
5566
5724
|
return token.type === "Numeric" && DECIMAL_INTEGER_PATTERN.test(token.value);
|
|
5567
5725
|
},
|
|
5726
|
+
/**
|
|
5727
|
+
* Gets the name and kind of the given function node.
|
|
5728
|
+
*
|
|
5729
|
+
* - `function foo() {}` .................... `function 'foo'`
|
|
5730
|
+
* - `(function foo() {})` .................. `function 'foo'`
|
|
5731
|
+
* - `(function() {})` ...................... `function`
|
|
5732
|
+
* - `function* foo() {}` ................... `generator function 'foo'`
|
|
5733
|
+
* - `(function* foo() {})` ................. `generator function 'foo'`
|
|
5734
|
+
* - `(function*() {})` ..................... `generator function`
|
|
5735
|
+
* - `() => {}` ............................. `arrow function`
|
|
5736
|
+
* - `async () => {}` ....................... `async arrow function`
|
|
5737
|
+
* - `({ foo: function foo() {} })` ......... `method 'foo'`
|
|
5738
|
+
* - `({ foo: function() {} })` ............. `method 'foo'`
|
|
5739
|
+
* - `({ ['foo']: function() {} })` ......... `method 'foo'`
|
|
5740
|
+
* - `({ [foo]: function() {} })` ........... `method`
|
|
5741
|
+
* - `({ foo() {} })` ....................... `method 'foo'`
|
|
5742
|
+
* - `({ foo: function* foo() {} })` ........ `generator method 'foo'`
|
|
5743
|
+
* - `({ foo: function*() {} })` ............ `generator method 'foo'`
|
|
5744
|
+
* - `({ ['foo']: function*() {} })` ........ `generator method 'foo'`
|
|
5745
|
+
* - `({ [foo]: function*() {} })` .......... `generator method`
|
|
5746
|
+
* - `({ *foo() {} })` ...................... `generator method 'foo'`
|
|
5747
|
+
* - `({ foo: async function foo() {} })` ... `async method 'foo'`
|
|
5748
|
+
* - `({ foo: async function() {} })` ....... `async method 'foo'`
|
|
5749
|
+
* - `({ ['foo']: async function() {} })` ... `async method 'foo'`
|
|
5750
|
+
* - `({ [foo]: async function() {} })` ..... `async method`
|
|
5751
|
+
* - `({ async foo() {} })` ................. `async method 'foo'`
|
|
5752
|
+
* - `({ get foo() {} })` ................... `getter 'foo'`
|
|
5753
|
+
* - `({ set foo(a) {} })` .................. `setter 'foo'`
|
|
5754
|
+
* - `class A { constructor() {} }` ......... `constructor`
|
|
5755
|
+
* - `class A { foo() {} }` ................. `method 'foo'`
|
|
5756
|
+
* - `class A { *foo() {} }` ................ `generator method 'foo'`
|
|
5757
|
+
* - `class A { async foo() {} }` ........... `async method 'foo'`
|
|
5758
|
+
* - `class A { ['foo']() {} }` ............. `method 'foo'`
|
|
5759
|
+
* - `class A { *['foo']() {} }` ............ `generator method 'foo'`
|
|
5760
|
+
* - `class A { async ['foo']() {} }` ....... `async method 'foo'`
|
|
5761
|
+
* - `class A { [foo]() {} }` ............... `method`
|
|
5762
|
+
* - `class A { *[foo]() {} }` .............. `generator method`
|
|
5763
|
+
* - `class A { async [foo]() {} }` ......... `async method`
|
|
5764
|
+
* - `class A { get foo() {} }` ............. `getter 'foo'`
|
|
5765
|
+
* - `class A { set foo(a) {} }` ............ `setter 'foo'`
|
|
5766
|
+
* - `class A { static foo() {} }` .......... `static method 'foo'`
|
|
5767
|
+
* - `class A { static *foo() {} }` ......... `static generator method 'foo'`
|
|
5768
|
+
* - `class A { static async foo() {} }` .... `static async method 'foo'`
|
|
5769
|
+
* - `class A { static get foo() {} }` ...... `static getter 'foo'`
|
|
5770
|
+
* - `class A { static set foo(a) {} }` ..... `static setter 'foo'`
|
|
5771
|
+
* - `class A { foo = () => {}; }` .......... `method 'foo'`
|
|
5772
|
+
* - `class A { foo = function() {}; }` ..... `method 'foo'`
|
|
5773
|
+
* - `class A { foo = function bar() {}; }` . `method 'foo'`
|
|
5774
|
+
* - `class A { static foo = () => {}; }` ... `static method 'foo'`
|
|
5775
|
+
* - `class A { '#foo' = () => {}; }` ....... `method '#foo'`
|
|
5776
|
+
* - `class A { #foo = () => {}; }` ......... `private method #foo`
|
|
5777
|
+
* - `class A { static #foo = () => {}; }` .. `static private method #foo`
|
|
5778
|
+
* - `class A { '#foo'() {} }` .............. `method '#foo'`
|
|
5779
|
+
* - `class A { #foo() {} }` ................ `private method #foo`
|
|
5780
|
+
* - `class A { static #foo() {} }` ......... `static private method #foo`
|
|
5781
|
+
* @param {ASTNode} node The function node to get.
|
|
5782
|
+
* @returns {string} The name and kind of the function node.
|
|
5783
|
+
*/
|
|
5568
5784
|
getFunctionNameWithKind(node) {
|
|
5569
5785
|
let parent = node.parent, tokens = [];
|
|
5570
5786
|
if ((parent.type === "MethodDefinition" || parent.type === "PropertyDefinition" || node.type === "TSPropertySignature" || node.type === "TSMethodSignature") && (parent.static && tokens.push("static"), !parent.computed && parent.key?.type === "PrivateIdentifier" && tokens.push("private")), node.async && tokens.push("async"), node.generator && tokens.push("generator"), parent.type === "Property" || parent.type === "MethodDefinition") {
|
|
@@ -5579,6 +5795,103 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
5579
5795
|
else node.type === "TSMethodSignature" ? tokens.push(`'${getStaticPropertyName(node)}'`) : node.id && tokens.push(`'${node.id.name}'`);
|
|
5580
5796
|
return tokens.join(" ");
|
|
5581
5797
|
},
|
|
5798
|
+
/**
|
|
5799
|
+
* Gets the location of the given function node for reporting.
|
|
5800
|
+
*
|
|
5801
|
+
* - `function foo() {}`
|
|
5802
|
+
* ^^^^^^^^^^^^
|
|
5803
|
+
* - `(function foo() {})`
|
|
5804
|
+
* ^^^^^^^^^^^^
|
|
5805
|
+
* - `(function() {})`
|
|
5806
|
+
* ^^^^^^^^
|
|
5807
|
+
* - `function* foo() {}`
|
|
5808
|
+
* ^^^^^^^^^^^^^
|
|
5809
|
+
* - `(function* foo() {})`
|
|
5810
|
+
* ^^^^^^^^^^^^^
|
|
5811
|
+
* - `(function*() {})`
|
|
5812
|
+
* ^^^^^^^^^
|
|
5813
|
+
* - `() => {}`
|
|
5814
|
+
* ^^
|
|
5815
|
+
* - `async () => {}`
|
|
5816
|
+
* ^^
|
|
5817
|
+
* - `({ foo: function foo() {} })`
|
|
5818
|
+
* ^^^^^^^^^^^^^^^^^
|
|
5819
|
+
* - `({ foo: function() {} })`
|
|
5820
|
+
* ^^^^^^^^^^^^^
|
|
5821
|
+
* - `({ ['foo']: function() {} })`
|
|
5822
|
+
* ^^^^^^^^^^^^^^^^^
|
|
5823
|
+
* - `({ [foo]: function() {} })`
|
|
5824
|
+
* ^^^^^^^^^^^^^^^
|
|
5825
|
+
* - `({ foo() {} })`
|
|
5826
|
+
* ^^^
|
|
5827
|
+
* - `({ foo: function* foo() {} })`
|
|
5828
|
+
* ^^^^^^^^^^^^^^^^^^
|
|
5829
|
+
* - `({ foo: function*() {} })`
|
|
5830
|
+
* ^^^^^^^^^^^^^^
|
|
5831
|
+
* - `({ ['foo']: function*() {} })`
|
|
5832
|
+
* ^^^^^^^^^^^^^^^^^^
|
|
5833
|
+
* - `({ [foo]: function*() {} })`
|
|
5834
|
+
* ^^^^^^^^^^^^^^^^
|
|
5835
|
+
* - `({ *foo() {} })`
|
|
5836
|
+
* ^^^^
|
|
5837
|
+
* - `({ foo: async function foo() {} })`
|
|
5838
|
+
* ^^^^^^^^^^^^^^^^^^^^^^^
|
|
5839
|
+
* - `({ foo: async function() {} })`
|
|
5840
|
+
* ^^^^^^^^^^^^^^^^^^^
|
|
5841
|
+
* - `({ ['foo']: async function() {} })`
|
|
5842
|
+
* ^^^^^^^^^^^^^^^^^^^^^^^
|
|
5843
|
+
* - `({ [foo]: async function() {} })`
|
|
5844
|
+
* ^^^^^^^^^^^^^^^^^^^^^
|
|
5845
|
+
* - `({ async foo() {} })`
|
|
5846
|
+
* ^^^^^^^^^
|
|
5847
|
+
* - `({ get foo() {} })`
|
|
5848
|
+
* ^^^^^^^
|
|
5849
|
+
* - `({ set foo(a) {} })`
|
|
5850
|
+
* ^^^^^^^
|
|
5851
|
+
* - `class A { constructor() {} }`
|
|
5852
|
+
* ^^^^^^^^^^^
|
|
5853
|
+
* - `class A { foo() {} }`
|
|
5854
|
+
* ^^^
|
|
5855
|
+
* - `class A { *foo() {} }`
|
|
5856
|
+
* ^^^^
|
|
5857
|
+
* - `class A { async foo() {} }`
|
|
5858
|
+
* ^^^^^^^^^
|
|
5859
|
+
* - `class A { ['foo']() {} }`
|
|
5860
|
+
* ^^^^^^^
|
|
5861
|
+
* - `class A { *['foo']() {} }`
|
|
5862
|
+
* ^^^^^^^^
|
|
5863
|
+
* - `class A { async ['foo']() {} }`
|
|
5864
|
+
* ^^^^^^^^^^^^^
|
|
5865
|
+
* - `class A { [foo]() {} }`
|
|
5866
|
+
* ^^^^^
|
|
5867
|
+
* - `class A { *[foo]() {} }`
|
|
5868
|
+
* ^^^^^^
|
|
5869
|
+
* - `class A { async [foo]() {} }`
|
|
5870
|
+
* ^^^^^^^^^^^
|
|
5871
|
+
* - `class A { get foo() {} }`
|
|
5872
|
+
* ^^^^^^^
|
|
5873
|
+
* - `class A { set foo(a) {} }`
|
|
5874
|
+
* ^^^^^^^
|
|
5875
|
+
* - `class A { static foo() {} }`
|
|
5876
|
+
* ^^^^^^^^^^
|
|
5877
|
+
* - `class A { static *foo() {} }`
|
|
5878
|
+
* ^^^^^^^^^^^
|
|
5879
|
+
* - `class A { static async foo() {} }`
|
|
5880
|
+
* ^^^^^^^^^^^^^^^^
|
|
5881
|
+
* - `class A { static get foo() {} }`
|
|
5882
|
+
* ^^^^^^^^^^^^^^
|
|
5883
|
+
* - `class A { static set foo(a) {} }`
|
|
5884
|
+
* ^^^^^^^^^^^^^^
|
|
5885
|
+
* - `class A { foo = function() {} }`
|
|
5886
|
+
* ^^^^^^^^^^^^^^
|
|
5887
|
+
* - `class A { static foo = function() {} }`
|
|
5888
|
+
* ^^^^^^^^^^^^^^^^^^^^^
|
|
5889
|
+
* - `class A { foo = (a, b) => {} }`
|
|
5890
|
+
* ^^^^^^
|
|
5891
|
+
* @param {ASTNode} node The function node to get.
|
|
5892
|
+
* @param {SourceCode} sourceCode The source code object to get tokens.
|
|
5893
|
+
* @returns {string} The location of the function node for reporting.
|
|
5894
|
+
*/
|
|
5582
5895
|
getFunctionHeadLoc(node, sourceCode) {
|
|
5583
5896
|
let parent = node.parent, start, end;
|
|
5584
5897
|
if (parent.type === "Property" || parent.type === "MethodDefinition" || parent.type === "PropertyDefinition" || parent.type === "TSPropertySignature" || parent.type === "TSMethodSignature") start = parent.loc.start, end = getOpeningParenOfParams(node, sourceCode).loc.start;
|
|
@@ -5591,6 +5904,50 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
5591
5904
|
end: Object.assign({}, end)
|
|
5592
5905
|
};
|
|
5593
5906
|
},
|
|
5907
|
+
/**
|
|
5908
|
+
* Gets next location when the result is not out of bound, otherwise returns null.
|
|
5909
|
+
*
|
|
5910
|
+
* Assumptions:
|
|
5911
|
+
*
|
|
5912
|
+
* - The given location represents a valid location in the given source code.
|
|
5913
|
+
* - Columns are 0-based.
|
|
5914
|
+
* - Lines are 1-based.
|
|
5915
|
+
* - Column immediately after the last character in a line (not incl. linebreaks) is considered to be a valid location.
|
|
5916
|
+
* - If the source code ends with a linebreak, `sourceCode.lines` array will have an extra element (empty string) at the end.
|
|
5917
|
+
* The start (column 0) of that extra line is considered to be a valid location.
|
|
5918
|
+
*
|
|
5919
|
+
* Examples of successive locations (line, column):
|
|
5920
|
+
*
|
|
5921
|
+
* code: foo
|
|
5922
|
+
* locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> null
|
|
5923
|
+
*
|
|
5924
|
+
* code: foo<LF>
|
|
5925
|
+
* locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> (2, 0) -> null
|
|
5926
|
+
*
|
|
5927
|
+
* code: foo<CR><LF>
|
|
5928
|
+
* locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> (2, 0) -> null
|
|
5929
|
+
*
|
|
5930
|
+
* code: a<LF>b
|
|
5931
|
+
* locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> null
|
|
5932
|
+
*
|
|
5933
|
+
* code: a<LF>b<LF>
|
|
5934
|
+
* locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> (3, 0) -> null
|
|
5935
|
+
*
|
|
5936
|
+
* code: a<CR><LF>b<CR><LF>
|
|
5937
|
+
* locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> (3, 0) -> null
|
|
5938
|
+
*
|
|
5939
|
+
* code: a<LF><LF>
|
|
5940
|
+
* locations: (1, 0) -> (1, 1) -> (2, 0) -> (3, 0) -> null
|
|
5941
|
+
*
|
|
5942
|
+
* code: <LF>
|
|
5943
|
+
* locations: (1, 0) -> (2, 0) -> null
|
|
5944
|
+
*
|
|
5945
|
+
* code:
|
|
5946
|
+
* locations: (1, 0) -> null
|
|
5947
|
+
* @param {SourceCode} sourceCode The sourceCode
|
|
5948
|
+
* @param {{line: number, column: number}} location The location
|
|
5949
|
+
* @returns {{line: number, column: number} | null} Next location
|
|
5950
|
+
*/
|
|
5594
5951
|
getNextLocation(sourceCode, { line, column }) {
|
|
5595
5952
|
return column < sourceCode.lines[line - 1].length ? {
|
|
5596
5953
|
line,
|
|
@@ -5600,11 +5957,23 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
5600
5957
|
column: 0
|
|
5601
5958
|
} : null;
|
|
5602
5959
|
},
|
|
5960
|
+
/**
|
|
5961
|
+
* Gets the parenthesized text of a node. This is similar to sourceCode.getText(node), but it also includes any parentheses
|
|
5962
|
+
* surrounding the node.
|
|
5963
|
+
* @param {SourceCode} sourceCode The source code object
|
|
5964
|
+
* @param {ASTNode} node An expression node
|
|
5965
|
+
* @returns {string} The text representing the node, with all surrounding parentheses included
|
|
5966
|
+
*/
|
|
5603
5967
|
getParenthesisedText(sourceCode, node) {
|
|
5604
5968
|
let leftToken = sourceCode.getFirstToken(node), rightToken = sourceCode.getLastToken(node);
|
|
5605
5969
|
for (; sourceCode.getTokenBefore(leftToken) && sourceCode.getTokenBefore(leftToken).type === "Punctuator" && sourceCode.getTokenBefore(leftToken).value === "(" && sourceCode.getTokenAfter(rightToken) && sourceCode.getTokenAfter(rightToken).type === "Punctuator" && sourceCode.getTokenAfter(rightToken).value === ")";) leftToken = sourceCode.getTokenBefore(leftToken), rightToken = sourceCode.getTokenAfter(rightToken);
|
|
5606
5970
|
return sourceCode.getText().slice(leftToken.range[0], rightToken.range[1]);
|
|
5607
5971
|
},
|
|
5972
|
+
/**
|
|
5973
|
+
* Determine if a node has a possibility to be an Error object
|
|
5974
|
+
* @param {ASTNode} node ASTNode to check
|
|
5975
|
+
* @returns {boolean} True if there is a chance it contains an Error obj
|
|
5976
|
+
*/
|
|
5608
5977
|
couldBeError(node) {
|
|
5609
5978
|
switch (node.type) {
|
|
5610
5979
|
case "Identifier":
|
|
@@ -5631,9 +6000,21 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
5631
6000
|
default: return !1;
|
|
5632
6001
|
}
|
|
5633
6002
|
},
|
|
6003
|
+
/**
|
|
6004
|
+
* Check if a given node is a numeric literal or not.
|
|
6005
|
+
* @param {ASTNode} node The node to check.
|
|
6006
|
+
* @returns {boolean} `true` if the node is a number or bigint literal.
|
|
6007
|
+
*/
|
|
5634
6008
|
isNumericLiteral(node) {
|
|
5635
6009
|
return node.type === "Literal" && (typeof node.value == "number" || !!node.bigint);
|
|
5636
6010
|
},
|
|
6011
|
+
/**
|
|
6012
|
+
* Determines whether two tokens can safely be placed next to each other without merging into a single token
|
|
6013
|
+
* @param {Token|string} leftValue The left token. If this is a string, it will be tokenized and the last token will be used.
|
|
6014
|
+
* @param {Token|string} rightValue The right token. If this is a string, it will be tokenized and the first token will be used.
|
|
6015
|
+
* @returns {boolean} If the tokens cannot be safely placed next to each other, returns `false`. If the tokens can be placed
|
|
6016
|
+
* next to each other, behavior is undefined (although it should return `true` in most cases).
|
|
6017
|
+
*/
|
|
5637
6018
|
canTokensBeAdjacent(leftValue, rightValue) {
|
|
5638
6019
|
let espreeOptions = {
|
|
5639
6020
|
ecmaVersion: espree.latestEcmaVersion,
|
|
@@ -5681,6 +6062,13 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
5681
6062
|
}
|
|
5682
6063
|
return !!(leftToken.type === "String" || rightToken.type === "String" || leftToken.type === "Template" || rightToken.type === "Template" || leftToken.type !== "Numeric" && rightToken.type === "Numeric" && rightToken.value.startsWith(".") || leftToken.type === "Block" || rightToken.type === "Block" || rightToken.type === "Line" || rightToken.type === "PrivateIdentifier");
|
|
5683
6064
|
},
|
|
6065
|
+
/**
|
|
6066
|
+
* Get the `loc` object of a given name in a `/*globals` directive comment.
|
|
6067
|
+
* @param {SourceCode} sourceCode The source code to convert index to loc.
|
|
6068
|
+
* @param {Comment} comment The `/*globals` directive comment which include the name.
|
|
6069
|
+
* @param {string} name The name to find.
|
|
6070
|
+
* @returns {SourceLocation} The `loc` object.
|
|
6071
|
+
*/
|
|
5684
6072
|
getNameLocationInGlobalDirectiveComment(sourceCode, comment, name) {
|
|
5685
6073
|
let namePattern = RegExp(`[\\s,]${escapeRegExp(name)}(?:$|[\\s,:])`, "gu");
|
|
5686
6074
|
namePattern.lastIndex = comment.value.indexOf("global") + 6;
|
|
@@ -5693,12 +6081,58 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
5693
6081
|
}
|
|
5694
6082
|
};
|
|
5695
6083
|
},
|
|
6084
|
+
/**
|
|
6085
|
+
* Determines whether the given raw string contains an octal escape sequence
|
|
6086
|
+
* or a non-octal decimal escape sequence ("\8", "\9").
|
|
6087
|
+
*
|
|
6088
|
+
* "\1", "\2" ... "\7", "\8", "\9"
|
|
6089
|
+
* "\00", "\01" ... "\07", "\08", "\09"
|
|
6090
|
+
*
|
|
6091
|
+
* "\0", when not followed by a digit, is not an octal escape sequence.
|
|
6092
|
+
* @param {string} rawString A string in its raw representation.
|
|
6093
|
+
* @returns {boolean} `true` if the string contains at least one octal escape sequence
|
|
6094
|
+
* or at least one non-octal decimal escape sequence.
|
|
6095
|
+
*/
|
|
5696
6096
|
hasOctalOrNonOctalDecimalEscapeSequence(rawString) {
|
|
5697
6097
|
return OCTAL_OR_NON_OCTAL_DECIMAL_ESCAPE_PATTERN.test(rawString);
|
|
5698
6098
|
},
|
|
6099
|
+
/**
|
|
6100
|
+
* Determines whether the given node is a template literal without expressions.
|
|
6101
|
+
* @param {ASTNode} node Node to check.
|
|
6102
|
+
* @returns {boolean} True if the node is a template literal without expressions.
|
|
6103
|
+
*/
|
|
5699
6104
|
isStaticTemplateLiteral(node) {
|
|
5700
6105
|
return node.type === "TemplateLiteral" && node.expressions.length === 0;
|
|
5701
6106
|
},
|
|
6107
|
+
/**
|
|
6108
|
+
* Determines whether the existing curly braces around the single statement are necessary to preserve the semantics of the code.
|
|
6109
|
+
* The braces, which make the given block body, are necessary in either of the following situations:
|
|
6110
|
+
*
|
|
6111
|
+
* 1. The statement is a lexical declaration.
|
|
6112
|
+
* 2. Without the braces, an `if` within the statement would become associated with an `else` after the closing brace:
|
|
6113
|
+
*
|
|
6114
|
+
* if (a) {
|
|
6115
|
+
* if (b)
|
|
6116
|
+
* foo();
|
|
6117
|
+
* }
|
|
6118
|
+
* else
|
|
6119
|
+
* bar();
|
|
6120
|
+
*
|
|
6121
|
+
* if (a)
|
|
6122
|
+
* while (b)
|
|
6123
|
+
* while (c) {
|
|
6124
|
+
* while (d)
|
|
6125
|
+
* if (e)
|
|
6126
|
+
* while(f)
|
|
6127
|
+
* foo();
|
|
6128
|
+
* }
|
|
6129
|
+
* else
|
|
6130
|
+
* bar();
|
|
6131
|
+
* @param {ASTNode} node `BlockStatement` body with exactly one statement directly inside. The statement can have its own nested statements.
|
|
6132
|
+
* @param {SourceCode} sourceCode The source code
|
|
6133
|
+
* @returns {boolean} `true` if the braces are necessary - removing them (replacing the given `BlockStatement` body with its single statement content)
|
|
6134
|
+
* would change the semantics of the code or produce a syntax error.
|
|
6135
|
+
*/
|
|
5702
6136
|
areBracesNecessary(node, sourceCode) {
|
|
5703
6137
|
/**
|
|
5704
6138
|
* Determines if the given node is a lexical declaration (let, const, using, await using, function, or class)
|
package/common/eslint-utils.cjs
CHANGED
|
@@ -989,10 +989,20 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
989
989
|
return typeof x == "object" && !!x && typeof x.type == "string";
|
|
990
990
|
}
|
|
991
991
|
let visitor = Object.freeze(Object.assign(Object.create(null), {
|
|
992
|
+
/**
|
|
993
|
+
* @param {Node} node
|
|
994
|
+
* @param {HasSideEffectOptions} options
|
|
995
|
+
* @param {Record<string, string[]>} visitorKeys
|
|
996
|
+
*/
|
|
992
997
|
$visit(node, options, visitorKeys) {
|
|
993
998
|
let { type } = node;
|
|
994
999
|
return typeof this[type] == "function" ? this[type](node, options, visitorKeys) : this.$visitChildren(node, options, visitorKeys);
|
|
995
1000
|
},
|
|
1001
|
+
/**
|
|
1002
|
+
* @param {Node} node
|
|
1003
|
+
* @param {HasSideEffectOptions} options
|
|
1004
|
+
* @param {Record<string, string[]>} visitorKeys
|
|
1005
|
+
*/
|
|
996
1006
|
$visitChildren(node, options, visitorKeys) {
|
|
997
1007
|
let { type } = node;
|
|
998
1008
|
for (let key of visitorKeys[type] || eslintVisitorKeys.getKeys(node)) {
|
|
@@ -1012,6 +1022,11 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
1012
1022
|
AwaitExpression() {
|
|
1013
1023
|
return !0;
|
|
1014
1024
|
},
|
|
1025
|
+
/**
|
|
1026
|
+
* @param {BinaryExpression} node
|
|
1027
|
+
* @param {HasSideEffectOptions} options
|
|
1028
|
+
* @param {Record<string, string[]>} visitorKeys
|
|
1029
|
+
*/
|
|
1015
1030
|
BinaryExpression(node, options, visitorKeys) {
|
|
1016
1031
|
return options.considerImplicitTypeConversion && typeConversionBinaryOps.has(node.operator) && (node.left.type !== "Literal" || node.right.type !== "Literal") ? !0 : this.$visitChildren(node, options, visitorKeys);
|
|
1017
1032
|
},
|
|
@@ -1024,21 +1039,46 @@ var require_eslint_visitor_keys = /* @__PURE__ */ require_chunk.t(((exports) =>
|
|
|
1024
1039
|
ImportExpression() {
|
|
1025
1040
|
return !0;
|
|
1026
1041
|
},
|
|
1042
|
+
/**
|
|
1043
|
+
* @param {MemberExpression} node
|
|
1044
|
+
* @param {HasSideEffectOptions} options
|
|
1045
|
+
* @param {Record<string, string[]>} visitorKeys
|
|
1046
|
+
*/
|
|
1027
1047
|
MemberExpression(node, options, visitorKeys) {
|
|
1028
1048
|
return options.considerGetters || options.considerImplicitTypeConversion && node.computed && node.property.type !== "Literal" ? !0 : this.$visitChildren(node, options, visitorKeys);
|
|
1029
1049
|
},
|
|
1050
|
+
/**
|
|
1051
|
+
* @param {MethodDefinition} node
|
|
1052
|
+
* @param {HasSideEffectOptions} options
|
|
1053
|
+
* @param {Record<string, string[]>} visitorKeys
|
|
1054
|
+
*/
|
|
1030
1055
|
MethodDefinition(node, options, visitorKeys) {
|
|
1031
1056
|
return options.considerImplicitTypeConversion && node.computed && node.key.type !== "Literal" ? !0 : this.$visitChildren(node, options, visitorKeys);
|
|
1032
1057
|
},
|
|
1033
1058
|
NewExpression() {
|
|
1034
1059
|
return !0;
|
|
1035
1060
|
},
|
|
1061
|
+
/**
|
|
1062
|
+
* @param {Property} node
|
|
1063
|
+
* @param {HasSideEffectOptions} options
|
|
1064
|
+
* @param {Record<string, string[]>} visitorKeys
|
|
1065
|
+
*/
|
|
1036
1066
|
Property(node, options, visitorKeys) {
|
|
1037
1067
|
return options.considerImplicitTypeConversion && node.computed && node.key.type !== "Literal" ? !0 : this.$visitChildren(node, options, visitorKeys);
|
|
1038
1068
|
},
|
|
1069
|
+
/**
|
|
1070
|
+
* @param {PropertyDefinition} node
|
|
1071
|
+
* @param {HasSideEffectOptions} options
|
|
1072
|
+
* @param {Record<string, string[]>} visitorKeys
|
|
1073
|
+
*/
|
|
1039
1074
|
PropertyDefinition(node, options, visitorKeys) {
|
|
1040
1075
|
return options.considerImplicitTypeConversion && node.computed && node.key.type !== "Literal" ? !0 : this.$visitChildren(node, options, visitorKeys);
|
|
1041
1076
|
},
|
|
1077
|
+
/**
|
|
1078
|
+
* @param {UnaryExpression} node
|
|
1079
|
+
* @param {HasSideEffectOptions} options
|
|
1080
|
+
* @param {Record<string, string[]>} visitorKeys
|
|
1081
|
+
*/
|
|
1042
1082
|
UnaryExpression(node, options, visitorKeys) {
|
|
1043
1083
|
return node.operator === "delete" || options.considerImplicitTypeConversion && typeConversionUnaryOps.has(node.operator) && node.argument.type !== "Literal" ? !0 : this.$visitChildren(node, options, visitorKeys);
|
|
1044
1084
|
},
|
package/package.json
CHANGED
|
@@ -110,6 +110,12 @@ var require_constructor_super = /* @__PURE__ */ require("../common/chunk.cjs").t
|
|
|
110
110
|
return segment.reachable && segInfoMap[segment.id].calledInEveryPaths;
|
|
111
111
|
}
|
|
112
112
|
return {
|
|
113
|
+
/**
|
|
114
|
+
* Stacks a constructor information.
|
|
115
|
+
* @param {CodePath} codePath A code path which was started.
|
|
116
|
+
* @param {ASTNode} node The current node.
|
|
117
|
+
* @returns {void}
|
|
118
|
+
*/
|
|
113
119
|
onCodePathStart(codePath, node) {
|
|
114
120
|
if (isConstructorFunction(node)) {
|
|
115
121
|
let superClass = node.parent.parent.parent.superClass;
|
|
@@ -130,6 +136,13 @@ var require_constructor_super = /* @__PURE__ */ require("../common/chunk.cjs").t
|
|
|
130
136
|
currentSegments: /* @__PURE__ */ new Set()
|
|
131
137
|
};
|
|
132
138
|
},
|
|
139
|
+
/**
|
|
140
|
+
* Pops a constructor information.
|
|
141
|
+
* And reports if `super()` lacked.
|
|
142
|
+
* @param {CodePath} codePath A code path which was ended.
|
|
143
|
+
* @param {ASTNode} node The current node.
|
|
144
|
+
* @returns {void}
|
|
145
|
+
*/
|
|
133
146
|
onCodePathEnd(codePath, node) {
|
|
134
147
|
let hasExtends = funcInfo.hasExtends;
|
|
135
148
|
if (funcInfo = funcInfo.upper, !hasExtends) return;
|
|
@@ -139,6 +152,12 @@ var require_constructor_super = /* @__PURE__ */ require("../common/chunk.cjs").t
|
|
|
139
152
|
node: node.parent
|
|
140
153
|
});
|
|
141
154
|
},
|
|
155
|
+
/**
|
|
156
|
+
* Initialize information of a given code path segment.
|
|
157
|
+
* @param {CodePathSegment} segment A code path segment to initialize.
|
|
158
|
+
* @param {CodePathSegment} node Node that starts the segment.
|
|
159
|
+
* @returns {void}
|
|
160
|
+
*/
|
|
142
161
|
onCodePathSegmentStart(segment, node) {
|
|
143
162
|
if (funcInfo.currentSegments.add(segment), !(funcInfo.isConstructor && funcInfo.hasExtends)) return;
|
|
144
163
|
let info = segInfoMap[segment.id] = new SegmentInfo(), seenPrevSegments = segment.prevSegments.filter(hasSegmentBeenSeen);
|
|
@@ -153,6 +172,15 @@ var require_constructor_super = /* @__PURE__ */ require("../common/chunk.cjs").t
|
|
|
153
172
|
onCodePathSegmentEnd(segment) {
|
|
154
173
|
funcInfo.currentSegments.delete(segment);
|
|
155
174
|
},
|
|
175
|
+
/**
|
|
176
|
+
* Update information of the code path segment when a code path was
|
|
177
|
+
* looped.
|
|
178
|
+
* @param {CodePathSegment} fromSegment The code path segment of the
|
|
179
|
+
* end of a loop.
|
|
180
|
+
* @param {CodePathSegment} toSegment A code path segment of the head
|
|
181
|
+
* of a loop.
|
|
182
|
+
* @returns {void}
|
|
183
|
+
*/
|
|
156
184
|
onCodePathSegmentLoop(fromSegment, toSegment) {
|
|
157
185
|
funcInfo.isConstructor && funcInfo.hasExtends && funcInfo.codePath.traverseSegments({
|
|
158
186
|
first: toSegment,
|
|
@@ -177,6 +205,11 @@ var require_constructor_super = /* @__PURE__ */ require("../common/chunk.cjs").t
|
|
|
177
205
|
}
|
|
178
206
|
});
|
|
179
207
|
},
|
|
208
|
+
/**
|
|
209
|
+
* Checks for a call of `super()`.
|
|
210
|
+
* @param {ASTNode} node A CallExpression node to check.
|
|
211
|
+
* @returns {void}
|
|
212
|
+
*/
|
|
180
213
|
"CallExpression:exit"(node) {
|
|
181
214
|
if (!(funcInfo.isConstructor && funcInfo.hasExtends) || node.callee.type !== "Super") return;
|
|
182
215
|
let segments = funcInfo.currentSegments, duplicate = !1, info = null;
|
|
@@ -189,6 +222,11 @@ var require_constructor_super = /* @__PURE__ */ require("../common/chunk.cjs").t
|
|
|
189
222
|
node
|
|
190
223
|
}));
|
|
191
224
|
},
|
|
225
|
+
/**
|
|
226
|
+
* Set the mark to the returned path as `super()` was called.
|
|
227
|
+
* @param {ASTNode} node A ReturnStatement node to check.
|
|
228
|
+
* @returns {void}
|
|
229
|
+
*/
|
|
192
230
|
ReturnStatement(node) {
|
|
193
231
|
if (!(funcInfo.isConstructor && funcInfo.hasExtends) || !node.argument) return;
|
|
194
232
|
let segments = funcInfo.currentSegments;
|
package/rules/no-extra-semi.cjs
CHANGED
|
@@ -74,6 +74,11 @@ var require_no_extra_semi = /* @__PURE__ */ require_chunk.t(((exports, module) =
|
|
|
74
74
|
for (let token = firstToken; token.type === "Punctuator" && !astUtils.isClosingBraceToken(token); token = sourceCode.getTokenAfter(token)) astUtils.isSemicolonToken(token) && report(token);
|
|
75
75
|
}
|
|
76
76
|
return {
|
|
77
|
+
/**
|
|
78
|
+
* Reports this empty statement, except if the parent node is a loop.
|
|
79
|
+
* @param {Node} node A EmptyStatement node to be reported.
|
|
80
|
+
* @returns {void}
|
|
81
|
+
*/
|
|
77
82
|
EmptyStatement(node) {
|
|
78
83
|
let parent = node.parent;
|
|
79
84
|
[
|
|
@@ -87,9 +92,19 @@ var require_no_extra_semi = /* @__PURE__ */ require_chunk.t(((exports, module) =
|
|
|
87
92
|
"WithStatement"
|
|
88
93
|
].includes(parent.type) || report(node);
|
|
89
94
|
},
|
|
95
|
+
/**
|
|
96
|
+
* Checks tokens from the head of this class body to the first MethodDefinition or the end of this class body.
|
|
97
|
+
* @param {Node} node A ClassBody node to check.
|
|
98
|
+
* @returns {void}
|
|
99
|
+
*/
|
|
90
100
|
ClassBody(node) {
|
|
91
101
|
checkForPartOfClassBody(sourceCode.getFirstToken(node, 1));
|
|
92
102
|
},
|
|
103
|
+
/**
|
|
104
|
+
* Checks tokens from this MethodDefinition to the next MethodDefinition or the end of this class body.
|
|
105
|
+
* @param {Node} node A MethodDefinition node of the start point.
|
|
106
|
+
* @returns {void}
|
|
107
|
+
*/
|
|
93
108
|
"MethodDefinition, PropertyDefinition, StaticBlock"(node) {
|
|
94
109
|
checkForPartOfClassBody(sourceCode.getTokenAfter(node));
|
|
95
110
|
}
|
|
@@ -95,6 +95,12 @@ var require_no_this_before_super = /* @__PURE__ */ require_chunk.t(((exports, mo
|
|
|
95
95
|
for (let segment of segments) segment.reachable && (segInfoMap[segment.id].superCalled = !0);
|
|
96
96
|
}
|
|
97
97
|
return {
|
|
98
|
+
/**
|
|
99
|
+
* Adds information of a constructor into the stack.
|
|
100
|
+
* @param {CodePath} codePath A code path which was started.
|
|
101
|
+
* @param {ASTNode} node The current node.
|
|
102
|
+
* @returns {void}
|
|
103
|
+
*/
|
|
98
104
|
onCodePathStart(codePath, node) {
|
|
99
105
|
if (isConstructorFunction(node)) {
|
|
100
106
|
let classNode = node.parent.parent.parent;
|
|
@@ -113,6 +119,14 @@ var require_no_this_before_super = /* @__PURE__ */ require_chunk.t(((exports, mo
|
|
|
113
119
|
currentSegments: /* @__PURE__ */ new Set()
|
|
114
120
|
};
|
|
115
121
|
},
|
|
122
|
+
/**
|
|
123
|
+
* Removes the top of stack item.
|
|
124
|
+
*
|
|
125
|
+
* And this traverses all segments of this code path then reports every
|
|
126
|
+
* invalid node.
|
|
127
|
+
* @param {CodePath} codePath A code path which was ended.
|
|
128
|
+
* @returns {void}
|
|
129
|
+
*/
|
|
116
130
|
onCodePathEnd(codePath) {
|
|
117
131
|
let isDerivedClass = funcInfo.hasExtends;
|
|
118
132
|
if (funcInfo = funcInfo.upper, !isDerivedClass) return;
|
|
@@ -131,6 +145,11 @@ var require_no_this_before_super = /* @__PURE__ */ require_chunk.t(((exports, mo
|
|
|
131
145
|
info.superCalled && controller.skip();
|
|
132
146
|
});
|
|
133
147
|
},
|
|
148
|
+
/**
|
|
149
|
+
* Initialize information of a given code path segment.
|
|
150
|
+
* @param {CodePathSegment} segment A code path segment to initialize.
|
|
151
|
+
* @returns {void}
|
|
152
|
+
*/
|
|
134
153
|
onCodePathSegmentStart(segment) {
|
|
135
154
|
funcInfo.currentSegments.add(segment), isInConstructorOfDerivedClass() && (segInfoMap[segment.id] = {
|
|
136
155
|
superCalled: segment.prevSegments.length > 0 && segment.prevSegments.every(isCalled),
|
|
@@ -146,6 +165,15 @@ var require_no_this_before_super = /* @__PURE__ */ require_chunk.t(((exports, mo
|
|
|
146
165
|
onCodePathSegmentEnd(segment) {
|
|
147
166
|
funcInfo.currentSegments.delete(segment);
|
|
148
167
|
},
|
|
168
|
+
/**
|
|
169
|
+
* Update information of the code path segment when a code path was
|
|
170
|
+
* looped.
|
|
171
|
+
* @param {CodePathSegment} fromSegment The code path segment of the
|
|
172
|
+
* end of a loop.
|
|
173
|
+
* @param {CodePathSegment} toSegment A code path segment of the head
|
|
174
|
+
* of a loop.
|
|
175
|
+
* @returns {void}
|
|
176
|
+
*/
|
|
149
177
|
onCodePathSegmentLoop(fromSegment, toSegment) {
|
|
150
178
|
isInConstructorOfDerivedClass() && funcInfo.codePath.traverseSegments({
|
|
151
179
|
first: toSegment,
|
|
@@ -155,15 +183,34 @@ var require_no_this_before_super = /* @__PURE__ */ require_chunk.t(((exports, mo
|
|
|
155
183
|
info.superCalled ? controller.skip() : segment.prevSegments.length > 0 && segment.prevSegments.every(isCalled) && (info.superCalled = !0), segInfoMap[segment.id] = info;
|
|
156
184
|
});
|
|
157
185
|
},
|
|
186
|
+
/**
|
|
187
|
+
* Reports if this is before `super()`.
|
|
188
|
+
* @param {ASTNode} node A target node.
|
|
189
|
+
* @returns {void}
|
|
190
|
+
*/
|
|
158
191
|
ThisExpression(node) {
|
|
159
192
|
isBeforeCallOfSuper() && setInvalid(node);
|
|
160
193
|
},
|
|
194
|
+
/**
|
|
195
|
+
* Reports if this is before `super()`.
|
|
196
|
+
* @param {ASTNode} node A target node.
|
|
197
|
+
* @returns {void}
|
|
198
|
+
*/
|
|
161
199
|
Super(node) {
|
|
162
200
|
!astUtils.isCallee(node) && isBeforeCallOfSuper() && setInvalid(node);
|
|
163
201
|
},
|
|
202
|
+
/**
|
|
203
|
+
* Marks `super()` called.
|
|
204
|
+
* @param {ASTNode} node A target node.
|
|
205
|
+
* @returns {void}
|
|
206
|
+
*/
|
|
164
207
|
"CallExpression:exit"(node) {
|
|
165
208
|
node.callee.type === "Super" && isBeforeCallOfSuper() && setSuperCalled();
|
|
166
209
|
},
|
|
210
|
+
/**
|
|
211
|
+
* Resets state.
|
|
212
|
+
* @returns {void}
|
|
213
|
+
*/
|
|
167
214
|
"Program:exit"() {
|
|
168
215
|
segInfoMap = Object.create(null);
|
|
169
216
|
}
|
|
@@ -127,8 +127,21 @@ var require_no_useless_assignment = /* @__PURE__ */ require_chunk.t(((exports, m
|
|
|
127
127
|
* and if additional iterations are needed, start iterating from the retained position.
|
|
128
128
|
*/
|
|
129
129
|
let subsequentSegmentData = {
|
|
130
|
+
/**
|
|
131
|
+
* Cache of subsequent segment information list that have already been iterated.
|
|
132
|
+
* @type {SubsequentSegmentData[]}
|
|
133
|
+
*/
|
|
130
134
|
results: [],
|
|
135
|
+
/**
|
|
136
|
+
* Subsequent segments that have already been iterated on. Used to avoid infinite loops.
|
|
137
|
+
* @type {Set<CodePathSegment>}
|
|
138
|
+
*/
|
|
131
139
|
subsequentSegments: /* @__PURE__ */ new Set(),
|
|
140
|
+
/**
|
|
141
|
+
* Unexplored code path segment.
|
|
142
|
+
* If additional iterations are needed, consume this information and iterate.
|
|
143
|
+
* @type {CodePathSegment[]}
|
|
144
|
+
*/
|
|
132
145
|
queueSegments: targetAssignment.segments.flatMap((segment) => segment.nextSegments)
|
|
133
146
|
};
|
|
134
147
|
/**
|
|
@@ -148,6 +148,26 @@ var require_padding_line_between_statements = /* @__PURE__ */ require_chunk.t(((
|
|
|
148
148
|
fix(fixer) {
|
|
149
149
|
let sourceCode = context.sourceCode, prevToken = getActualLastToken(sourceCode, prevNode), nextToken = sourceCode.getFirstTokenBetween(prevToken, nextNode, {
|
|
150
150
|
includeComments: !0,
|
|
151
|
+
/**
|
|
152
|
+
* Skip the trailing comments of the previous node.
|
|
153
|
+
* This inserts a blank line after the last trailing comment.
|
|
154
|
+
*
|
|
155
|
+
* For example:
|
|
156
|
+
*
|
|
157
|
+
* foo(); // trailing comment.
|
|
158
|
+
* // comment.
|
|
159
|
+
* bar();
|
|
160
|
+
*
|
|
161
|
+
* Get fixed to:
|
|
162
|
+
*
|
|
163
|
+
* foo(); // trailing comment.
|
|
164
|
+
*
|
|
165
|
+
* // comment.
|
|
166
|
+
* bar();
|
|
167
|
+
* @param {Token} token The token to check.
|
|
168
|
+
* @returns {boolean} `true` if the token is not a trailing comment.
|
|
169
|
+
* @private
|
|
170
|
+
*/
|
|
151
171
|
filter(token) {
|
|
152
172
|
return astUtils.isTokenOnSameLine(prevToken, token) ? (prevToken = token, !1) : !0;
|
|
153
173
|
}
|