build: update npm install command to use --legacy-peer-deps
This change modifies the build scripts to use --legacy-peer-deps flag when installing npm dependencies to resolve potential peer dependency conflicts during the build process. The change is applied to both bash (build.sh) and batch (build.bat) build scripts.
This commit is contained in:
+4
-132
@@ -1,6 +1,6 @@
|
||||
[](https://www.npmjs.com/package/eslint-scope)
|
||||
[](https://www.npmjs.com/package/eslint-scope)
|
||||
[](https://github.com/eslint/js/actions)
|
||||
[](https://github.com/eslint/eslint-scope/actions)
|
||||
|
||||
# ESLint Scope
|
||||
|
||||
@@ -26,19 +26,6 @@ To use in a CommonJS file:
|
||||
const eslintScope = require('eslint-scope');
|
||||
```
|
||||
|
||||
In order to analyze scope, you'll need to have an [ESTree](https://github.com/estree/estree) compliant AST structure to run it on. The primary method is `eslintScope.analyze()`, which takes two arguments:
|
||||
|
||||
1. `ast` - the ESTree-compliant AST structure to analyze.
|
||||
2. `options` (optional) - Options to adjust how the scope is analyzed, including:
|
||||
* `ignoreEval` (default: `false`) - Set to `true` to ignore all `eval()` calls (which would normally create scopes).
|
||||
* `nodejsScope` (default: `false`) - Set to `true` to create a top-level function scope needed for CommonJS evaluation.
|
||||
* `impliedStrict` (default: `false`) - Set to `true` to evaluate the code in strict mode even outside of modules and without `"use strict"`.
|
||||
* `ecmaVersion` (default: `5`) - The version of ECMAScript to use to evaluate the code.
|
||||
* `sourceType` (default: `"script"`) - The type of JavaScript file to evaluate. Change to `"module"` for ECMAScript module code.
|
||||
* `childVisitorKeys` (default: `null`) - An object with visitor key information (like [`eslint-visitor-keys`](https://github.com/eslint/js/tree/main/packages/eslint-visitor-keys)). Without this, `eslint-scope` finds child nodes to visit algorithmically. Providing this option is a performance enhancement.
|
||||
* `fallback` (default: `"iteration"`) - The strategy to use when `childVisitorKeys` is not specified. May be a function.
|
||||
* `jsx` (default: `false`) - Enables the tracking of JSX components as variable references.
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
@@ -46,13 +33,8 @@ import * as eslintScope from 'eslint-scope';
|
||||
import * as espree from 'espree';
|
||||
import estraverse from 'estraverse';
|
||||
|
||||
const options = {
|
||||
ecmaVersion: 2022,
|
||||
sourceType: "module"
|
||||
};
|
||||
|
||||
const ast = espree.parse(code, { range: true, ...options });
|
||||
const scopeManager = eslintScope.analyze(ast, options);
|
||||
const ast = espree.parse(code, { range: true });
|
||||
const scopeManager = eslintScope.analyze(ast);
|
||||
|
||||
const currentScope = scopeManager.acquire(ast); // global scope
|
||||
|
||||
@@ -74,101 +56,9 @@ estraverse.traverse(ast, {
|
||||
});
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
The following section describes the API for this package. You can also read [the docs](https://eslint.org/docs/latest/extend/scope-manager-interface).
|
||||
|
||||
### ScopeManager
|
||||
|
||||
The `ScopeManager` class is at the core of eslint-scope and is returned when you call `eslintScope.analyze()`. It manages all scopes in a given AST.
|
||||
|
||||
#### Properties
|
||||
|
||||
- `scopes` - An array of all scopes.
|
||||
- `globalScope` - Reference to the global scope.
|
||||
|
||||
#### Methods
|
||||
|
||||
- **`acquire(node, inner)`**
|
||||
Acquires the appropriate scope for a given node.
|
||||
- `node` - The AST node to acquire the scope from.
|
||||
- `inner` - Optional boolean. When `true`, returns the innermost scope, otherwise returns the outermost scope. Default is `false`.
|
||||
- Returns: The acquired scope or `null` if no scope is found.
|
||||
|
||||
- **`acquireAll(node)`**
|
||||
Acquires all scopes for a given node.
|
||||
- `node` - The AST node to acquire scopes from.
|
||||
- Returns: An array of scopes or `undefined` if none are found.
|
||||
|
||||
- **`release(node, inner)`**
|
||||
Returns the upper scope for a given node.
|
||||
- `node` - The AST node to release.
|
||||
- `inner` - Optional boolean. When `true`, returns the innermost upper scope, otherwise returns the outermost upper scope. Default is `false`.
|
||||
- Returns: The upper scope or `null` if no upper scope exists.
|
||||
|
||||
- **`getDeclaredVariables(node)`**
|
||||
Get variables that are declared by the node.
|
||||
- `node` - The AST node to get declarations from.
|
||||
- Returns: An array of variable objects declared by the node. If the node doesn't declare any variables, it returns an empty array.
|
||||
|
||||
- **`isGlobalReturn()`**
|
||||
Determines if the global return statement should be allowed.
|
||||
- Returns: `true` if the global return is enabled.
|
||||
|
||||
- **`isModule()`**
|
||||
Checks if the code should be handled as an ECMAScript module.
|
||||
- Returns: `true` if the sourceType is "module".
|
||||
|
||||
- **`isImpliedStrict()`**
|
||||
Checks if implied strict mode is enabled.
|
||||
- Returns: `true` if implied strict mode is enabled.
|
||||
|
||||
- **`isStrictModeSupported()`**
|
||||
Checks if strict mode is supported based on ECMAScript version.
|
||||
- Returns: `true` if the ECMAScript version supports strict mode.
|
||||
|
||||
### Scope Objects
|
||||
|
||||
Scopes returned by the ScopeManager methods have the following properties:
|
||||
|
||||
- `type` - The type of scope (e.g., "function", "block", "global").
|
||||
- `variables` - Array of variables declared in this scope.
|
||||
- `set` - A Map of variable names to Variable objects for variables declared in this scope.
|
||||
- `references` - Array of references in this scope.
|
||||
- `through` - Array of references in this scope and its child scopes that aren't resolved in this scope or its child scopes.
|
||||
- `variableScope` - Reference to the closest variable scope.
|
||||
- `upper` - Reference to the parent scope.
|
||||
- `childScopes` - Array of child scopes.
|
||||
- `block` - The AST node that created this scope.
|
||||
|
||||
### GlobalScope
|
||||
|
||||
The `GlobalScope` class is a specialized scope representing the global execution context. It extends the base `Scope` class with additional functionality for handling implicitly defined global variables.
|
||||
|
||||
#### Properties
|
||||
|
||||
- **`implicit`** - Tracks implicitly defined global variables (those used without declaration).
|
||||
- `set` - A Map of variable names to Variable objects for implicitly defined globals.
|
||||
- `variables` - Array of implicit global Variable objects.
|
||||
- `left` - Array of References that need to be linked to the variable they refer to.
|
||||
|
||||
### Variable Objects
|
||||
|
||||
Each variable object has the following properties:
|
||||
|
||||
- `name` - The variable name.
|
||||
- `identifiers` - Array of identifier nodes declaring this variable.
|
||||
- `references` - Array of references to this variable.
|
||||
- `defs` - Array of definition objects for this variable.
|
||||
- `scope` - The scope object where this variable is defined.
|
||||
|
||||
## Contributing
|
||||
|
||||
Issues and pull requests will be triaged and responded to as quickly as possible. We operate under the [ESLint Contributor Guidelines](http://eslint.org/docs/developer-guide/contributing), so please be sure to read them before contributing. If you're not sure where to dig in, check out the [issues](https://github.com/eslint/js/issues).
|
||||
|
||||
## Security Policy
|
||||
|
||||
We work hard to ensure that ESLint Scope is safe for everyone and that security issues are addressed quickly and responsibly. Read the full [security policy](https://github.com/eslint/.github/blob/master/SECURITY.md).
|
||||
Issues and pull requests will be triaged and responded to as quickly as possible. We operate under the [ESLint Contributor Guidelines](http://eslint.org/docs/developer-guide/contributing), so please be sure to read them before contributing. If you're not sure where to dig in, check out the [issues](https://github.com/eslint/eslint-scope/issues).
|
||||
|
||||
## Build Commands
|
||||
|
||||
@@ -178,21 +68,3 @@ We work hard to ensure that ESLint Scope is safe for everyone and that security
|
||||
## License
|
||||
|
||||
ESLint Scope is licensed under a permissive BSD 2-clause license.
|
||||
|
||||
<!-- NOTE: This section is autogenerated. Do not manually edit.-->
|
||||
<!--sponsorsstart-->
|
||||
## Sponsors
|
||||
|
||||
The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://eslint.org/donate)
|
||||
to get your logo on our READMEs and [website](https://eslint.org/sponsors).
|
||||
|
||||
<h3>Diamond Sponsors</h3>
|
||||
<p><a href="https://www.ag-grid.com/"><img src="https://images.opencollective.com/ag-grid/bec0580/logo.png" alt="AG Grid" height="128"></a></p><h3>Platinum Sponsors</h3>
|
||||
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="128"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="128"></a></p><h3>Gold Sponsors</h3>
|
||||
<p><a href="https://qlty.sh/"><img src="https://images.opencollective.com/qltysh/33d157d/logo.png" alt="Qlty Software" height="96"></a> <a href="https://trunk.io/"><img src="https://images.opencollective.com/trunkio/fb92d60/avatar.png" alt="trunk.io" height="96"></a> <a href="https://shopify.engineering/"><img src="https://avatars.githubusercontent.com/u/8085" alt="Shopify" height="96"></a></p><h3>Silver Sponsors</h3>
|
||||
<p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/e6d15e1/logo.png" alt="Vite" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301" alt="American Express" height="64"></a> <a href="https://stackblitz.com"><img src="https://avatars.githubusercontent.com/u/28635252" alt="StackBlitz" height="64"></a></p><h3>Bronze Sponsors</h3>
|
||||
<p><a href="https://sentry.io"><img src="https://github.com/getsentry.png" alt="Sentry" height="32"></a> <a href="https://syntax.fm"><img src="https://github.com/syntaxfm.png" alt="Syntax" height="32"></a> <a href="https://cybozu.co.jp/"><img src="https://images.opencollective.com/cybozu/933e46d/logo.png" alt="Cybozu" 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://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" 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://www.gitbook.com"><img src="https://avatars.githubusercontent.com/u/7111340" alt="GitBook" height="32"></a> <a href="https://nolebase.ayaka.io"><img src="https://avatars.githubusercontent.com/u/11081491" alt="Neko" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104" alt="Nx" height="32"></a> <a href="https://opensource.mercedes-benz.com/"><img src="https://avatars.githubusercontent.com/u/34240465" alt="Mercedes-Benz Group" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774" alt="HeroCoders" height="32"></a> <a href="https://www.lambdatest.com"><img src="https://avatars.githubusercontent.com/u/171592363" alt="LambdaTest" height="32"></a></p>
|
||||
<h3>Technology Sponsors</h3>
|
||||
Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work.
|
||||
<p><a href="https://netlify.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/netlify-icon.svg" alt="Netlify" height="32"></a> <a href="https://algolia.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/algolia-icon.svg" alt="Algolia" height="32"></a> <a href="https://1password.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/1password-icon.svg" alt="1Password" height="32"></a></p>
|
||||
<!--sponsorsend-->
|
||||
|
||||
+70
-169
@@ -2,32 +2,16 @@
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
var assert = require('assert');
|
||||
var estraverse = require('estraverse');
|
||||
var esrecurse = require('esrecurse');
|
||||
|
||||
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
||||
|
||||
var assert__default = /*#__PURE__*/_interopDefaultLegacy(assert);
|
||||
var estraverse__default = /*#__PURE__*/_interopDefaultLegacy(estraverse);
|
||||
var esrecurse__default = /*#__PURE__*/_interopDefaultLegacy(esrecurse);
|
||||
|
||||
/**
|
||||
* @fileoverview Assertion utilities.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
|
||||
/**
|
||||
* Throws an error if the given condition is not truthy.
|
||||
* @param {boolean} condition The condition to check.
|
||||
* @param {string} message The message to include with the error.
|
||||
* @returns {void}
|
||||
* @throws {Error} When the condition is not truthy.
|
||||
*/
|
||||
function assert(condition, message = "Assertion failed.") {
|
||||
if (!condition) {
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>
|
||||
|
||||
@@ -389,9 +373,10 @@ const { Syntax: Syntax$2 } = estraverse__default["default"];
|
||||
* @param {Scope} scope scope
|
||||
* @param {Block} block block
|
||||
* @param {boolean} isMethodDefinition is method definition
|
||||
* @param {boolean} useDirective use directive
|
||||
* @returns {boolean} is strict scope
|
||||
*/
|
||||
function isStrictScope(scope, block, isMethodDefinition) {
|
||||
function isStrictScope(scope, block, isMethodDefinition, useDirective) {
|
||||
let body;
|
||||
|
||||
// When upper scope is exists and strict, inner scope is also strict.
|
||||
@@ -431,29 +416,41 @@ function isStrictScope(scope, block, isMethodDefinition) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Search for a 'use strict' directive.
|
||||
for (let i = 0, iz = body.body.length; i < iz; ++i) {
|
||||
const stmt = body.body[i];
|
||||
// Search 'use strict' directive.
|
||||
if (useDirective) {
|
||||
for (let i = 0, iz = body.body.length; i < iz; ++i) {
|
||||
const stmt = body.body[i];
|
||||
|
||||
/*
|
||||
* Check if the current statement is a directive.
|
||||
* If it isn't, then we're past the directive prologue
|
||||
* so stop the search because directives cannot
|
||||
* appear after this point.
|
||||
*
|
||||
* Some parsers set `directive:null` on non-directive
|
||||
* statements, so the `typeof` check is safer than
|
||||
* checking for property existence.
|
||||
*/
|
||||
if (typeof stmt.directive !== "string") {
|
||||
break;
|
||||
if (stmt.type !== Syntax$2.DirectiveStatement) {
|
||||
break;
|
||||
}
|
||||
if (stmt.raw === "\"use strict\"" || stmt.raw === "'use strict'") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0, iz = body.body.length; i < iz; ++i) {
|
||||
const stmt = body.body[i];
|
||||
|
||||
if (stmt.directive === "use strict") {
|
||||
return true;
|
||||
if (stmt.type !== Syntax$2.ExpressionStatement) {
|
||||
break;
|
||||
}
|
||||
const expr = stmt.expression;
|
||||
|
||||
if (expr.type !== Syntax$2.Literal || typeof expr.value !== "string") {
|
||||
break;
|
||||
}
|
||||
if (expr.raw !== null && expr.raw !== undefined) {
|
||||
if (expr.raw === "\"use strict\"" || expr.raw === "'use strict'") {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (expr.value === "use strict") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -510,8 +507,7 @@ class Scope {
|
||||
/**
|
||||
* The tainted variables of this scope, as <code>{ Variable.name :
|
||||
* boolean }</code>.
|
||||
* @member {Map} Scope#taints
|
||||
*/
|
||||
* @member {Map} Scope#taints */
|
||||
this.taints = new Map();
|
||||
|
||||
/**
|
||||
@@ -602,7 +598,7 @@ class Scope {
|
||||
* @member {boolean} Scope#isStrict
|
||||
*/
|
||||
this.isStrict = scopeManager.isStrictModeSupported()
|
||||
? isStrictScope(this, block, isMethodDefinition)
|
||||
? isStrictScope(this, block, isMethodDefinition, scopeManager.__useDirective())
|
||||
: false;
|
||||
|
||||
/**
|
||||
@@ -690,7 +686,7 @@ class Scope {
|
||||
|
||||
// To override by function scopes.
|
||||
// References in default parameters isn't resolved to variables which are in their function body.
|
||||
__isValidResolution(ref, variable) { // eslint-disable-line class-methods-use-this, no-unused-vars -- Desired as instance method with signature
|
||||
__isValidResolution(ref, variable) { // eslint-disable-line class-methods-use-this, no-unused-vars
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -724,17 +720,17 @@ class Scope {
|
||||
}
|
||||
|
||||
__addDeclaredVariablesOfNode(variable, node) {
|
||||
if (node === null || node === void 0) {
|
||||
if (node === null || node === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
let variables = this.__declaredVariables.get(node);
|
||||
|
||||
if (variables === null || variables === void 0) {
|
||||
if (variables === null || variables === undefined) {
|
||||
variables = [];
|
||||
this.__declaredVariables.set(node, variables);
|
||||
}
|
||||
if (!variables.includes(variable)) {
|
||||
if (variables.indexOf(variable) === -1) {
|
||||
variables.push(variable);
|
||||
}
|
||||
}
|
||||
@@ -774,7 +770,7 @@ class Scope {
|
||||
__referencing(node, assign, writeExpr, maybeImplicitGlobal, partial, init) {
|
||||
|
||||
// because Array element may be null
|
||||
if (!node || (node.type !== Syntax$2.Identifier && node.type !== "JSXIdentifier")) {
|
||||
if (!node || node.type !== Syntax$2.Identifier) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -816,8 +812,8 @@ class Scope {
|
||||
resolve(ident) {
|
||||
let ref, i, iz;
|
||||
|
||||
assert(this.__isClosed(), "Scope should be closed.");
|
||||
assert(ident.type === Syntax$2.Identifier, "Target should be identifier.");
|
||||
assert__default["default"](this.__isClosed(), "Scope should be closed.");
|
||||
assert__default["default"](ident.type === Syntax$2.Identifier, "Target should be identifier.");
|
||||
for (i = 0, iz = this.references.length; i < iz; ++i) {
|
||||
ref = this.references[i];
|
||||
if (ref.identifier === ident) {
|
||||
@@ -841,7 +837,7 @@ class Scope {
|
||||
* @function Scope#isArgumentsMaterialized
|
||||
* @returns {boolean} arguemnts materialized
|
||||
*/
|
||||
isArgumentsMaterialized() { // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
isArgumentsMaterialized() { // eslint-disable-line class-methods-use-this
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -850,7 +846,7 @@ class Scope {
|
||||
* @function Scope#isThisMaterialized
|
||||
* @returns {boolean} this materialized
|
||||
*/
|
||||
isThisMaterialized() { // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
isThisMaterialized() { // eslint-disable-line class-methods-use-this
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -867,9 +863,6 @@ class Scope {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Global scope.
|
||||
*/
|
||||
class GlobalScope extends Scope {
|
||||
constructor(scopeManager, block) {
|
||||
super(scopeManager, "global", null, block, false);
|
||||
@@ -931,18 +924,12 @@ class GlobalScope extends Scope {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Module scope.
|
||||
*/
|
||||
class ModuleScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "module", upperScope, block, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function expression name scope.
|
||||
*/
|
||||
class FunctionExpressionNameScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "function-expression-name", upperScope, block, false);
|
||||
@@ -959,18 +946,12 @@ class FunctionExpressionNameScope extends Scope {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Catch scope.
|
||||
*/
|
||||
class CatchScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "catch", upperScope, block, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* With statement scope.
|
||||
*/
|
||||
class WithScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "with", upperScope, block, false);
|
||||
@@ -993,27 +974,18 @@ class WithScope extends Scope {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Block scope.
|
||||
*/
|
||||
class BlockScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "block", upperScope, block, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch scope.
|
||||
*/
|
||||
class SwitchScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "switch", upperScope, block, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function scope.
|
||||
*/
|
||||
class FunctionScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block, isMethodDefinition) {
|
||||
super(scopeManager, "function", upperScope, block, isMethodDefinition);
|
||||
@@ -1045,7 +1017,7 @@ class FunctionScope extends Scope {
|
||||
|
||||
const variable = this.set.get("arguments");
|
||||
|
||||
assert(variable, "Always have arguments variable.");
|
||||
assert__default["default"](variable, "Always have arguments variable.");
|
||||
return variable.tainted || variable.references.length !== 0;
|
||||
}
|
||||
|
||||
@@ -1091,36 +1063,24 @@ class FunctionScope extends Scope {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope of for, for-in, and for-of statements.
|
||||
*/
|
||||
class ForScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "for", upperScope, block, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class scope.
|
||||
*/
|
||||
class ClassScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "class", upperScope, block, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class field initializer scope.
|
||||
*/
|
||||
class ClassFieldInitializerScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "class-field-initializer", upperScope, block, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class static block scope.
|
||||
*/
|
||||
class ClassStaticBlockScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "class-static-block", upperScope, block, true);
|
||||
@@ -1166,6 +1126,10 @@ class ScopeManager {
|
||||
this.__declaredVariables = new WeakMap();
|
||||
}
|
||||
|
||||
__useDirective() {
|
||||
return this.__options.directive;
|
||||
}
|
||||
|
||||
__isOptimistic() {
|
||||
return this.__options.optimistic;
|
||||
}
|
||||
@@ -1174,10 +1138,6 @@ class ScopeManager {
|
||||
return this.__options.ignoreEval;
|
||||
}
|
||||
|
||||
__isJSXEnabled() {
|
||||
return this.__options.jsx === true;
|
||||
}
|
||||
|
||||
isGlobalReturn() {
|
||||
return this.__options.nodejsScope || this.__options.sourceType === "commonjs";
|
||||
}
|
||||
@@ -1297,13 +1257,13 @@ class ScopeManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
attach() { } // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
attach() { } // eslint-disable-line class-methods-use-this
|
||||
|
||||
detach() { } // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
detach() { } // eslint-disable-line class-methods-use-this
|
||||
|
||||
__nestScope(scope) {
|
||||
if (scope instanceof GlobalScope) {
|
||||
assert(this.__currentScope === null);
|
||||
assert__default["default"](this.__currentScope === null);
|
||||
this.globalScope = scope;
|
||||
}
|
||||
this.__currentScope = scope;
|
||||
@@ -1397,12 +1357,9 @@ const { Syntax: Syntax$1 } = estraverse__default["default"];
|
||||
* @returns {any} Last elment
|
||||
*/
|
||||
function getLast(xs) {
|
||||
return xs.at(-1) || null;
|
||||
return xs[xs.length - 1] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor for destructuring patterns.
|
||||
*/
|
||||
class PatternVisitor extends esrecurse__default["default"].Visitor {
|
||||
static isPattern(node) {
|
||||
const nodeType = node.type;
|
||||
@@ -1431,7 +1388,7 @@ class PatternVisitor extends esrecurse__default["default"].Visitor {
|
||||
|
||||
this.callback(pattern, {
|
||||
topLevel: pattern === this.rootPattern,
|
||||
rest: lastRestElement !== null && lastRestElement !== void 0 && lastRestElement.argument === pattern,
|
||||
rest: lastRestElement !== null && lastRestElement !== undefined && lastRestElement.argument === pattern,
|
||||
assignments: this.assignments
|
||||
});
|
||||
}
|
||||
@@ -1557,7 +1514,7 @@ function traverseIdentifierInPattern(options, rootPattern, referencer, callback)
|
||||
visitor.visit(rootPattern);
|
||||
|
||||
// Process the right hand nodes recursively.
|
||||
if (referencer !== null && referencer !== void 0) {
|
||||
if (referencer !== null && referencer !== undefined) {
|
||||
visitor.rightHandNodes.forEach(referencer.visit, referencer);
|
||||
}
|
||||
}
|
||||
@@ -1568,9 +1525,6 @@ function traverseIdentifierInPattern(options, rootPattern, referencer, callback)
|
||||
// FIXME: Now, we don't create module environment, because the context is
|
||||
// implementation dependent.
|
||||
|
||||
/**
|
||||
* Visitor for import specifiers.
|
||||
*/
|
||||
class Importer extends esrecurse__default["default"].Visitor {
|
||||
constructor(declaration, referencer) {
|
||||
super(null, referencer.options);
|
||||
@@ -1617,9 +1571,7 @@ class Importer extends esrecurse__default["default"].Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Referencing variables and creating bindings.
|
||||
*/
|
||||
// Referencing variables and creating bindings.
|
||||
class Referencer extends esrecurse__default["default"].Visitor {
|
||||
constructor(options, scopeManager) {
|
||||
super(null, options);
|
||||
@@ -1783,6 +1735,8 @@ class Referencer extends esrecurse__default["default"].Visitor {
|
||||
));
|
||||
}
|
||||
|
||||
this.visit(node.superClass);
|
||||
|
||||
this.scopeManager.__nestClassScope(node);
|
||||
|
||||
if (node.id) {
|
||||
@@ -1793,8 +1747,6 @@ class Referencer extends esrecurse__default["default"].Visitor {
|
||||
node
|
||||
));
|
||||
}
|
||||
|
||||
this.visit(node.superClass);
|
||||
this.visit(node.body);
|
||||
|
||||
this.close(node);
|
||||
@@ -1904,7 +1856,7 @@ class Referencer extends esrecurse__default["default"].Visitor {
|
||||
this.currentScope().__define(pattern,
|
||||
new Definition(
|
||||
Variable.CatchClause,
|
||||
pattern,
|
||||
node.param,
|
||||
node,
|
||||
null,
|
||||
null,
|
||||
@@ -1943,7 +1895,7 @@ class Referencer extends esrecurse__default["default"].Visitor {
|
||||
this.currentScope().__referencing(node);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this -- Desired as instance method
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
PrivateIdentifier() {
|
||||
|
||||
// Do nothing.
|
||||
@@ -1993,9 +1945,9 @@ class Referencer extends esrecurse__default["default"].Visitor {
|
||||
this.visitProperty(node);
|
||||
}
|
||||
|
||||
BreakStatement() {} // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
BreakStatement() {} // eslint-disable-line class-methods-use-this
|
||||
|
||||
ContinueStatement() {} // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
ContinueStatement() {} // eslint-disable-line class-methods-use-this
|
||||
|
||||
LabeledStatement(node) {
|
||||
this.visit(node.body);
|
||||
@@ -2110,7 +2062,7 @@ class Referencer extends esrecurse__default["default"].Visitor {
|
||||
}
|
||||
|
||||
ImportDeclaration(node) {
|
||||
assert(this.scopeManager.__isES6() && this.scopeManager.isModule(), "ImportDeclaration should appear when the mode is ES6 and in the module context.");
|
||||
assert__default["default"](this.scopeManager.__isES6() && this.scopeManager.isModule(), "ImportDeclaration should appear when the mode is ES6 and in the module context.");
|
||||
|
||||
const importer = new Importer(node, this);
|
||||
|
||||
@@ -2154,67 +2106,15 @@ class Referencer extends esrecurse__default["default"].Visitor {
|
||||
this.visit(local);
|
||||
}
|
||||
|
||||
MetaProperty() { // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
MetaProperty() { // eslint-disable-line class-methods-use-this
|
||||
|
||||
// do nothing.
|
||||
}
|
||||
|
||||
JSXIdentifier(node) {
|
||||
|
||||
// Special case: "this" should not count as a reference
|
||||
if (this.scopeManager.__isJSXEnabled() && node.name !== "this") {
|
||||
this.currentScope().__referencing(node);
|
||||
}
|
||||
}
|
||||
|
||||
JSXMemberExpression(node) {
|
||||
this.visit(node.object);
|
||||
}
|
||||
|
||||
JSXElement(node) {
|
||||
if (this.scopeManager.__isJSXEnabled()) {
|
||||
this.visit(node.openingElement);
|
||||
node.children.forEach(this.visit, this);
|
||||
} else {
|
||||
this.visitChildren(node);
|
||||
}
|
||||
}
|
||||
|
||||
JSXOpeningElement(node) {
|
||||
if (this.scopeManager.__isJSXEnabled()) {
|
||||
|
||||
const nameNode = node.name;
|
||||
const isComponentName = nameNode.type === "JSXIdentifier" && nameNode.name[0].toUpperCase() === nameNode.name[0];
|
||||
const isComponent = isComponentName || nameNode.type === "JSXMemberExpression";
|
||||
|
||||
// we only want to visit JSXIdentifier nodes if they are capitalized
|
||||
if (isComponent) {
|
||||
this.visit(nameNode);
|
||||
}
|
||||
}
|
||||
|
||||
node.attributes.forEach(this.visit, this);
|
||||
}
|
||||
|
||||
JSXAttribute(node) {
|
||||
if (node.value) {
|
||||
this.visit(node.value);
|
||||
}
|
||||
}
|
||||
|
||||
JSXExpressionContainer(node) {
|
||||
this.visit(node.expression);
|
||||
}
|
||||
|
||||
JSXNamespacedName(node) {
|
||||
this.visit(node.namespace);
|
||||
this.visit(node.name);
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set sw=4 ts=4 et tw=80 : */
|
||||
|
||||
const version = "8.4.0";
|
||||
const version = "7.2.2";
|
||||
|
||||
/*
|
||||
Copyright (C) 2012-2014 Yusuke Suzuki <utatane.tea@gmail.com>
|
||||
@@ -2249,6 +2149,7 @@ const version = "8.4.0";
|
||||
function defaultOptions() {
|
||||
return {
|
||||
optimistic: false,
|
||||
directive: false,
|
||||
nodejsScope: false,
|
||||
impliedStrict: false,
|
||||
sourceType: "script", // one of ['script', 'module', 'commonjs']
|
||||
@@ -2276,7 +2177,7 @@ function updateDeeply(target, override) {
|
||||
}
|
||||
|
||||
for (const key in override) {
|
||||
if (Object.hasOwn(override, key)) {
|
||||
if (Object.prototype.hasOwnProperty.call(override, key)) {
|
||||
const val = override[key];
|
||||
|
||||
if (isHashObject(val)) {
|
||||
@@ -2300,6 +2201,7 @@ function updateDeeply(target, override) {
|
||||
* @param {espree.Tree} tree Abstract Syntax Tree
|
||||
* @param {Object} providedOptions Options that tailor the scope analysis
|
||||
* @param {boolean} [providedOptions.optimistic=false] the optimistic flag
|
||||
* @param {boolean} [providedOptions.directive=false] the directive flag
|
||||
* @param {boolean} [providedOptions.ignoreEval=false] whether to check 'eval()' calls
|
||||
* @param {boolean} [providedOptions.nodejsScope=false] whether the whole
|
||||
* script is executed under node.js environment. When enabled, escope adds
|
||||
@@ -2308,7 +2210,6 @@ function updateDeeply(target, override) {
|
||||
* (if ecmaVersion >= 5).
|
||||
* @param {string} [providedOptions.sourceType='script'] the source type of the script. one of 'script', 'module', and 'commonjs'
|
||||
* @param {number} [providedOptions.ecmaVersion=5] which ECMAScript version is considered
|
||||
* @param {boolean} [providedOptions.jsx=false] support JSX references
|
||||
* @param {Object} [providedOptions.childVisitorKeys=null] Additional known visitor keys. See [esrecurse](https://github.com/estools/esrecurse)'s the `childVisitorKeys` option.
|
||||
* @param {string} [providedOptions.fallback='iteration'] A kind of the fallback in order to encounter with unknown node. See [esrecurse](https://github.com/estools/esrecurse)'s the `fallback` option.
|
||||
* @returns {ScopeManager} ScopeManager
|
||||
@@ -2320,7 +2221,7 @@ function analyze(tree, providedOptions) {
|
||||
|
||||
referencer.visit(tree);
|
||||
|
||||
assert(scopeManager.__currentScope === null, "currentScope should be null.");
|
||||
assert__default["default"](scopeManager.__currentScope === null, "currentScope should be null.");
|
||||
|
||||
return scopeManager;
|
||||
}
|
||||
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
/**
|
||||
* @fileoverview Assertion utilities.
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
|
||||
/**
|
||||
* Throws an error if the given condition is not truthy.
|
||||
* @param {boolean} condition The condition to check.
|
||||
* @param {string} message The message to include with the error.
|
||||
* @returns {void}
|
||||
* @throws {Error} When the condition is not truthy.
|
||||
*/
|
||||
export function assert(condition, message = "Assertion failed.") {
|
||||
if (!condition) {
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -45,8 +45,9 @@
|
||||
* The main interface is the {@link analyze} function.
|
||||
* @module escope
|
||||
*/
|
||||
/* eslint no-underscore-dangle: ["error", { "allow": ["__currentScope"] }] */
|
||||
|
||||
import { assert } from "./assert.js";
|
||||
import assert from "assert";
|
||||
|
||||
import ScopeManager from "./scope-manager.js";
|
||||
import Referencer from "./referencer.js";
|
||||
@@ -62,6 +63,7 @@ import eslintScopeVersion from "./version.js";
|
||||
function defaultOptions() {
|
||||
return {
|
||||
optimistic: false,
|
||||
directive: false,
|
||||
nodejsScope: false,
|
||||
impliedStrict: false,
|
||||
sourceType: "script", // one of ['script', 'module', 'commonjs']
|
||||
@@ -89,7 +91,7 @@ function updateDeeply(target, override) {
|
||||
}
|
||||
|
||||
for (const key in override) {
|
||||
if (Object.hasOwn(override, key)) {
|
||||
if (Object.prototype.hasOwnProperty.call(override, key)) {
|
||||
const val = override[key];
|
||||
|
||||
if (isHashObject(val)) {
|
||||
@@ -113,6 +115,7 @@ function updateDeeply(target, override) {
|
||||
* @param {espree.Tree} tree Abstract Syntax Tree
|
||||
* @param {Object} providedOptions Options that tailor the scope analysis
|
||||
* @param {boolean} [providedOptions.optimistic=false] the optimistic flag
|
||||
* @param {boolean} [providedOptions.directive=false] the directive flag
|
||||
* @param {boolean} [providedOptions.ignoreEval=false] whether to check 'eval()' calls
|
||||
* @param {boolean} [providedOptions.nodejsScope=false] whether the whole
|
||||
* script is executed under node.js environment. When enabled, escope adds
|
||||
@@ -121,7 +124,6 @@ function updateDeeply(target, override) {
|
||||
* (if ecmaVersion >= 5).
|
||||
* @param {string} [providedOptions.sourceType='script'] the source type of the script. one of 'script', 'module', and 'commonjs'
|
||||
* @param {number} [providedOptions.ecmaVersion=5] which ECMAScript version is considered
|
||||
* @param {boolean} [providedOptions.jsx=false] support JSX references
|
||||
* @param {Object} [providedOptions.childVisitorKeys=null] Additional known visitor keys. See [esrecurse](https://github.com/estools/esrecurse)'s the `childVisitorKeys` option.
|
||||
* @param {string} [providedOptions.fallback='iteration'] A kind of the fallback in order to encounter with unknown node. See [esrecurse](https://github.com/estools/esrecurse)'s the `fallback` option.
|
||||
* @returns {ScopeManager} ScopeManager
|
||||
|
||||
+4
-5
@@ -22,6 +22,8 @@
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* eslint-disable no-undefined */
|
||||
|
||||
import estraverse from "estraverse";
|
||||
import esrecurse from "esrecurse";
|
||||
|
||||
@@ -33,12 +35,9 @@ const { Syntax } = estraverse;
|
||||
* @returns {any} Last elment
|
||||
*/
|
||||
function getLast(xs) {
|
||||
return xs.at(-1) || null;
|
||||
return xs[xs.length - 1] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor for destructuring patterns.
|
||||
*/
|
||||
class PatternVisitor extends esrecurse.Visitor {
|
||||
static isPattern(node) {
|
||||
const nodeType = node.type;
|
||||
@@ -67,7 +66,7 @@ class PatternVisitor extends esrecurse.Visitor {
|
||||
|
||||
this.callback(pattern, {
|
||||
topLevel: pattern === this.rootPattern,
|
||||
rest: lastRestElement !== null && lastRestElement !== void 0 && lastRestElement.argument === pattern,
|
||||
rest: lastRestElement !== null && lastRestElement !== undefined && lastRestElement.argument === pattern,
|
||||
assignments: this.assignments
|
||||
});
|
||||
}
|
||||
|
||||
+13
-67
@@ -22,13 +22,16 @@
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
/* eslint-disable no-undefined */
|
||||
|
||||
import estraverse from "estraverse";
|
||||
import esrecurse from "esrecurse";
|
||||
import Reference from "./reference.js";
|
||||
import Variable from "./variable.js";
|
||||
import PatternVisitor from "./pattern-visitor.js";
|
||||
import { Definition, ParameterDefinition } from "./definition.js";
|
||||
import { assert } from "./assert.js";
|
||||
import assert from "assert";
|
||||
|
||||
const { Syntax } = estraverse;
|
||||
|
||||
@@ -48,7 +51,7 @@ function traverseIdentifierInPattern(options, rootPattern, referencer, callback)
|
||||
visitor.visit(rootPattern);
|
||||
|
||||
// Process the right hand nodes recursively.
|
||||
if (referencer !== null && referencer !== void 0) {
|
||||
if (referencer !== null && referencer !== undefined) {
|
||||
visitor.rightHandNodes.forEach(referencer.visit, referencer);
|
||||
}
|
||||
}
|
||||
@@ -59,9 +62,6 @@ function traverseIdentifierInPattern(options, rootPattern, referencer, callback)
|
||||
// FIXME: Now, we don't create module environment, because the context is
|
||||
// implementation dependent.
|
||||
|
||||
/**
|
||||
* Visitor for import specifiers.
|
||||
*/
|
||||
class Importer extends esrecurse.Visitor {
|
||||
constructor(declaration, referencer) {
|
||||
super(null, referencer.options);
|
||||
@@ -108,9 +108,7 @@ class Importer extends esrecurse.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Referencing variables and creating bindings.
|
||||
*/
|
||||
// Referencing variables and creating bindings.
|
||||
class Referencer extends esrecurse.Visitor {
|
||||
constructor(options, scopeManager) {
|
||||
super(null, options);
|
||||
@@ -274,6 +272,8 @@ class Referencer extends esrecurse.Visitor {
|
||||
));
|
||||
}
|
||||
|
||||
this.visit(node.superClass);
|
||||
|
||||
this.scopeManager.__nestClassScope(node);
|
||||
|
||||
if (node.id) {
|
||||
@@ -284,8 +284,6 @@ class Referencer extends esrecurse.Visitor {
|
||||
node
|
||||
));
|
||||
}
|
||||
|
||||
this.visit(node.superClass);
|
||||
this.visit(node.body);
|
||||
|
||||
this.close(node);
|
||||
@@ -395,7 +393,7 @@ class Referencer extends esrecurse.Visitor {
|
||||
this.currentScope().__define(pattern,
|
||||
new Definition(
|
||||
Variable.CatchClause,
|
||||
pattern,
|
||||
node.param,
|
||||
node,
|
||||
null,
|
||||
null,
|
||||
@@ -434,7 +432,7 @@ class Referencer extends esrecurse.Visitor {
|
||||
this.currentScope().__referencing(node);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this -- Desired as instance method
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
PrivateIdentifier() {
|
||||
|
||||
// Do nothing.
|
||||
@@ -484,9 +482,9 @@ class Referencer extends esrecurse.Visitor {
|
||||
this.visitProperty(node);
|
||||
}
|
||||
|
||||
BreakStatement() {} // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
BreakStatement() {} // eslint-disable-line class-methods-use-this
|
||||
|
||||
ContinueStatement() {} // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
ContinueStatement() {} // eslint-disable-line class-methods-use-this
|
||||
|
||||
LabeledStatement(node) {
|
||||
this.visit(node.body);
|
||||
@@ -645,62 +643,10 @@ class Referencer extends esrecurse.Visitor {
|
||||
this.visit(local);
|
||||
}
|
||||
|
||||
MetaProperty() { // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
MetaProperty() { // eslint-disable-line class-methods-use-this
|
||||
|
||||
// do nothing.
|
||||
}
|
||||
|
||||
JSXIdentifier(node) {
|
||||
|
||||
// Special case: "this" should not count as a reference
|
||||
if (this.scopeManager.__isJSXEnabled() && node.name !== "this") {
|
||||
this.currentScope().__referencing(node);
|
||||
}
|
||||
}
|
||||
|
||||
JSXMemberExpression(node) {
|
||||
this.visit(node.object);
|
||||
}
|
||||
|
||||
JSXElement(node) {
|
||||
if (this.scopeManager.__isJSXEnabled()) {
|
||||
this.visit(node.openingElement);
|
||||
node.children.forEach(this.visit, this);
|
||||
} else {
|
||||
this.visitChildren(node);
|
||||
}
|
||||
}
|
||||
|
||||
JSXOpeningElement(node) {
|
||||
if (this.scopeManager.__isJSXEnabled()) {
|
||||
|
||||
const nameNode = node.name;
|
||||
const isComponentName = nameNode.type === "JSXIdentifier" && nameNode.name[0].toUpperCase() === nameNode.name[0];
|
||||
const isComponent = isComponentName || nameNode.type === "JSXMemberExpression";
|
||||
|
||||
// we only want to visit JSXIdentifier nodes if they are capitalized
|
||||
if (isComponent) {
|
||||
this.visit(nameNode);
|
||||
}
|
||||
}
|
||||
|
||||
node.attributes.forEach(this.visit, this);
|
||||
}
|
||||
|
||||
JSXAttribute(node) {
|
||||
if (node.value) {
|
||||
this.visit(node.value);
|
||||
}
|
||||
}
|
||||
|
||||
JSXExpressionContainer(node) {
|
||||
this.visit(node.expression);
|
||||
}
|
||||
|
||||
JSXNamespacedName(node) {
|
||||
this.visit(node.namespace);
|
||||
this.visit(node.name);
|
||||
}
|
||||
}
|
||||
|
||||
export default Referencer;
|
||||
|
||||
+9
-7
@@ -22,6 +22,8 @@
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
|
||||
import {
|
||||
BlockScope,
|
||||
CatchScope,
|
||||
@@ -36,7 +38,7 @@ import {
|
||||
SwitchScope,
|
||||
WithScope
|
||||
} from "./scope.js";
|
||||
import { assert } from "./assert.js";
|
||||
import assert from "assert";
|
||||
|
||||
/**
|
||||
* @constructor ScopeManager
|
||||
@@ -51,6 +53,10 @@ class ScopeManager {
|
||||
this.__declaredVariables = new WeakMap();
|
||||
}
|
||||
|
||||
__useDirective() {
|
||||
return this.__options.directive;
|
||||
}
|
||||
|
||||
__isOptimistic() {
|
||||
return this.__options.optimistic;
|
||||
}
|
||||
@@ -59,10 +65,6 @@ class ScopeManager {
|
||||
return this.__options.ignoreEval;
|
||||
}
|
||||
|
||||
__isJSXEnabled() {
|
||||
return this.__options.jsx === true;
|
||||
}
|
||||
|
||||
isGlobalReturn() {
|
||||
return this.__options.nodejsScope || this.__options.sourceType === "commonjs";
|
||||
}
|
||||
@@ -182,9 +184,9 @@ class ScopeManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
attach() { } // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
attach() { } // eslint-disable-line class-methods-use-this
|
||||
|
||||
detach() { } // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
detach() { } // eslint-disable-line class-methods-use-this
|
||||
|
||||
__nestScope(scope) {
|
||||
if (scope instanceof GlobalScope) {
|
||||
|
||||
+45
-66
@@ -22,12 +22,15 @@
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
/* eslint-disable no-undefined */
|
||||
|
||||
import estraverse from "estraverse";
|
||||
|
||||
import Reference from "./reference.js";
|
||||
import Variable from "./variable.js";
|
||||
import { Definition } from "./definition.js";
|
||||
import { assert } from "./assert.js";
|
||||
import assert from "assert";
|
||||
|
||||
const { Syntax } = estraverse;
|
||||
|
||||
@@ -36,9 +39,10 @@ const { Syntax } = estraverse;
|
||||
* @param {Scope} scope scope
|
||||
* @param {Block} block block
|
||||
* @param {boolean} isMethodDefinition is method definition
|
||||
* @param {boolean} useDirective use directive
|
||||
* @returns {boolean} is strict scope
|
||||
*/
|
||||
function isStrictScope(scope, block, isMethodDefinition) {
|
||||
function isStrictScope(scope, block, isMethodDefinition, useDirective) {
|
||||
let body;
|
||||
|
||||
// When upper scope is exists and strict, inner scope is also strict.
|
||||
@@ -78,29 +82,41 @@ function isStrictScope(scope, block, isMethodDefinition) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Search for a 'use strict' directive.
|
||||
for (let i = 0, iz = body.body.length; i < iz; ++i) {
|
||||
const stmt = body.body[i];
|
||||
// Search 'use strict' directive.
|
||||
if (useDirective) {
|
||||
for (let i = 0, iz = body.body.length; i < iz; ++i) {
|
||||
const stmt = body.body[i];
|
||||
|
||||
/*
|
||||
* Check if the current statement is a directive.
|
||||
* If it isn't, then we're past the directive prologue
|
||||
* so stop the search because directives cannot
|
||||
* appear after this point.
|
||||
*
|
||||
* Some parsers set `directive:null` on non-directive
|
||||
* statements, so the `typeof` check is safer than
|
||||
* checking for property existence.
|
||||
*/
|
||||
if (typeof stmt.directive !== "string") {
|
||||
break;
|
||||
if (stmt.type !== Syntax.DirectiveStatement) {
|
||||
break;
|
||||
}
|
||||
if (stmt.raw === "\"use strict\"" || stmt.raw === "'use strict'") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0, iz = body.body.length; i < iz; ++i) {
|
||||
const stmt = body.body[i];
|
||||
|
||||
if (stmt.directive === "use strict") {
|
||||
return true;
|
||||
if (stmt.type !== Syntax.ExpressionStatement) {
|
||||
break;
|
||||
}
|
||||
const expr = stmt.expression;
|
||||
|
||||
if (expr.type !== Syntax.Literal || typeof expr.value !== "string") {
|
||||
break;
|
||||
}
|
||||
if (expr.raw !== null && expr.raw !== undefined) {
|
||||
if (expr.raw === "\"use strict\"" || expr.raw === "'use strict'") {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (expr.value === "use strict") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -157,8 +173,7 @@ class Scope {
|
||||
/**
|
||||
* The tainted variables of this scope, as <code>{ Variable.name :
|
||||
* boolean }</code>.
|
||||
* @member {Map} Scope#taints
|
||||
*/
|
||||
* @member {Map} Scope#taints */
|
||||
this.taints = new Map();
|
||||
|
||||
/**
|
||||
@@ -249,7 +264,7 @@ class Scope {
|
||||
* @member {boolean} Scope#isStrict
|
||||
*/
|
||||
this.isStrict = scopeManager.isStrictModeSupported()
|
||||
? isStrictScope(this, block, isMethodDefinition)
|
||||
? isStrictScope(this, block, isMethodDefinition, scopeManager.__useDirective())
|
||||
: false;
|
||||
|
||||
/**
|
||||
@@ -337,7 +352,7 @@ class Scope {
|
||||
|
||||
// To override by function scopes.
|
||||
// References in default parameters isn't resolved to variables which are in their function body.
|
||||
__isValidResolution(ref, variable) { // eslint-disable-line class-methods-use-this, no-unused-vars -- Desired as instance method with signature
|
||||
__isValidResolution(ref, variable) { // eslint-disable-line class-methods-use-this, no-unused-vars
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -371,17 +386,17 @@ class Scope {
|
||||
}
|
||||
|
||||
__addDeclaredVariablesOfNode(variable, node) {
|
||||
if (node === null || node === void 0) {
|
||||
if (node === null || node === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
let variables = this.__declaredVariables.get(node);
|
||||
|
||||
if (variables === null || variables === void 0) {
|
||||
if (variables === null || variables === undefined) {
|
||||
variables = [];
|
||||
this.__declaredVariables.set(node, variables);
|
||||
}
|
||||
if (!variables.includes(variable)) {
|
||||
if (variables.indexOf(variable) === -1) {
|
||||
variables.push(variable);
|
||||
}
|
||||
}
|
||||
@@ -421,7 +436,7 @@ class Scope {
|
||||
__referencing(node, assign, writeExpr, maybeImplicitGlobal, partial, init) {
|
||||
|
||||
// because Array element may be null
|
||||
if (!node || (node.type !== Syntax.Identifier && node.type !== "JSXIdentifier")) {
|
||||
if (!node || node.type !== Syntax.Identifier) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -488,7 +503,7 @@ class Scope {
|
||||
* @function Scope#isArgumentsMaterialized
|
||||
* @returns {boolean} arguemnts materialized
|
||||
*/
|
||||
isArgumentsMaterialized() { // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
isArgumentsMaterialized() { // eslint-disable-line class-methods-use-this
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -497,7 +512,7 @@ class Scope {
|
||||
* @function Scope#isThisMaterialized
|
||||
* @returns {boolean} this materialized
|
||||
*/
|
||||
isThisMaterialized() { // eslint-disable-line class-methods-use-this -- Desired as instance method
|
||||
isThisMaterialized() { // eslint-disable-line class-methods-use-this
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -514,9 +529,6 @@ class Scope {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Global scope.
|
||||
*/
|
||||
class GlobalScope extends Scope {
|
||||
constructor(scopeManager, block) {
|
||||
super(scopeManager, "global", null, block, false);
|
||||
@@ -578,18 +590,12 @@ class GlobalScope extends Scope {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Module scope.
|
||||
*/
|
||||
class ModuleScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "module", upperScope, block, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function expression name scope.
|
||||
*/
|
||||
class FunctionExpressionNameScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "function-expression-name", upperScope, block, false);
|
||||
@@ -606,18 +612,12 @@ class FunctionExpressionNameScope extends Scope {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Catch scope.
|
||||
*/
|
||||
class CatchScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "catch", upperScope, block, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* With statement scope.
|
||||
*/
|
||||
class WithScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "with", upperScope, block, false);
|
||||
@@ -640,27 +640,18 @@ class WithScope extends Scope {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Block scope.
|
||||
*/
|
||||
class BlockScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "block", upperScope, block, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch scope.
|
||||
*/
|
||||
class SwitchScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "switch", upperScope, block, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function scope.
|
||||
*/
|
||||
class FunctionScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block, isMethodDefinition) {
|
||||
super(scopeManager, "function", upperScope, block, isMethodDefinition);
|
||||
@@ -738,36 +729,24 @@ class FunctionScope extends Scope {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope of for, for-in, and for-of statements.
|
||||
*/
|
||||
class ForScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "for", upperScope, block, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class scope.
|
||||
*/
|
||||
class ClassScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "class", upperScope, block, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class field initializer scope.
|
||||
*/
|
||||
class ClassFieldInitializerScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "class-field-initializer", upperScope, block, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class static block scope.
|
||||
*/
|
||||
class ClassStaticBlockScope extends Scope {
|
||||
constructor(scopeManager, upperScope, block) {
|
||||
super(scopeManager, "class-static-block", upperScope, block, true);
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
const version = "8.4.0";
|
||||
const version = "7.2.2";
|
||||
|
||||
export default version;
|
||||
|
||||
+25
-26
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "eslint-scope",
|
||||
"description": "ECMAScript scope analyzer for ESLint",
|
||||
"homepage": "https://github.com/eslint/js/blob/main/packages/eslint-scope/README.md",
|
||||
"homepage": "http://github.com/eslint/eslint-scope",
|
||||
"main": "./dist/eslint-scope.cjs",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
@@ -11,34 +11,27 @@
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"version": "8.4.0",
|
||||
"version": "7.2.2",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eslint/js.git",
|
||||
"directory": "packages/eslint-scope"
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"repository": "eslint/eslint-scope",
|
||||
"funding": "https://opencollective.com/eslint",
|
||||
"keywords": [
|
||||
"eslint"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/eslint/js/issues"
|
||||
"url": "https://github.com/eslint/eslint-scope/issues"
|
||||
},
|
||||
"license": "BSD-2-Clause",
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"build:update-version": "node tools/update-version.js",
|
||||
"prepublishOnly": "npm run build:update-version && npm run build",
|
||||
"pretest": "npm run build",
|
||||
"release:generate:latest": "eslint-generate-release",
|
||||
"release:generate:alpha": "eslint-generate-prerelease alpha",
|
||||
"release:generate:beta": "eslint-generate-prerelease beta",
|
||||
"release:generate:rc": "eslint-generate-prerelease rc",
|
||||
"release:publish": "eslint-publish-release",
|
||||
"test": "node Makefile.js test"
|
||||
"lint": "npm run build && node Makefile.js lint",
|
||||
"update-version": "node tools/update-version.js",
|
||||
"test": "npm run build && node Makefile.js test",
|
||||
"prepublishOnly": "npm run update-version && npm run build",
|
||||
"generate-release": "eslint-generate-release",
|
||||
"generate-alpharelease": "eslint-generate-prerelease alpha",
|
||||
"generate-betarelease": "eslint-generate-prerelease beta",
|
||||
"generate-rcrelease": "eslint-generate-prerelease rc",
|
||||
"publish-release": "eslint-publish-release"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
@@ -51,14 +44,20 @@
|
||||
"estraverse": "^5.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/parser": "^8.7.0",
|
||||
"@typescript-eslint/parser": "^4.28.1",
|
||||
"c8": "^7.7.3",
|
||||
"chai": "^4.3.4",
|
||||
"eslint": "^7.29.0",
|
||||
"eslint-config-eslint": "^7.0.0",
|
||||
"eslint-plugin-jsdoc": "^35.4.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-release": "^3.2.0",
|
||||
"eslint-visitor-keys": "^4.2.1",
|
||||
"espree": "^10.4.0",
|
||||
"eslint-visitor-keys": "^3.3.0",
|
||||
"espree": "^9.3.1",
|
||||
"mocha": "^9.0.1",
|
||||
"npm-license": "^0.3.3",
|
||||
"rollup": "^2.52.7",
|
||||
"shelljs": "^0.8.5",
|
||||
"typescript": "^5.4.2"
|
||||
"shelljs": "^0.8.4",
|
||||
"typescript": "^4.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user