Socket
Socket
Sign inDemoInstall

eslint

Package Overview
Dependencies
Maintainers
4
Versions
369
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint - npm Package Compare versions

Comparing version 8.33.0 to 8.38.0

lib/rules/utils/regular-expressions.js

4

conf/rule-type-list.json

@@ -9,3 +9,3 @@ {

"name": "Deprecated",
"description": "These rules have been deprecated in accordance with the <a href=\"/docs/use/rule-deprecation\">deprecation policy</a>, and replaced by newer rules:",
"description": "These rules have been deprecated in accordance with the <a href=\"{{ '/use/rule-deprecation' | url }}\">deprecation policy</a>, and replaced by newer rules:",
"rules": []

@@ -15,3 +15,3 @@ },

"name": "Removed",
"description": "These rules from older versions of ESLint (before the <a href=\"/docs/use/rule-deprecation\">deprecation policy</a> existed) have been replaced by newer rules:",
"description": "These rules from older versions of ESLint (before the <a href=\"{{ '/use/rule-deprecation' | url }}\">deprecation policy</a> existed) have been replaced by newer rules:",
"rules": [

@@ -18,0 +18,0 @@ { "removed": "generator-star", "replacedBy": ["generator-star-spacing"] },

@@ -618,4 +618,4 @@ /**

loadRules,
getEslintRecommendedConfig: () => require("../../conf/eslint-recommended.js"),
getEslintAllConfig: () => require("../../conf/eslint-all.js")
getEslintRecommendedConfig: () => require("@eslint/js").configs.recommended,
getEslintAllConfig: () => require("@eslint/js").configs.all
});

@@ -622,0 +622,0 @@ const fileEnumerator = new FileEnumerator({

@@ -220,4 +220,4 @@ /**

cwd,
getEslintRecommendedConfig: () => require("../../conf/eslint-recommended.js"),
getEslintAllConfig: () => require("../../conf/eslint-all.js")
getEslintRecommendedConfig: () => require("@eslint/js").configs.recommended,
getEslintAllConfig: () => require("@eslint/js").configs.all
}),

@@ -353,3 +353,3 @@ extensions = null,

if (globInputPaths && isGlobPattern(pattern)) {
return this._iterateFilesWithGlob(absolutePath, isDot);
return this._iterateFilesWithGlob(pattern, isDot);
}

@@ -403,4 +403,6 @@

const directoryPath = path.resolve(getGlobParent(pattern));
const globPart = pattern.slice(directoryPath.length + 1);
const { cwd } = internalSlotsMap.get(this);
const directoryPath = path.resolve(cwd, getGlobParent(pattern));
const absolutePath = path.resolve(cwd, pattern);
const globPart = absolutePath.slice(directoryPath.length + 1);

@@ -412,3 +414,3 @@ /*

const recursive = /\*\*|\/|\\/u.test(globPart);
const selector = new Minimatch(pattern, minimatchOpts);
const selector = new Minimatch(absolutePath, minimatchOpts);

@@ -415,0 +417,0 @@ debug(`recursive? ${recursive}`);

@@ -22,5 +22,2 @@ /**

"@": {
parsers: {
espree: require("espree")
},

@@ -47,3 +44,3 @@ /*

ecmaVersion: "latest",
parser: "@/espree",
parser: require("espree"),
parserOptions: {}

@@ -50,0 +47,0 @@ }

@@ -16,3 +16,3 @@ /**

const { defaultConfig } = require("./default-config");
const recommendedConfig = require("../../conf/eslint-recommended");
const jsPlugin = require("@eslint/js");

@@ -40,2 +40,41 @@ //-----------------------------------------------------------------------------

/**
* Returns the name of an object in the config by reading its `meta` key.
* @param {Object} object The object to check.
* @returns {string?} The name of the object if found or `null` if there
* is no name.
*/
function getObjectId(object) {
// first check old-style name
let name = object.name;
if (!name) {
if (!object.meta) {
return null;
}
name = object.meta.name;
if (!name) {
return null;
}
}
// now check for old-style version
let version = object.version;
if (!version) {
version = object.meta && object.meta.version;
}
// if there's a version then append that
if (version) {
return `${name}@${version}`;
}
return name;
}
const originalBaseConfig = Symbol("originalBaseConfig");

@@ -101,3 +140,9 @@

if (config === "eslint:recommended") {
return recommendedConfig;
// if we are in a Node.js environment warn the user
if (typeof process !== "undefined" && process.emitWarning) {
process.emitWarning("The 'eslint:recommended' string configuration is deprecated and will be replaced by the @eslint/js package's 'recommended' config.");
}
return jsPlugin.configs.recommended;
}

@@ -107,8 +152,8 @@

/*
* Load `eslint-all.js` here instead of at the top level to avoid loading all rule modules
* when it isn't necessary. `eslint-all.js` reads `meta` of rule objects to filter out deprecated ones,
* so requiring `eslint-all.js` module loads all rule modules as a consequence.
*/
return require("../../conf/eslint-all");
// if we are in a Node.js environment warn the user
if (typeof process !== "undefined" && process.emitWarning) {
process.emitWarning("The 'eslint:all' string configuration is deprecated and will be replaced by the @eslint/js package's 'all' config.");
}
return jsPlugin.configs.all;
}

@@ -152,12 +197,11 @@

if (languageOptions && languageOptions.parser) {
if (typeof languageOptions.parser === "string") {
const { pluginName, objectName: localParserName } = splitPluginIdentifier(languageOptions.parser);
const { parser } = languageOptions;
parserName = languageOptions.parser;
if (typeof parser === "object") {
parserName = getObjectId(parser);
if (!plugins || !plugins[pluginName] || !plugins[pluginName].parsers || !plugins[pluginName].parsers[localParserName]) {
throw new TypeError(`Key "parser": Could not find "${localParserName}" in plugin "${pluginName}".`);
if (!parserName) {
invalidParser = true;
}
languageOptions.parser = plugins[pluginName].parsers[localParserName];
} else {

@@ -180,2 +224,9 @@ invalidParser = true;

config.processor = plugins[pluginName].processors[localProcessorName];
} else if (typeof processor === "object") {
processorName = getObjectId(processor);
if (!processorName) {
invalidProcessor = true;
}
} else {

@@ -194,7 +245,7 @@ invalidProcessor = true;

if (invalidParser) {
throw new Error("Caching is not supported when parser is an object.");
throw new Error("Could not serialize parser object (missing 'meta' object).");
}
if (invalidProcessor) {
throw new Error("Caching is not supported when processor is an object.");
throw new Error("Could not serialize processor object (missing 'meta' object).");
}

@@ -204,3 +255,12 @@

...this,
plugins: Object.keys(plugins),
plugins: Object.entries(plugins).map(([namespace, plugin]) => {
const pluginId = getObjectId(plugin);
if (!pluginId) {
return namespace;
}
return `${namespace}:${pluginId}`;
}),
languageOptions: {

@@ -207,0 +267,0 @@ ...languageOptions,

@@ -182,14 +182,2 @@ /**

/**
* Validates that a value is an object or a string.
* @param {any} value The value to check.
* @returns {void}
* @throws {TypeError} If the value isn't an object or a string.
*/
function assertIsObjectOrString(value) {
if ((!value || typeof value !== "object") && typeof value !== "string") {
throw new TypeError("Expected an object or string.");
}
}
//-----------------------------------------------------------------------------

@@ -246,11 +234,9 @@ // Low-Level Schemas

validate(value) {
assertIsObjectOrString(value);
if (typeof value === "object" && typeof value.parse !== "function" && typeof value.parseForESLint !== "function") {
throw new TypeError("Expected object to have a parse() or parseForESLint() method.");
if (!value || typeof value !== "object" ||
(typeof value.parse !== "function" && typeof value.parseForESLint !== "function")
) {
throw new TypeError("Expected object with parse() or parseForESLint() method.");
}
if (typeof value === "string") {
assertIsPluginMemberName(value);
}
}

@@ -257,0 +243,0 @@ };

@@ -226,3 +226,3 @@ /**

* or an empty array if there are no matches.
* @throws {UnmatchedSearchPatternsErrror} If there is a pattern that doesn't
* @throws {UnmatchedSearchPatternsError} If there is a pattern that doesn't
* match any files.

@@ -530,5 +530,5 @@ */

// save patterns for later use based on whether globs are enabled
if (globInputPaths && isGlobPattern(filePath)) {
if (globInputPaths && isGlobPattern(pattern)) {
const basePath = globParent(filePath);
const basePath = path.resolve(cwd, globParent(pattern));

@@ -573,37 +573,2 @@ // group in cwd if possible and split out others

/**
* Checks whether a file exists at the given location
* @param {string} resolvedPath A path from the CWD
* @throws {Error} As thrown by `fs.statSync` or `fs.isFile`.
* @returns {boolean} `true` if a file exists
*/
function fileExists(resolvedPath) {
try {
return fs.statSync(resolvedPath).isFile();
} catch (error) {
if (error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
return false;
}
throw error;
}
}
/**
* Checks whether a directory exists at the given location
* @param {string} resolvedPath A path from the CWD
* @throws {Error} As thrown by `fs.statSync` or `fs.isDirectory`.
* @returns {boolean} `true` if a directory exists
*/
function directoryExists(resolvedPath) {
try {
return fs.statSync(resolvedPath).isDirectory();
} catch (error) {
if (error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
return false;
}
throw error;
}
}
//-----------------------------------------------------------------------------

@@ -930,4 +895,2 @@ // Results-related Helpers

isGlobPattern,
directoryExists,
fileExists,
findFiles,

@@ -934,0 +897,0 @@

@@ -348,3 +348,3 @@ /**

static setDefaultConfig(config) {
if (typeof config !== "object") {
if (typeof config !== "object" || config === null) {
throw new TypeError("FlatRuleTester.setDefaultConfig: config must be an object");

@@ -351,0 +351,0 @@ }

@@ -415,3 +415,3 @@ /**

static setDefaultConfig(config) {
if (typeof config !== "object") {
if (typeof config !== "object" || config === null) {
throw new TypeError("RuleTester.setDefaultConfig: config must be an object");

@@ -418,0 +418,0 @@ }

@@ -19,3 +19,3 @@ /**

const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
const TARGET_METHODS = /^(?:every|filter|find(?:Last)?(?:Index)?|flatMap|forEach|map|reduce(?:Right)?|some|sort)$/u;
const TARGET_METHODS = /^(?:every|filter|find(?:Last)?(?:Index)?|flatMap|forEach|map|reduce(?:Right)?|some|sort|toSorted)$/u;

@@ -22,0 +22,0 @@ /**

@@ -50,2 +50,3 @@ /**

},
type: "array",
items: [

@@ -52,0 +53,0 @@ {

@@ -31,2 +31,3 @@ /**

let stack = [];
const sourceCode = context.getSourceCode();

@@ -87,3 +88,3 @@ /**

// Gets declared variables, and checks its references.
const variables = context.getDeclaredVariables(node);
const variables = sourceCode.getDeclaredVariables(node);

@@ -90,0 +91,0 @@ for (let i = 0; i < variables.length; ++i) {

@@ -76,2 +76,3 @@ /**

const allow = options.allow || [];
const sourceCode = context.getSourceCode();

@@ -249,4 +250,4 @@ //--------------------------------------------------------------------------

// Report camelcase of global variable references ------------------
Program() {
const scope = context.getScope();
Program(node) {
const scope = sourceCode.getScope(node);

@@ -300,3 +301,3 @@ if (!ignoreGlobals) {

]](node) {
for (const variable of context.getDeclaredVariables(node)) {
for (const variable of sourceCode.getDeclaredVariables(node)) {
if (isGoodName(variable.name)) {

@@ -351,3 +352,3 @@ continue;

ImportDeclaration(node) {
for (const variable of context.getDeclaredVariables(node)) {
for (const variable of sourceCode.getDeclaredVariables(node)) {
if (isGoodName(variable.name)) {

@@ -354,0 +355,0 @@ continue;

@@ -39,2 +39,3 @@ /**

let aliases = [];
const sourceCode = context.getSourceCode();

@@ -119,6 +120,7 @@ if (context.options.length === 0) {

* Check each alias to ensure that is was assigned to the correct value.
* @param {ASTNode} node The node that represents the scope to check.
* @returns {void}
*/
function ensureWasAssigned() {
const scope = context.getScope();
function ensureWasAssigned(node) {
const scope = sourceCode.getScope(node);

@@ -125,0 +127,0 @@ aliases.forEach(alias => {

@@ -162,3 +162,3 @@ /**

// Skip recursive functions.
const nameVar = context.getDeclaredVariables(node)[0];
const nameVar = sourceCode.getDeclaredVariables(node)[0];

@@ -165,0 +165,0 @@ if (isFunctionName(nameVar) && nameVar.references.length > 0) {

@@ -74,8 +74,10 @@ /**

create(context) {
const sourceCode = context.getSourceCode();
return {
CallExpression(node) {
const currentScope = context.getScope();
const currentScope = sourceCode.getScope(node);
if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) {
const isGoodRequire = context.getAncestors().every(parent => ACCEPTABLE_PARENTS.has(parent.type));
const isGoodRequire = sourceCode.getAncestors(node).every(parent => ACCEPTABLE_PARENTS.has(parent.type));

@@ -82,0 +84,0 @@ if (!isGoodRequire) {

@@ -41,2 +41,3 @@ /**

const errorArgument = context.options[0] || "err";
const sourceCode = context.getSourceCode();

@@ -83,3 +84,3 @@ /**

function checkForError(node) {
const scope = context.getScope(),
const scope = sourceCode.getScope(node),
parameters = getParameters(scope),

@@ -86,0 +87,0 @@ firstParameter = parameters[0];

@@ -143,2 +143,3 @@ /**

const reportedNodes = new Set();
const sourceCode = context.getSourceCode();

@@ -235,4 +236,4 @@ let globalScope;

Program() {
globalScope = context.getScope();
Program(node) {
globalScope = sourceCode.getScope(node);
},

@@ -239,0 +240,0 @@

@@ -124,2 +124,3 @@ /**

const reportedNodes = new Set();
const sourceCode = context.getSourceCode();

@@ -214,4 +215,4 @@ let globalScope;

Program() {
globalScope = context.getScope();
Program(node) {
globalScope = sourceCode.getScope(node);
},

@@ -218,0 +219,0 @@

@@ -70,2 +70,3 @@ /**

const sourceCode = context.getSourceCode();
let globalScope;

@@ -174,4 +175,4 @@

Program() {
globalScope = context.getScope();
Program(node) {
globalScope = sourceCode.getScope(node);
},

@@ -178,0 +179,0 @@

@@ -116,2 +116,6 @@ /**

type: "boolean"
},
afterHashbangComment: {
type: "boolean",
default: false
}

@@ -453,2 +457,9 @@ },

}
} else if (token.type === "Shebang") {
if (options.afterHashbangComment) {
checkForEmptyLine(token, {
after: options.afterHashbangComment,
before: false
});
}
}

@@ -455,0 +466,0 @@ });

@@ -115,3 +115,3 @@ /**

* truthiness checks: value, Boolean(value), !!value
* falsyness checks: !value, !Boolean(value)
* falsiness checks: !value, !Boolean(value)
* nullish checks: value == null, value === undefined || value === null

@@ -163,3 +163,3 @@ * @param {ASTNode} expression Test condition

docs: {
description: "Require or disallow logical assignment logical operator shorthand",
description: "Require or disallow logical assignment operator shorthand",
recommended: false,

@@ -211,3 +211,3 @@ url: "https://eslint.org/docs/rules/logical-assignment-operators"

const sourceCode = context.getSourceCode();
const isStrict = context.getScope().isStrict;
const isStrict = sourceCode.getScope(sourceCode.ast).isStrict;

@@ -415,3 +415,3 @@ /**

const body = hasBody ? ifNode.consequent.body[0] : ifNode.consequent;
const scope = context.getScope();
const scope = sourceCode.getScope(ifNode);
const existence = getExistence(ifNode.test, scope);

@@ -418,0 +418,0 @@

@@ -25,3 +25,33 @@ /**

fixable: "whitespace",
schema: [{ enum: ["starred-block", "separate-lines", "bare-block"] }],
schema: {
anyOf: [
{
type: "array",
items: [
{
enum: ["starred-block", "bare-block"]
}
],
additionalItems: false
},
{
type: "array",
items: [
{
enum: ["separate-lines"]
},
{
type: "object",
properties: {
checkJSDoc: {
type: "boolean"
}
},
additionalProperties: false
}
],
additionalItems: false
}
]
},
messages: {

@@ -41,2 +71,4 @@ expectedBlock: "Expected a block comment instead of consecutive line comments.",

const option = context.options[0] || "starred-block";
const params = context.options[1] || {};
const checkJSDoc = !!params.checkJSDoc;

@@ -338,7 +370,14 @@ //----------------------------------------------------------------------

if (firstComment.type !== "Block" || isJSDocComment(commentGroup)) {
const isJSDoc = isJSDocComment(commentGroup);
if (firstComment.type !== "Block" || (!checkJSDoc && isJSDoc)) {
return;
}
const commentLines = getCommentLines(commentGroup);
let commentLines = getCommentLines(commentGroup);
if (isJSDoc) {
commentLines = commentLines.slice(1, commentLines.length - 1);
}
const tokenAfter = sourceCode.getTokenAfter(firstComment, { includeComments: true });

@@ -345,0 +384,0 @@

@@ -34,16 +34,7 @@ /**

fixable: "code",
schema: {
anyOf: [
{
type: "array",
items: [
{
enum: ["always", "never"]
}
],
minItems: 0,
maxItems: 1
}
]
},
schema: [
{
enum: ["always", "never"]
}
],
messages: {

@@ -50,0 +41,0 @@ missing: "Missing '()' invoking a constructor.",

@@ -104,6 +104,8 @@ /**

create(context) {
const sourceCode = context.getSourceCode();
return {
CallExpression(node) {
const callee = skipChainExpression(node.callee),
currentScope = context.getScope();
currentScope = sourceCode.getScope(node);

@@ -110,0 +112,0 @@ // without window.

@@ -42,2 +42,4 @@ /**

const sourceCode = context.getSourceCode();
//--------------------------------------------------------------------------

@@ -64,3 +66,3 @@ // Helpers

"CatchClause[param!=null]"(node) {
let scope = context.getScope();
let scope = sourceCode.getScope(node);

@@ -67,0 +69,0 @@ /*

@@ -34,2 +34,4 @@ /**

const sourceCode = context.getSourceCode();
/**

@@ -53,3 +55,3 @@ * Finds and reports references that are non initializer and writable.

function checkForClass(node) {
context.getDeclaredVariables(node).forEach(checkVariable);
sourceCode.getDeclaredVariables(node).forEach(checkVariable);
}

@@ -56,0 +58,0 @@

@@ -54,2 +54,3 @@ /**

const allowed = options.allow || [];
const sourceCode = context.getSourceCode();

@@ -113,4 +114,4 @@ /**

return {
"Program:exit"() {
const scope = context.getScope();
"Program:exit"(node) {
const scope = sourceCode.getScope(node);
const consoleVar = astUtils.getVariableByName(scope, "console");

@@ -117,0 +118,0 @@ const shadowed = consoleVar && consoleVar.defs.length > 0;

@@ -34,2 +34,4 @@ /**

const sourceCode = context.getSourceCode();
/**

@@ -49,3 +51,3 @@ * Finds and reports references that are non initializer and writable.

if (node.kind === "const") {
context.getDeclaredVariables(node).forEach(checkVariable);
sourceCode.getDeclaredVariables(node).forEach(checkVariable);
}

@@ -52,0 +54,0 @@ }

@@ -18,2 +18,19 @@ /**

/**
* Checks whether or not a node is `null` or `undefined`. Similar to the one
* found in ast-utils.js, but this one correctly handles the edge case that
* `undefined` has been redefined.
* @param {Scope} scope Scope in which the expression was found.
* @param {ASTNode} node A node to check.
* @returns {boolean} Whether or not the node is a `null` or `undefined`.
* @public
*/
function isNullOrUndefined(scope, node) {
return (
isNullLiteral(node) ||
(node.type === "Identifier" && node.name === "undefined" && isReferenceToGlobalVariable(scope, node)) ||
(node.type === "UnaryExpression" && node.operator === "void")
);
}
/**
* Test if an AST node has a statically knowable constant nullishness. Meaning,

@@ -25,5 +42,10 @@ * it will always resolve to a constant value of either: `null`, `undefined`

* @param {ASTNode} node The AST node being tested.
* @param {boolean} nonNullish if `true` then nullish values are not considered constant.
* @returns {boolean} Does `node` have constant nullishness?
*/
function hasConstantNullishness(scope, node) {
function hasConstantNullishness(scope, node, nonNullish) {
if (nonNullish && isNullOrUndefined(scope, node)) {
return false;
}
switch (node.type) {

@@ -50,5 +72,8 @@ case "ObjectExpression": // Objects are never nullish

}
case "LogicalExpression": {
return node.operator === "??" && hasConstantNullishness(scope, node.right, true);
}
case "AssignmentExpression":
if (node.operator === "=") {
return hasConstantNullishness(scope, node.right);
return hasConstantNullishness(scope, node.right, nonNullish);
}

@@ -86,3 +111,3 @@

return hasConstantNullishness(scope, last);
return hasConstantNullishness(scope, last, nonNullish);
}

@@ -355,3 +380,3 @@ case "Identifier":

*
* Catching these is especially useful for primitive constructures
* Catching these is especially useful for primitive constructors
* which return boxed values, a surprising gotcha' in JavaScript.

@@ -387,20 +412,2 @@ */

/**
* Checks whether or not a node is `null` or `undefined`. Similar to the one
* found in ast-utils.js, but this one correctly handles the edge case that
* `undefined` has been redefined.
* @param {Scope} scope Scope in which the expression was found.
* @param {ASTNode} node A node to check.
* @returns {boolean} Whether or not the node is a `null` or `undefined`.
* @public
*/
function isNullOrUndefined(scope, node) {
return (
isNullLiteral(node) ||
(node.type === "Identifier" && node.name === "undefined" && isReferenceToGlobalVariable(scope, node)) ||
(node.type === "UnaryExpression" && node.operator === "void")
);
}
/**
* Checks if one operand will cause the result to be constant.

@@ -416,3 +423,3 @@ * @param {Scope} scope Scope in which the expression was found.

if (
(isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b)) ||
(isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b, false)) ||
(isStaticBoolean(scope, a) && hasConstantLooseBooleanComparison(scope, b))

@@ -424,3 +431,3 @@ ) {

if (
(isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b)) ||
(isNullOrUndefined(scope, a) && hasConstantNullishness(scope, b, false)) ||
(isStaticBoolean(scope, a) && hasConstantStrictBooleanComparison(scope, b))

@@ -457,10 +464,12 @@ ) {

create(context) {
const sourceCode = context.getSourceCode();
return {
LogicalExpression(node) {
const { operator, left } = node;
const scope = context.getScope();
const scope = sourceCode.getScope(node);
if ((operator === "&&" || operator === "||") && isConstant(scope, left, true)) {
context.report({ node: left, messageId: "constantShortCircuit", data: { property: "truthiness", operator } });
} else if (operator === "??" && hasConstantNullishness(scope, left)) {
} else if (operator === "??" && hasConstantNullishness(scope, left, false)) {
context.report({ node: left, messageId: "constantShortCircuit", data: { property: "nullishness", operator } });

@@ -470,3 +479,3 @@ }

BinaryExpression(node) {
const scope = context.getScope();
const scope = sourceCode.getScope(node);
const { right, left, operator } = node;

@@ -473,0 +482,0 @@ const rightConstantOperand = findBinaryExpressionConstantOperand(scope, left, right, operator);

@@ -51,2 +51,3 @@ /**

loopSetStack = [];
const sourceCode = context.getSourceCode();

@@ -66,3 +67,3 @@ let loopsInCurrentScope = new Set();

function trackConstantConditionLoop(node) {
if (node.test && isConstant(context.getScope(), node.test, true)) {
if (node.test && isConstant(sourceCode.getScope(node), node.test, true)) {
loopsInCurrentScope.add(node);

@@ -92,3 +93,3 @@ }

function reportIfConstant(node) {
if (node.test && isConstant(context.getScope(), node.test, true)) {
if (node.test && isConstant(sourceCode.getScope(node), node.test, true)) {
context.report({ node: node.test, messageId: "unexpected" });

@@ -95,0 +96,0 @@ }

@@ -8,3 +8,3 @@ /**

const RegExpValidator = require("regexpp").RegExpValidator;
const RegExpValidator = require("@eslint-community/regexpp").RegExpValidator;
const collector = new (class {

@@ -11,0 +11,0 @@ constructor() {

@@ -18,3 +18,3 @@ /**

docs: {
description: "Disallow division operators explicitly at the beginning of regular expressions",
description: "Disallow equal signs explicitly at the beginning of regular expressions",
recommended: false,

@@ -21,0 +21,0 @@ url: "https://eslint.org/docs/rules/no-div-regex"

@@ -32,2 +32,4 @@ /**

const sourceCode = context.getSourceCode();
//--------------------------------------------------------------------------

@@ -53,3 +55,3 @@ // Helpers

function checkParams(node) {
const variables = context.getDeclaredVariables(node);
const variables = sourceCode.getDeclaredVariables(node);

@@ -56,0 +58,0 @@ for (let i = 0; i < variables.length; ++i) {

@@ -50,2 +50,4 @@ /**

const sourceCode = context.getSourceCode();
//--------------------------------------------------------------------------

@@ -173,21 +175,20 @@ // Helpers

* Display the context report if rule is violated
* @param {Node} node The 'else' node
* @param {Node} elseNode The 'else' node
* @returns {void}
*/
function displayReport(node) {
const currentScope = context.getScope();
function displayReport(elseNode) {
const currentScope = sourceCode.getScope(elseNode.parent);
context.report({
node,
node: elseNode,
messageId: "unexpected",
fix(fixer) {
if (!isSafeFromNameCollisions(node, currentScope)) {
if (!isSafeFromNameCollisions(elseNode, currentScope)) {
return null;
}
const sourceCode = context.getSourceCode();
const startToken = sourceCode.getFirstToken(node);
const startToken = sourceCode.getFirstToken(elseNode);
const elseToken = sourceCode.getTokenBefore(startToken);
const source = sourceCode.getText(node);
const source = sourceCode.getText(elseNode);
const lastIfToken = sourceCode.getTokenBefore(elseToken);

@@ -208,3 +209,3 @@ let fixedSource, firstTokenOfElseBlock;

*/
const ifBlockMaybeUnsafe = node.parent.consequent.type !== "BlockStatement" && lastIfToken.value !== ";";
const ifBlockMaybeUnsafe = elseNode.parent.consequent.type !== "BlockStatement" && lastIfToken.value !== ";";
const elseBlockUnsafe = /^[([/+`-]/u.test(firstTokenOfElseBlock.value);

@@ -216,3 +217,3 @@

const endToken = sourceCode.getLastToken(node);
const endToken = sourceCode.getLastToken(elseNode);
const lastTokenOfElseBlock = sourceCode.getTokenBefore(endToken);

@@ -251,4 +252,4 @@

return new FixTracker(fixer, sourceCode)
.retainEnclosingFunction(node)
.replaceTextRange([elseToken.range[0], node.range[1]], fixedSource);
.retainEnclosingFunction(elseNode)
.replaceTextRange([elseToken.range[0], elseNode.range[1]], fixedSource);
}

@@ -255,0 +256,0 @@ });

@@ -75,3 +75,3 @@ /**

/**
* Pushs a `this` scope (non-arrow function, class static block, or class field initializer) information to the stack.
* Pushes a `this` scope (non-arrow function, class static block, or class field initializer) information to the stack.
* Top-level scopes are handled separately.

@@ -88,3 +88,3 @@ *

function enterThisScope(node) {
const strict = context.getScope().isStrict;
const strict = sourceCode.getScope(node).isStrict;

@@ -226,3 +226,3 @@ funcInfo = {

Program(node) {
const scope = context.getScope(),
const scope = sourceCode.getScope(node),
features = context.parserOptions.ecmaFeatures || {},

@@ -245,4 +245,4 @@ strict =

"Program:exit"() {
const globalScope = context.getScope();
"Program:exit"(node) {
const globalScope = sourceCode.getScope(node);

@@ -249,0 +249,0 @@ exitThisScope();

@@ -34,2 +34,4 @@ /**

const sourceCode = context.getSourceCode();
/**

@@ -48,3 +50,3 @@ * Finds and reports references that are non initializer and writable.

CatchClause(node) {
context.getDeclaredVariables(node).forEach(checkVariable);
sourceCode.getDeclaredVariables(node).forEach(checkVariable);
}

@@ -51,0 +53,0 @@ };

@@ -54,2 +54,3 @@ /**

const config = context.options[0] || {};
const sourceCode = context.getSourceCode();
const exceptions = new Set(config.exceptions || []);

@@ -163,4 +164,4 @@ const modifiedBuiltins = new Set(

"Program:exit"() {
const globalScope = context.getScope();
"Program:exit"(node) {
const globalScope = sourceCode.getScope(node);

@@ -167,0 +168,0 @@ modifiedBuiltins.forEach(builtin => {

@@ -13,3 +13,3 @@ /**

const astUtils = require("./utils/ast-utils");
const eslintUtils = require("eslint-utils");
const eslintUtils = require("@eslint-community/eslint-utils");

@@ -16,0 +16,0 @@ const precedence = astUtils.getPrecedence;

@@ -11,3 +11,3 @@ /**

const { isParenthesized: isParenthesizedRaw } = require("eslint-utils");
const { isParenthesized: isParenthesizedRaw } = require("@eslint-community/eslint-utils");
const astUtils = require("./utils/ast-utils.js");

@@ -770,2 +770,34 @@

/**
* Checks if the left-hand side of an assignment is an identifier, the operator is one of
* `=`, `&&=`, `||=` or `??=` and the right-hand side is an anonymous class or function.
*
* As per https://tc39.es/ecma262/#sec-assignment-operators-runtime-semantics-evaluation, an
* assignment involving one of the operators `=`, `&&=`, `||=` or `??=` where the right-hand
* side is an anonymous class or function and the left-hand side is an *unparenthesized*
* identifier has different semantics than other assignments.
* Specifically, when an expression like `foo = function () {}` is evaluated, `foo.name`
* will be set to the string "foo", i.e. the identifier name. The same thing does not happen
* when evaluating `(foo) = function () {}`.
* Since the parenthesizing of the identifier in the left-hand side is significant in this
* special case, the parentheses, if present, should not be flagged as unnecessary.
* @param {ASTNode} node an AssignmentExpression node.
* @returns {boolean} `true` if the left-hand side of the assignment is an identifier, the
* operator is one of `=`, `&&=`, `||=` or `??=` and the right-hand side is an anonymous
* class or function; otherwise, `false`.
*/
function isAnonymousFunctionAssignmentException({ left, operator, right }) {
if (left.type === "Identifier" && ["=", "&&=", "||=", "??="].includes(operator)) {
const rhsType = right.type;
if (rhsType === "ArrowFunctionExpression") {
return true;
}
if ((rhsType === "FunctionExpression" || rhsType === "ClassExpression") && !right.id) {
return true;
}
}
return false;
}
return {

@@ -809,3 +841,4 @@ ArrayExpression(node) {

AssignmentExpression(node) {
if (canBeAssignmentTarget(node.left) && hasExcessParens(node.left)) {
if (canBeAssignmentTarget(node.left) && hasExcessParens(node.left) &&
(!isAnonymousFunctionAssignmentException(node) || isParenthesisedTwice(node.left))) {
report(node.left);

@@ -812,0 +845,0 @@ }

@@ -34,2 +34,4 @@ /**

const sourceCode = context.getSourceCode();
/**

@@ -69,3 +71,3 @@ * Reports a reference if is non initializer and writable.

function checkForFunction(node) {
context.getDeclaredVariables(node).forEach(checkVariable);
sourceCode.getDeclaredVariables(node).forEach(checkVariable);
}

@@ -72,0 +74,0 @@

@@ -44,2 +44,3 @@ /**

const config = context.options[0];
const sourceCode = context.getSourceCode();
const exceptions = (config && config.exceptions) || [];

@@ -88,4 +89,4 @@

return {
Program() {
const globalScope = context.getScope();
Program(node) {
const globalScope = sourceCode.getScope(node);

@@ -92,0 +93,0 @@ globalScope.variables.forEach(checkVariable);

@@ -46,2 +46,3 @@ /**

const checkLexicalBindings = context.options[0] && context.options[0].lexicalBindings === true;
const sourceCode = context.getSourceCode();

@@ -66,4 +67,4 @@ /**

return {
Program() {
const scope = context.getScope();
Program(node) {
const scope = sourceCode.getScope(node);

@@ -70,0 +71,0 @@ scope.variables.forEach(variable => {

@@ -13,3 +13,3 @@ /**

const astUtils = require("./utils/ast-utils");
const { getStaticValue } = require("eslint-utils");
const { getStaticValue } = require("@eslint-community/eslint-utils");

@@ -41,2 +41,3 @@ //------------------------------------------------------------------------------

const EVAL_LIKE_FUNC_PATTERN = /^(?:set(?:Interval|Timeout)|execScript)$/u;
const sourceCode = context.getSourceCode();

@@ -71,3 +72,3 @@ /**

const staticValue = getStaticValue(firstArgument, context.getScope());
const staticValue = getStaticValue(firstArgument, sourceCode.getScope(node));
const isStaticString = staticValue && typeof staticValue.value === "string";

@@ -123,4 +124,4 @@ const isString = isStaticString || isEvaluatedString(firstArgument);

},
"Program:exit"() {
const globalScope = context.getScope();
"Program:exit"(node) {
const globalScope = sourceCode.getScope(node);

@@ -127,0 +128,0 @@ GLOBAL_CANDIDATES

@@ -12,3 +12,3 @@ /**

const { findVariable } = require("eslint-utils");
const { findVariable } = require("@eslint-community/eslint-utils");
const astUtils = require("./utils/ast-utils");

@@ -198,7 +198,9 @@

create(context) {
const sourceCode = context.getSourceCode();
return {
ImportDeclaration(node) {
const scope = context.getScope();
const scope = sourceCode.getScope(node);
for (const variable of context.getDeclaredVariables(node)) {
for (const variable of sourceCode.getDeclaredVariables(node)) {
const shouldCheckMembers = variable.defs.some(

@@ -205,0 +207,0 @@ d => d.node.type === "ImportNamespaceSpecifier"

@@ -11,3 +11,3 @@ /**

const RegExpValidator = require("regexpp").RegExpValidator;
const RegExpValidator = require("@eslint-community/regexpp").RegExpValidator;
const validator = new RegExpValidator();

@@ -14,0 +14,0 @@ const validFlags = /[dgimsuy]/gu;

@@ -98,3 +98,3 @@ /**

if (codePath.origin === "program") {
const scope = context.getScope();
const scope = sourceCode.getScope(node);
const features = context.parserOptions.ecmaFeatures || {};

@@ -124,3 +124,3 @@

stack.push({
init: !context.getScope().isStrict,
init: !sourceCode.getScope(node).isStrict,
node,

@@ -127,0 +127,0 @@ valid: true

@@ -37,2 +37,3 @@ /**

create(context) {
const sourceCode = context.getSourceCode();

@@ -63,3 +64,3 @@ //--------------------------------------------------------------------------

// Fetch the innermost scope.
const scope = context.getScope();
const scope = sourceCode.getScope(node);

@@ -66,0 +67,0 @@ /*

@@ -36,2 +36,3 @@ /**

let ruleDef;
const sourceCode = context.getSourceCode();

@@ -71,5 +72,6 @@ /**

* and "marks it" as valid if any.
* @param {ASTNode} node The current node to check.
* @returns {void}
*/
function markLoneBlock() {
function markLoneBlock(node) {
if (loneBlocks.length === 0) {

@@ -79,3 +81,3 @@ return;

const block = context.getAncestors().pop();
const block = sourceCode.getAncestors(node).pop();

@@ -122,9 +124,9 @@ if (loneBlocks[loneBlocks.length - 1] === block) {

if (node.kind === "let" || node.kind === "const") {
markLoneBlock();
markLoneBlock(node);
}
};
ruleDef.FunctionDeclaration = function() {
if (context.getScope().isStrict) {
markLoneBlock();
ruleDef.FunctionDeclaration = function(node) {
if (sourceCode.getScope(node).isStrict) {
markLoneBlock(node);
}

@@ -131,0 +133,0 @@ };

@@ -35,3 +35,3 @@ /**

IfStatement(node) {
const ancestors = context.getAncestors(),
const ancestors = sourceCode.getAncestors(node),
parent = ancestors.pop(),

@@ -38,0 +38,0 @@ grandparent = ancestors.pop();

@@ -171,2 +171,4 @@ /**

const sourceCode = context.getSourceCode();
/**

@@ -187,3 +189,3 @@ * Reports functions which match the following condition:

const references = context.getScope().through;
const references = sourceCode.getScope(node).through;
const unsafeRefs = references.filter(r => !isSafe(loopNode, r)).map(r => r.identifier.name);

@@ -190,0 +192,0 @@

@@ -6,6 +6,7 @@ /**

const { CALL, CONSTRUCT, ReferenceTracker, getStringIfConstant } = require("eslint-utils");
const { RegExpValidator, RegExpParser, visitRegExpAST } = require("regexpp");
const { CALL, CONSTRUCT, ReferenceTracker, getStringIfConstant } = require("@eslint-community/eslint-utils");
const { RegExpParser, visitRegExpAST } = require("@eslint-community/regexpp");
const { isCombiningCharacter, isEmojiModifier, isRegionalIndicatorSymbol, isSurrogatePair } = require("./utils/unicode");
const astUtils = require("./utils/ast-utils.js");
const { isValidWithUnicodeFlag } = require("./utils/regular-expressions");

@@ -16,4 +17,2 @@ //------------------------------------------------------------------------------

const REGEXPP_LATEST_ECMA_VERSION = 2022;
/**

@@ -190,34 +189,6 @@ * Iterate character sequences of a given nodes.

/**
* Checks if the given regular expression pattern would be valid with the `u` flag.
* @param {string} pattern The regular expression pattern to verify.
* @returns {boolean} `true` if the pattern would be valid with the `u` flag.
* `false` if the pattern would be invalid with the `u` flag or the configured
* ecmaVersion doesn't support the `u` flag.
*/
function isValidWithUnicodeFlag(pattern) {
const { ecmaVersion } = context.languageOptions;
// ecmaVersion <= 5 doesn't support the 'u' flag
if (ecmaVersion <= 5) {
return false;
}
const validator = new RegExpValidator({
ecmaVersion: Math.min(ecmaVersion, REGEXPP_LATEST_ECMA_VERSION)
});
try {
validator.validatePattern(pattern, void 0, void 0, /* uFlag = */ true);
} catch {
return false;
}
return true;
}
return {
"Literal[regex]"(node) {
verify(node, node.regex.pattern, node.regex.flags, fixer => {
if (!isValidWithUnicodeFlag(node.regex.pattern)) {
if (!isValidWithUnicodeFlag(context.languageOptions.ecmaVersion, node.regex.pattern)) {
return null;

@@ -229,4 +200,4 @@ }

},
"Program"() {
const scope = context.getScope();
"Program"(node) {
const scope = sourceCode.getScope(node);
const tracker = new ReferenceTracker(scope);

@@ -239,6 +210,6 @@

*/
for (const { node } of tracker.iterateGlobalReferences({
for (const { node: refNode } of tracker.iterateGlobalReferences({
RegExp: { [CALL]: true, [CONSTRUCT]: true }
})) {
const [patternNode, flagsNode] = node.arguments;
const [patternNode, flagsNode] = refNode.arguments;
const pattern = getStringIfConstant(patternNode, scope);

@@ -248,10 +219,10 @@ const flags = getStringIfConstant(flagsNode, scope);

if (typeof pattern === "string") {
verify(node, pattern, flags || "", fixer => {
verify(refNode, pattern, flags || "", fixer => {
if (!isValidWithUnicodeFlag(pattern)) {
if (!isValidWithUnicodeFlag(context.languageOptions.ecmaVersion, pattern)) {
return null;
}
if (node.arguments.length === 1) {
const penultimateToken = sourceCode.getLastToken(node, { skip: 1 }); // skip closing parenthesis
if (refNode.arguments.length === 1) {
const penultimateToken = sourceCode.getLastToken(refNode, { skip: 1 }); // skip closing parenthesis

@@ -258,0 +229,0 @@ return fixer.insertTextAfter(

@@ -50,2 +50,3 @@ /**

const exceptions = (config && config.exceptions) || [];
const sourceCode = context.getSourceCode();

@@ -91,4 +92,4 @@ /**

return {
Program() {
const globalScope = context.getScope();
Program(node) {
const globalScope = sourceCode.getScope(node);

@@ -95,0 +96,0 @@ globalScope.variables.forEach(checkVariable);

@@ -43,6 +43,7 @@ /**

create(context) {
const sourceCode = context.getSourceCode();
return {
"Program:exit"() {
const globalScope = context.getScope();
"Program:exit"(node) {
const globalScope = sourceCode.getScope(node);
const variable = globalScope.set.get("Function");

@@ -52,8 +53,8 @@

variable.references.forEach(ref => {
const node = ref.identifier;
const { parent } = node;
const idNode = ref.identifier;
const { parent } = idNode;
let evalNode;
if (parent) {
if (node === parent.callee && (
if (idNode === parent.callee && (
parent.type === "NewExpression" ||

@@ -65,3 +66,3 @@ parent.type === "CallExpression"

parent.type === "MemberExpression" &&
node === parent.object &&
idNode === parent.object &&
callMethods.has(astUtils.getStaticPropertyName(parent))

@@ -68,0 +69,0 @@ ) {

@@ -38,5 +38,7 @@ /**

const sourceCode = context.getSourceCode();
return {
"Program:exit"() {
const globalScope = context.getScope();
"Program:exit"(node) {
const globalScope = sourceCode.getScope(node);

@@ -48,8 +50,8 @@ for (const nonConstructorName of nonConstructorGlobalFunctionNames) {

variable.references.forEach(ref => {
const node = ref.identifier;
const parent = node.parent;
const idNode = ref.identifier;
const parent = idNode.parent;
if (parent && parent.type === "NewExpression" && parent.callee === node) {
if (parent && parent.type === "NewExpression" && parent.callee === idNode) {
context.report({
node,
node: idNode,
messageId: "noNewNonconstructor",

@@ -56,0 +58,0 @@ data: { name: nonConstructorName }

@@ -37,6 +37,9 @@ /**

create(context) {
const sourceCode = context.getSourceCode();
return {
NewExpression(node) {
const variable = astUtils.getVariableByName(
context.getScope(),
sourceCode.getScope(node),
node.callee.name

@@ -43,0 +46,0 @@ );

@@ -32,5 +32,7 @@ /**

const sourceCode = context.getSourceCode();
return {
"Program:exit"() {
const globalScope = context.getScope();
"Program:exit"(node) {
const globalScope = sourceCode.getScope(node);
const variable = globalScope.set.get("Symbol");

@@ -40,8 +42,8 @@

variable.references.forEach(ref => {
const node = ref.identifier;
const parent = node.parent;
const idNode = ref.identifier;
const parent = idNode.parent;
if (parent && parent.type === "NewExpression" && parent.callee === node) {
if (parent && parent.type === "NewExpression" && parent.callee === idNode) {
context.report({
node,
node: idNode,
messageId: "noNewSymbol"

@@ -48,0 +50,0 @@ });

@@ -12,3 +12,3 @@ /**

const { CALL, CONSTRUCT, ReferenceTracker } = require("eslint-utils");
const { CALL, CONSTRUCT, ReferenceTracker } = require("@eslint-community/eslint-utils");
const getPropertyName = require("./utils/ast-utils").getStaticPropertyName;

@@ -62,5 +62,7 @@

const sourceCode = context.getSourceCode();
return {
Program() {
const scope = context.getScope();
Program(node) {
const scope = sourceCode.getScope(node);
const tracker = new ReferenceTracker(scope);

@@ -76,8 +78,8 @@ const traceMap = {};

for (const { node, path } of tracker.iterateGlobalReferences(traceMap)) {
const name = getReportNodeName(node.callee);
for (const { node: refNode, path } of tracker.iterateGlobalReferences(traceMap)) {
const name = getReportNodeName(refNode.callee);
const ref = path[0];
const messageId = name === ref ? "unexpectedCall" : "unexpectedRefCall";
context.report({ node, messageId, data: { name, ref } });
context.report({ node: refNode, messageId, data: { name, ref } });
}

@@ -84,0 +86,0 @@ }

@@ -73,2 +73,3 @@ /**

const ignoredPropertyAssignmentsForRegex = context.options[0] && context.options[0].ignorePropertyModificationsForRegex || [];
const sourceCode = context.getSourceCode();

@@ -218,3 +219,3 @@ /**

function checkForFunction(node) {
context.getDeclaredVariables(node).forEach(checkVariable);
sourceCode.getDeclaredVariables(node).forEach(checkVariable);
}

@@ -221,0 +222,0 @@

@@ -12,3 +12,3 @@ /**

const { findVariable } = require("eslint-utils");
const { findVariable } = require("@eslint-community/eslint-utils");

@@ -88,2 +88,3 @@ //------------------------------------------------------------------------------

let funcInfo = null;
const sourceCode = context.getSourceCode();

@@ -104,3 +105,3 @@ /**

upper: funcInfo,
shouldCheck: functionTypesToCheck.has(node.type) && isPromiseExecutor(node, context.getScope())
shouldCheck: functionTypesToCheck.has(node.type) && isPromiseExecutor(node, sourceCode.getScope(node))
};

@@ -107,0 +108,0 @@

@@ -132,3 +132,3 @@ /**

function checkForBlock(node) {
const scope = context.getScope();
const scope = sourceCode.getScope(node);

@@ -145,4 +145,4 @@ /*

return {
Program() {
const scope = context.getScope();
Program(node) {
const scope = sourceCode.getScope(node);

@@ -149,0 +149,0 @@ findVariablesInScope(scope);

@@ -13,3 +13,3 @@ /**

const astUtils = require("./utils/ast-utils");
const regexpp = require("regexpp");
const regexpp = require("@eslint-community/regexpp");

@@ -58,2 +58,4 @@ //------------------------------------------------------------------------------

const sourceCode = context.getSourceCode();
/**

@@ -154,3 +156,3 @@ * Validate regular expression

function checkFunction(node) {
const scope = context.getScope();
const scope = sourceCode.getScope(node);
const regExpVar = astUtils.getVariableByName(scope, "RegExp");

@@ -157,0 +159,0 @@ const shadowed = regExpVar && regExpVar.defs.length > 0;

@@ -102,2 +102,3 @@ /**

const restrictDefaultExports = context.options[0] && context.options[0].restrictDefaultExports;
const sourceCode = context.getSourceCode();

@@ -180,3 +181,3 @@ /**

} else if (declaration.type === "VariableDeclaration") {
context.getDeclaredVariables(declaration)
sourceCode.getDeclaredVariables(declaration)
.map(v => v.defs.find(d => d.parent === declaration))

@@ -183,0 +184,0 @@ .map(d => d.name) // Identifier nodes

@@ -53,2 +53,4 @@ /**

const sourceCode = context.getSourceCode();
// If no globals are restricted, we don't need to do anything

@@ -103,4 +105,4 @@ if (context.options.length === 0) {

return {
Program() {
const scope = context.getScope();
Program(node) {
const scope = sourceCode.getScope(node);

@@ -107,0 +109,0 @@ // Report variables declared elsewhere (ex: variables defined as "global" by eslint)

@@ -13,3 +13,3 @@ /**

const astUtils = require("./utils/ast-utils");
const { findVariable } = require("eslint-utils");
const { findVariable } = require("@eslint-community/eslint-utils");

@@ -160,2 +160,3 @@ //------------------------------------------------------------------------------

let funcInfo = null;
const sourceCode = context.getSourceCode();

@@ -168,3 +169,3 @@ /**

function enterFunction(node) {
const outerScope = getOuterScope(context.getScope());
const outerScope = getOuterScope(sourceCode.getScope(node));

@@ -171,0 +172,0 @@ funcInfo = {

@@ -46,6 +46,7 @@ /**

const RESTRICTED = new Set(["undefined", "NaN", "Infinity", "arguments", "eval"]);
const sourceCode = context.getSourceCode();
return {
"VariableDeclaration, :function, CatchClause"(node) {
for (const variable of context.getDeclaredVariables(node)) {
for (const variable of sourceCode.getDeclaredVariables(node)) {
if (variable.defs.length > 0 && RESTRICTED.has(variable.name) && !safelyShadowsUndefined(variable)) {

@@ -52,0 +53,0 @@ context.report({

@@ -70,2 +70,3 @@ /**

};
const sourceCode = context.getSourceCode();

@@ -322,4 +323,4 @@ /**

return {
"Program:exit"() {
const globalScope = context.getScope();
"Program:exit"(node) {
const globalScope = sourceCode.getScope(node);
const stack = globalScope.childScopes.slice();

@@ -326,0 +327,0 @@

@@ -42,3 +42,3 @@ /**

init = node.init && node.init.name,
scope = context.getScope(),
scope = sourceCode.getScope(node),
undefinedVar = astUtils.getVariableByName(scope, "undefined"),

@@ -45,0 +45,0 @@ shadowed = undefinedVar && undefinedVar.defs.length > 0,

@@ -57,6 +57,7 @@ /**

const considerTypeOf = options && options.typeof === true || false;
const sourceCode = context.getSourceCode();
return {
"Program:exit"(/* node */) {
const globalScope = context.getScope();
"Program:exit"(node) {
const globalScope = sourceCode.getScope(node);

@@ -63,0 +64,0 @@ globalScope.through.forEach(ref => {

@@ -31,2 +31,4 @@ /**

const sourceCode = context.getSourceCode();
/**

@@ -70,4 +72,4 @@ * Report an invalid "undefined" identifier node.

return {
"Program:exit"() {
const globalScope = context.getScope();
"Program:exit"(node) {
const globalScope = sourceCode.getScope(node);

@@ -74,0 +76,0 @@ const stack = [globalScope];

@@ -87,2 +87,3 @@ /**

const allowInObjectDestructuring = typeof options.allowInObjectDestructuring !== "undefined" ? options.allowInObjectDestructuring : true;
const sourceCode = context.getSourceCode();

@@ -217,3 +218,3 @@ //-------------------------------------------------------------------------

function checkForDanglingUnderscoreInVariableExpression(node) {
context.getDeclaredVariables(node).forEach(variable => {
sourceCode.getDeclaredVariables(node).forEach(variable => {
const definition = variable.defs.find(def => def.node === node);

@@ -220,0 +221,0 @@ const identifierNode = definition.name;

@@ -343,4 +343,4 @@ /**

return {
"Program:exit"() {
const queue = [context.getScope()];
"Program:exit"(node) {
const queue = [sourceCode.getScope(node)];

@@ -347,0 +347,0 @@ groupMap = new Map();

@@ -73,3 +73,4 @@ /**

allowTaggedTemplates = config.allowTaggedTemplates || false,
enforceForJSX = config.enforceForJSX || false;
enforceForJSX = config.enforceForJSX || false,
sourceCode = context.getSourceCode();

@@ -184,3 +185,3 @@ /**

ExpressionStatement(node) {
if (Checker.isDisallowed(node.expression) && !isDirective(node, context.getAncestors())) {
if (Checker.isDisallowed(node.expression) && !isDirective(node, sourceCode.getAncestors(node))) {
context.report({ node, messageId: "unusedExpression" });

@@ -187,0 +188,0 @@ }

@@ -558,3 +558,3 @@ /**

const def = variable.defs[0];
const params = context.getDeclaredVariables(def.node);
const params = sourceCode.getDeclaredVariables(def.node);
const posteriorParams = params.slice(params.indexOf(variable) + 1);

@@ -677,3 +677,3 @@

"Program:exit"(programNode) {
const unusedVars = collectUnusedVariables(context.getScope(), []);
const unusedVars = collectUnusedVariables(sourceCode.getScope(programNode), []);

@@ -680,0 +680,0 @@ for (let i = 0, l = unusedVars.length; i < l; ++i) {

@@ -261,2 +261,3 @@ /**

const options = parseOptions(context.options[0]);
const sourceCode = context.getSourceCode();

@@ -343,4 +344,4 @@ /**

return {
Program() {
checkReferencesInScope(context.getScope());
Program(node) {
checkReferencesInScope(sourceCode.getScope(node));
}

@@ -347,0 +348,0 @@ };

@@ -12,4 +12,4 @@ /**

const { CALL, CONSTRUCT, ReferenceTracker, getStringIfConstant } = require("eslint-utils");
const { RegExpParser, visitRegExpAST } = require("regexpp");
const { CALL, CONSTRUCT, ReferenceTracker, getStringIfConstant } = require("@eslint-community/eslint-utils");
const { RegExpParser, visitRegExpAST } = require("@eslint-community/regexpp");

@@ -86,2 +86,4 @@ //------------------------------------------------------------------------------

const sourceCode = context.getSourceCode();
/**

@@ -172,4 +174,4 @@ * Checks and reports useless backreferences in the given regular expression.

},
Program() {
const scope = context.getScope(),
Program(node) {
const scope = sourceCode.getScope(node),
tracker = new ReferenceTracker(scope),

@@ -183,4 +185,4 @@ traceMap = {

for (const { node } of tracker.iterateGlobalReferences(traceMap)) {
const [patternNode, flagsNode] = node.arguments,
for (const { node: refNode } of tracker.iterateGlobalReferences(traceMap)) {
const [patternNode, flagsNode] = refNode.arguments,
pattern = getStringIfConstant(patternNode, scope),

@@ -190,3 +192,3 @@ flags = getStringIfConstant(flagsNode, scope);

if (typeof pattern === "string") {
checkRegex(node, pattern, flags || "");
checkRegex(refNode, pattern, flags || "");
}

@@ -193,0 +195,0 @@ }

@@ -200,3 +200,3 @@ /**

// Makes and pushs a new scope information.
// Makes and pushes a new scope information.
onCodePathStart(codePath) {

@@ -203,0 +203,0 @@ scopeInfo = {

@@ -213,3 +213,3 @@ /**

}
const variables = context.getDeclaredVariables(declarator);
const variables = sourceCode.getDeclaredVariables(declarator);

@@ -272,3 +272,3 @@ return variables.some(hasReferenceInTDZ(declarator.init));

function canFix(node) {
const variables = context.getDeclaredVariables(node);
const variables = sourceCode.getDeclaredVariables(node);
const scopeNode = getScopeNode(node);

@@ -275,0 +275,0 @@

@@ -357,7 +357,8 @@ /**

* Also, this marks all `arguments` identifiers so that they can be detected later.
* @param {ASTNode} node The node representing the function.
* @returns {void}
*/
function enterFunction() {
function enterFunction(node) {
lexicalScopeStack.unshift(new Set());
context.getScope().variables.filter(variable => variable.name === "arguments").forEach(variable => {
sourceCode.getScope(node).variables.filter(variable => variable.name === "arguments").forEach(variable => {
variable.references.map(ref => ref.identifier).forEach(identifier => argumentsIdentifiers.add(identifier));

@@ -364,0 +365,0 @@ });

@@ -266,3 +266,3 @@ /**

// Skip recursive functions.
const nameVar = context.getDeclaredVariables(node)[0];
const nameVar = sourceCode.getDeclaredVariables(node)[0];

@@ -274,3 +274,3 @@ if (isFunctionName(nameVar) && nameVar.references.length > 0) {

// Skip if it's using arguments.
const variable = getVariableOfArguments(context.getScope());
const variable = getVariableOfArguments(sourceCode.getScope(node));

@@ -277,0 +277,0 @@ if (variable && variable.references.length > 0) {

@@ -496,3 +496,3 @@ /**

if (node.kind === "let" && !isInitOfForStatement(node)) {
variables.push(...context.getDeclaredVariables(node));
variables.push(...sourceCode.getDeclaredVariables(node));
}

@@ -499,0 +499,0 @@ }

@@ -13,3 +13,3 @@ /**

const astUtils = require("./utils/ast-utils");
const { CALL, ReferenceTracker } = require("eslint-utils");
const { CALL, ReferenceTracker } = require("@eslint-community/eslint-utils");

@@ -176,4 +176,4 @@ //------------------------------------------------------------------------------

return {
Program() {
const scope = context.getScope();
Program(node) {
const scope = sourceCode.getScope(node);
const tracker = new ReferenceTracker(scope);

@@ -186,4 +186,4 @@ const trackMap = {

for (const { node } of tracker.iterateGlobalReferences(trackMap)) {
report(node);
for (const { node: refNode } of tracker.iterateGlobalReferences(trackMap)) {
report(refNode);
}

@@ -190,0 +190,0 @@ }

@@ -17,4 +17,4 @@ /**

getStringIfConstant
} = require("eslint-utils");
const regexpp = require("regexpp");
} = require("@eslint-community/eslint-utils");
const regexpp = require("@eslint-community/regexpp");

@@ -155,4 +155,4 @@ //------------------------------------------------------------------------------

},
Program() {
const scope = context.getScope();
Program(node) {
const scope = sourceCode.getScope(node);
const tracker = new ReferenceTracker(scope);

@@ -166,8 +166,8 @@ const traceMap = {

for (const { node } of tracker.iterateGlobalReferences(traceMap)) {
const regex = getStringIfConstant(node.arguments[0]);
const flags = getStringIfConstant(node.arguments[1]);
for (const { node: refNode } of tracker.iterateGlobalReferences(traceMap)) {
const regex = getStringIfConstant(refNode.arguments[0]);
const flags = getStringIfConstant(refNode.arguments[1]);
if (regex) {
checkRegex(regex, node, node.arguments[0], flags && flags.includes("u"));
checkRegex(regex, refNode, refNode.arguments[0], flags && flags.includes("u"));
}

@@ -174,0 +174,0 @@ }

@@ -64,2 +64,5 @@ /**

create(context) {
const sourceCode = context.getSourceCode();
return {

@@ -76,3 +79,3 @@ CallExpression(node) {

// check `Object` scope
const scope = context.getScope();
const scope = sourceCode.getScope(node);
const variable = astUtils.getVariableByName(scope, "Object");

@@ -90,3 +93,2 @@

fix(fixer) {
const sourceCode = context.getSourceCode();

@@ -93,0 +95,0 @@ if (sourceCode.getCommentsInside(node.callee).length > 0) {

@@ -9,3 +9,3 @@ /**

const { CALL, ReferenceTracker } = require("eslint-utils");
const { CALL, ReferenceTracker } = require("@eslint-community/eslint-utils");
const {

@@ -269,4 +269,4 @@ isCommaToken,

return {
Program() {
const scope = context.getScope();
Program(node) {
const scope = sourceCode.getScope(node);
const tracker = new ReferenceTracker(scope);

@@ -280,18 +280,18 @@ const trackMap = {

// Iterate all calls of `Object.assign` (only of the global variable `Object`).
for (const { node } of tracker.iterateGlobalReferences(trackMap)) {
for (const { node: refNode } of tracker.iterateGlobalReferences(trackMap)) {
if (
node.arguments.length >= 1 &&
node.arguments[0].type === "ObjectExpression" &&
!hasArraySpread(node) &&
refNode.arguments.length >= 1 &&
refNode.arguments[0].type === "ObjectExpression" &&
!hasArraySpread(refNode) &&
!(
node.arguments.length > 1 &&
hasArgumentsWithAccessors(node)
refNode.arguments.length > 1 &&
hasArgumentsWithAccessors(refNode)
)
) {
const messageId = node.arguments.length === 1
const messageId = refNode.arguments.length === 1
? "useLiteralMessage"
: "useSpreadMessage";
const fix = defineFixer(node, sourceCode);
const fix = defineFixer(refNode, sourceCode);
context.report({ node, messageId, fix });
context.report({ node: refNode, messageId, fix });
}

@@ -298,0 +298,0 @@ }

@@ -44,2 +44,3 @@ /**

const ALLOW_EMPTY_REJECT = context.options.length && context.options[0].allowEmptyReject;
const sourceCode = context.getSourceCode();

@@ -104,3 +105,3 @@ //----------------------------------------------------------------------

) {
context.getDeclaredVariables(node.arguments[0])
sourceCode.getDeclaredVariables(node.arguments[0])

@@ -107,0 +108,0 @@ /*

@@ -13,5 +13,6 @@ /**

const astUtils = require("./utils/ast-utils");
const { CALL, CONSTRUCT, ReferenceTracker, findVariable } = require("eslint-utils");
const { RegExpValidator, visitRegExpAST, RegExpParser } = require("regexpp");
const { CALL, CONSTRUCT, ReferenceTracker, findVariable } = require("@eslint-community/eslint-utils");
const { RegExpValidator, visitRegExpAST, RegExpParser } = require("@eslint-community/regexpp");
const { canTokensBeAdjacent } = require("./utils/ast-utils");
const { REGEXPP_LATEST_ECMA_VERSION } = require("./utils/regular-expressions");

@@ -22,4 +23,2 @@ //------------------------------------------------------------------------------

const REGEXPP_LATEST_ECMA_VERSION = 2022;
/**

@@ -168,3 +167,3 @@ * Determines whether the given node is a string literal.

function isGlobalReference(node) {
const scope = context.getScope();
const scope = sourceCode.getScope(node);
const variable = findVariable(scope, node);

@@ -381,4 +380,4 @@

return {
Program() {
const scope = context.getScope();
Program(node) {
const scope = sourceCode.getScope(node);
const tracker = new ReferenceTracker(scope);

@@ -392,12 +391,12 @@ const traceMap = {

for (const { node } of tracker.iterateGlobalReferences(traceMap)) {
if (disallowRedundantWrapping && isUnnecessarilyWrappedRegexLiteral(node)) {
const regexNode = node.arguments[0];
for (const { node: refNode } of tracker.iterateGlobalReferences(traceMap)) {
if (disallowRedundantWrapping && isUnnecessarilyWrappedRegexLiteral(refNode)) {
const regexNode = refNode.arguments[0];
if (node.arguments.length === 2) {
if (refNode.arguments.length === 2) {
const suggests = [];
const argFlags = getStringValue(node.arguments[1]) || "";
const argFlags = getStringValue(refNode.arguments[1]) || "";
if (canFixTo(node, regexNode.regex.pattern, argFlags)) {
if (canFixTo(refNode, regexNode.regex.pattern, argFlags)) {
suggests.push({

@@ -415,3 +414,3 @@ messageId: "replaceWithLiteralAndFlags",

!areFlagsEqual(mergedFlags, argFlags) &&
canFixTo(node, regexNode.regex.pattern, mergedFlags)
canFixTo(refNode, regexNode.regex.pattern, mergedFlags)
) {

@@ -426,3 +425,3 @@ suggests.push({

context.report({
node,
node: refNode,
messageId: "unexpectedRedundantRegExpWithFlags",

@@ -435,3 +434,3 @@ suggest: suggests.map(({ flags, pattern, messageId }) => ({

fix(fixer) {
return fixer.replaceText(node, getSafeOutput(node, `/${pattern}/${flags}`));
return fixer.replaceText(refNode, getSafeOutput(refNode, `/${pattern}/${flags}`));
}

@@ -443,3 +442,3 @@ }))

if (canFixTo(node, regexNode.regex.pattern, regexNode.regex.flags)) {
if (canFixTo(refNode, regexNode.regex.pattern, regexNode.regex.flags)) {
outputs.push(sourceCode.getText(regexNode));

@@ -450,3 +449,3 @@ }

context.report({
node,
node: refNode,
messageId: "unexpectedRedundantRegExp",

@@ -457,4 +456,4 @@ suggest: outputs.map(output => ({

return fixer.replaceText(
node,
getSafeOutput(node, output)
refNode,
getSafeOutput(refNode, output)
);

@@ -465,12 +464,12 @@ }

}
} else if (hasOnlyStaticStringArguments(node)) {
let regexContent = getStringValue(node.arguments[0]);
} else if (hasOnlyStaticStringArguments(refNode)) {
let regexContent = getStringValue(refNode.arguments[0]);
let noFix = false;
let flags;
if (node.arguments[1]) {
flags = getStringValue(node.arguments[1]);
if (refNode.arguments[1]) {
flags = getStringValue(refNode.arguments[1]);
}
if (!canFixTo(node, regexContent, flags)) {
if (!canFixTo(refNode, regexContent, flags)) {
noFix = true;

@@ -509,3 +508,3 @@ }

context.report({
node,
node: refNode,
messageId: "unexpectedRegExp",

@@ -515,3 +514,3 @@ suggest: noFix ? [] : [{

fix(fixer) {
return fixer.replaceText(node, getSafeOutput(node, newRegExpValue));
return fixer.replaceText(refNode, getSafeOutput(refNode, newRegExpValue));
}

@@ -518,0 +517,0 @@ }]

@@ -82,2 +82,4 @@ /**

const sourceCode = context.getSourceCode();
/**

@@ -98,6 +100,7 @@ * Reports a given reference.

* Reports references of the implicit `arguments` variable if exist.
* @param {ASTNode} node The node representing the function.
* @returns {void}
*/
function checkForArguments() {
const argumentsVar = getVariableOfArguments(context.getScope());
function checkForArguments(node) {
const argumentsVar = getVariableOfArguments(sourceCode.getScope(node));

@@ -104,0 +107,0 @@ if (argumentsVar) {

@@ -107,2 +107,3 @@ /**

const mode = context.options[0] || MODE_ALWAYS;
const sourceCode = context.getSourceCode();

@@ -135,3 +136,2 @@ /**

fix(fixer) {
const sourceCode = context.getSourceCode();
const tokens = sourceCode.getTokens(node);

@@ -167,4 +167,4 @@ const lastToken = tokens[tokens.length - 1]; // Parenthesis.

return {
"Program:exit"() {
const scope = context.getScope();
"Program:exit"(node) {
const scope = sourceCode.getScope(node);
let variable;

@@ -176,6 +176,6 @@

variable.references.forEach(reference => {
const node = reference.identifier;
const idNode = reference.identifier;
if (astUtils.isCallee(node)) {
checkArguments(node.parent);
if (astUtils.isCallee(idNode)) {
checkArguments(idNode.parent);
}

@@ -189,8 +189,8 @@ });

variable.references.forEach(reference => {
const node = reference.identifier.parent;
const maybeCallee = node.parent.type === "ChainExpression"
? node.parent
: node;
const parentNode = reference.identifier.parent;
const maybeCallee = parentNode.parent.type === "ChainExpression"
? parentNode.parent
: parentNode;
if (isParseIntMethod(node) && astUtils.isCallee(maybeCallee)) {
if (isParseIntMethod(parentNode) && astUtils.isCallee(maybeCallee)) {
checkArguments(maybeCallee.parent);

@@ -197,0 +197,0 @@ }

@@ -207,4 +207,4 @@ /**

return {
onCodePathStart(codePath) {
const scope = context.getScope();
onCodePathStart(codePath, node) {
const scope = sourceCode.getScope(node);
const shouldVerify =

@@ -211,0 +211,0 @@ scope.type === "function" &&

@@ -17,3 +17,5 @@ /**

getStringIfConstant
} = require("eslint-utils");
} = require("@eslint-community/eslint-utils");
const astUtils = require("./utils/ast-utils.js");
const { isValidWithUnicodeFlag } = require("./utils/regular-expressions");

@@ -35,3 +37,6 @@ //------------------------------------------------------------------------------

hasSuggestions: true,
messages: {
addUFlag: "Add the 'u' flag.",
requireUFlag: "Use the 'u' flag."

@@ -44,2 +49,5 @@ },

create(context) {
const sourceCode = context.getSourceCode();
return {

@@ -50,8 +58,21 @@ "Literal[regex]"(node) {

if (!flags.includes("u")) {
context.report({ node, messageId: "requireUFlag" });
context.report({
messageId: "requireUFlag",
node,
suggest: isValidWithUnicodeFlag(context.languageOptions.ecmaVersion, node.regex.pattern)
? [
{
fix(fixer) {
return fixer.insertTextAfter(node, "u");
},
messageId: "addUFlag"
}
]
: null
});
}
},
Program() {
const scope = context.getScope();
Program(node) {
const scope = sourceCode.getScope(node);
const tracker = new ReferenceTracker(scope);

@@ -62,8 +83,47 @@ const trackMap = {

for (const { node } of tracker.iterateGlobalReferences(trackMap)) {
const flagsNode = node.arguments[1];
for (const { node: refNode } of tracker.iterateGlobalReferences(trackMap)) {
const [patternNode, flagsNode] = refNode.arguments;
if (patternNode && patternNode.type === "SpreadElement") {
continue;
}
const pattern = getStringIfConstant(patternNode, scope);
const flags = getStringIfConstant(flagsNode, scope);
if (!flagsNode || (typeof flags === "string" && !flags.includes("u"))) {
context.report({ node, messageId: "requireUFlag" });
context.report({
messageId: "requireUFlag",
node: refNode,
suggest: typeof pattern === "string" && isValidWithUnicodeFlag(context.languageOptions.ecmaVersion, pattern)
? [
{
fix(fixer) {
if (flagsNode) {
if ((flagsNode.type === "Literal" && typeof flagsNode.value === "string") || flagsNode.type === "TemplateLiteral") {
const flagsNodeText = sourceCode.getText(flagsNode);
return fixer.replaceText(flagsNode, [
flagsNodeText.slice(0, flagsNodeText.length - 1),
flagsNodeText.slice(flagsNodeText.length - 1)
].join("u"));
}
// We intentionally don't suggest concatenating + "u" to non-literals
return null;
}
const penultimateToken = sourceCode.getLastToken(refNode, { skip: 1 }); // skip closing parenthesis
return fixer.insertTextAfter(
penultimateToken,
astUtils.isCommaToken(penultimateToken)
? ' "u",'
: ', "u"'
);
},
messageId: "addUFlag"
}
]
: null
});
}

@@ -70,0 +130,0 @@ }

@@ -38,2 +38,4 @@ /**

const sourceCode = context.getSourceCode();
/**

@@ -55,4 +57,4 @@ * Reports if node does not conform the rule in case rule is set to

return {
"Program:exit"() {
const scope = context.getScope();
"Program:exit"(node) {
const scope = sourceCode.getScope(node);
const variable = astUtils.getVariableByName(scope, "Symbol");

@@ -62,6 +64,6 @@

variable.references.forEach(reference => {
const node = reference.identifier;
const idNode = reference.identifier;
if (astUtils.isCallee(node)) {
checkArgument(node.parent);
if (astUtils.isCallee(idNode)) {
checkArgument(idNode.parent);
}

@@ -68,0 +70,0 @@ });

@@ -47,3 +47,3 @@ /**

OPERATORS = new Set(["==", "===", "!=", "!=="]);
const sourceCode = context.getSourceCode();
const requireStringLiterals = context.options[0] && context.options[0].requireStringLiterals;

@@ -81,4 +81,4 @@

Program() {
globalScope = context.getScope();
Program(node) {
globalScope = sourceCode.getScope(node);
},

@@ -88,3 +88,3 @@

if (isTypeofExpression(node)) {
const parent = context.getAncestors().pop();
const parent = sourceCode.getAncestors(node).pop();

@@ -91,0 +91,0 @@ if (parent.type === "BinaryExpression" && OPERATORS.has(parent.operator)) {

@@ -13,3 +13,3 @@ /**

const astUtils = require("./utils/ast-utils");
const eslintUtils = require("eslint-utils");
const eslintUtils = require("@eslint-community/eslint-utils");

@@ -16,0 +16,0 @@ //----------------------------------------------------------------------

@@ -43,3 +43,3 @@ /**

const afterToken = sourceCode.getTokenAfter(node);
const ancestors = context.getAncestors();
const ancestors = sourceCode.getAncestors(node);
const grandparent = ancestors[ancestors.length - 1];

@@ -46,0 +46,0 @@

@@ -346,3 +346,3 @@ /**

isComparisonOperator(node.operator) &&
!(exceptRange && isRangeTest(context.getAncestors().pop()))
!(exceptRange && isRangeTest(sourceCode.getAncestors(node).pop()))
) {

@@ -349,0 +349,0 @@ context.report({

@@ -12,3 +12,3 @@ /**

const
{ isCommentToken } = require("eslint-utils"),
{ isCommentToken } = require("@eslint-community/eslint-utils"),
TokenStore = require("./token-store"),

@@ -19,2 +19,8 @@ astUtils = require("../shared/ast-utils"),

//------------------------------------------------------------------------------
// Type Definitions
//------------------------------------------------------------------------------
/** @typedef {import("eslint-scope").Variable} Variable */
//------------------------------------------------------------------------------
// Private

@@ -148,2 +154,4 @@ //------------------------------------------------------------------------------

const caches = Symbol("caches");
/**

@@ -182,2 +190,9 @@ * Represents parsed source code.

/**
* General purpose caching for the class.
*/
this[caches] = new Map([
["scopes", new WeakMap()]
]);
/**
* The flag to indicate that the source code has Unicode BOM.

@@ -595,4 +610,82 @@ * @type {boolean}

}
/**
* Gets the scope for the given node
* @param {ASTNode} currentNode The node to get the scope of
* @returns {eslint-scope.Scope} The scope information for this node
* @throws {TypeError} If the `currentNode` argument is missing.
*/
getScope(currentNode) {
if (!currentNode) {
throw new TypeError("Missing required argument: node.");
}
// check cache first
const cache = this[caches].get("scopes");
const cachedScope = cache.get(currentNode);
if (cachedScope) {
return cachedScope;
}
// On Program node, get the outermost scope to avoid return Node.js special function scope or ES modules scope.
const inner = currentNode.type !== "Program";
for (let node = currentNode; node; node = node.parent) {
const scope = this.scopeManager.acquire(node, inner);
if (scope) {
if (scope.type === "function-expression-name") {
cache.set(currentNode, scope.childScopes[0]);
return scope.childScopes[0];
}
cache.set(currentNode, scope);
return scope;
}
}
cache.set(currentNode, this.scopeManager.scopes[0]);
return this.scopeManager.scopes[0];
}
/**
* Gets all of the declared variables in the scope associated
* with `node`. This is a convenience method that passes through
* to the same method on the `scopeManager`.
* @param {ASTNode} node The node from which to retrieve the scope to check.
* @returns {Array<Variable>} An array of variable nodes representing
* the declared variables in the scope associated with `node`.
*/
getDeclaredVariables(node) {
return this.scopeManager.getDeclaredVariables(node);
}
/* eslint-disable class-methods-use-this -- node is owned by SourceCode */
/**
* Gets all the ancestors of a given node
* @param {ASTNode} node The node
* @returns {Array<ASTNode>} All the ancestor nodes in the AST, not including the provided node, starting
* from the root node at index 0 and going inwards to the parent node.
* @throws {TypeError} When `node` is missing.
*/
getAncestors(node) {
if (!node) {
throw new TypeError("Missing required argument: node.");
}
const ancestorsStartingAtParent = [];
for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) {
ancestorsStartingAtParent.push(ancestor);
}
return ancestorsStartingAtParent.reverse();
}
/* eslint-enable class-methods-use-this -- node is owned by SourceCode */
}
module.exports = SourceCode;

@@ -12,3 +12,3 @@ /**

const assert = require("assert");
const { isCommentToken } = require("eslint-utils");
const { isCommentToken } = require("@eslint-community/eslint-utils");
const cursors = require("./cursors");

@@ -15,0 +15,0 @@ const ForwardTokenCursor = require("./forward-token-cursor");

@@ -52,4 +52,9 @@ /**

const index = indexMap[startLoc - 1];
const token = (index >= 0 && index < tokens.length) ? tokens[index] : null;
const token = tokens[index];
// If the mapped index is out of bounds, the returned cursor index will point after the end of the tokens array.
if (!token) {
return tokens.length;
}
/*

@@ -59,3 +64,3 @@ * For the map of "comment's location -> token's index", it points the next token of a comment.

*/
if (token && token.range[0] >= startLoc) {
if (token.range[0] >= startLoc) {
return index;

@@ -82,4 +87,9 @@ }

const index = indexMap[endLoc - 1];
const token = (index >= 0 && index < tokens.length) ? tokens[index] : null;
const token = tokens[index];
// If the mapped index is out of bounds, the returned cursor index will point before the end of the tokens array.
if (!token) {
return tokens.length - 1;
}
/*

@@ -89,3 +99,3 @@ * For the map of "comment's location -> token's index", it points the next token of a comment.

*/
if (token && token.range[1] > endLoc) {
if (token.range[1] > endLoc) {
return index - 1;

@@ -92,0 +102,0 @@ }

@@ -13,4 +13,4 @@ "use strict";

If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://eslint.org/chat/help
If you think you already have a configuration file or if you need more help, please stop by the ESLint Discord server: https://eslint.org/chat
`.trimStart();
};
{
"name": "eslint",
"version": "8.33.0",
"version": "8.38.0",
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",

@@ -40,2 +40,6 @@ "description": "An AST-based pattern checker for JavaScript.",

"*.md": "markdownlint --fix",
"lib/rules/*.js": [
"node tools/update-eslint-all.js",
"git add packages/js/src/configs/eslint-all.js"
],
"docs/src/rules/*.md": [

@@ -60,3 +64,6 @@ "node tools/fetch-docs-links.js",

"dependencies": {
"@eslint/eslintrc": "^1.4.1",
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.2",
"@eslint/js": "8.38.0",
"@humanwhocodes/config-array": "^0.11.8",

@@ -72,6 +79,5 @@ "@humanwhocodes/module-importer": "^1.0.1",

"eslint-scope": "^7.1.1",
"eslint-utils": "^3.0.0",
"eslint-visitor-keys": "^3.3.0",
"espree": "^9.4.0",
"esquery": "^1.4.0",
"eslint-visitor-keys": "^3.4.0",
"espree": "^9.5.1",
"esquery": "^1.4.2",
"esutils": "^2.0.2",

@@ -97,3 +103,2 @@ "fast-deep-equal": "^3.1.3",

"optionator": "^0.9.1",
"regexpp": "^3.2.0",
"strip-ansi": "^6.0.1",

@@ -100,0 +105,0 @@ "strip-json-comments": "^3.1.0",

@@ -19,4 +19,3 @@ [![npm version](https://img.shields.io/npm/v/eslint.svg)](https://www.npmjs.com/package/eslint)

[Twitter](https://twitter.com/geteslint) |
[Mailing List](https://groups.google.com/group/eslint) |
[Chat Room](https://eslint.org/chat)
[Discord](https://eslint.org/chat)

@@ -133,3 +132,3 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code. In many ways, it is similar to JSLint and JSHint with a few exceptions:

Join our [Mailing List](https://groups.google.com/group/eslint) or [Chatroom](https://eslint.org/chat).
Open a [discussion](https://github.com/eslint/eslint/discussions) or stop by our [Discord server](https://eslint.org/chat).

@@ -218,7 +217,2 @@ ### Why doesn't ESLint lock dependency versions?

</td><td align="center" valign="top" width="11%">
<a href="https://github.com/btmills">
<img src="https://github.com/btmills.png?s=75" width="75" height="75"><br />
Brandon Mills
</a>
</td><td align="center" valign="top" width="11%">
<a href="https://github.com/mdjermanovic">

@@ -256,5 +250,5 @@ <img src="https://github.com/mdjermanovic.png?s=75" width="75" height="75"><br />

</td><td align="center" valign="top" width="11%">
<a href="https://github.com/SaraSoueidan">
<img src="https://github.com/SaraSoueidan.png?s=75" width="75" height="75"><br />
Sara Soueidan
<a href="https://github.com/fasttime">
<img src="https://github.com/fasttime.png?s=75" width="75" height="75"><br />
Francesco Trotta
</a>

@@ -300,4 +294,4 @@ </td><td align="center" valign="top" width="11%">

<p><a href="https://ridicorp.com/career/"><img src="https://images.opencollective.com/ridi-corporation/175dcf3/logo.png" alt="RIDI" height="96"></a> <a href="https://engineering.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a></p><h3>Silver Sponsors</h3>
<p><a href="https://sentry.io"><img src="https://avatars.githubusercontent.com/u/1396951?v=4" alt="Sentry" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a></p><h3>Bronze Sponsors</h3>
<p><a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" 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: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://transloadit.com/"><img src="https://avatars.githubusercontent.com/u/125754?v=4" alt="Transloadit" height="32"></a> <a href="https://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a> <a href="https://quickbookstoolhub.com"><img src="https://avatars.githubusercontent.com/u/95090305?u=e5bc398ef775c9ed19f955c675cdc1fb6abf01df&v=4" alt="QuickBooks Tool hub" height="32"></a></p>
<p><a href="https://sentry.io"><img src="https://avatars.githubusercontent.com/u/1396951?v=4" alt="Sentry" 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?v=4" alt="American Express" height="64"></a></p><h3>Bronze Sponsors</h3>
<p><a href="https://paydaysay.com/"><img src="https://images.opencollective.com/payday-say-organization/9cd2467/logo.png" alt="PayDay Say" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" 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: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://transloadit.com/"><img src="https://avatars.githubusercontent.com/u/125754?v=4" alt="Transloadit" height="32"></a> <a href="https://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a> <a href="https://quickbookstoolhub.com"><img src="https://avatars.githubusercontent.com/u/95090305?u=e5bc398ef775c9ed19f955c675cdc1fb6abf01df&v=4" alt="QuickBooks Tool hub" height="32"></a></p>
<!--sponsorsend-->

@@ -304,0 +298,0 @@

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc