Bump the npm group with 6 updates (#1902)

* Bump the npm group with 6 updates

Bumps the npm group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [@octokit/types](https://github.com/octokit/types.ts) | `11.1.0` | `12.0.0` |
| [@types/adm-zip](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/adm-zip) | `0.5.1` | `0.5.2` |
| [@types/semver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/semver) | `7.5.2` | `7.5.3` |
| [@types/sinon](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/sinon) | `10.0.16` | `10.0.17` |
| [eslint](https://github.com/eslint/eslint) | `8.49.0` | `8.50.0` |
| [eslint-import-resolver-typescript](https://github.com/import-js/eslint-import-resolver-typescript) | `3.6.0` | `3.6.1` |


Updates `@octokit/types` from 11.1.0 to 12.0.0
- [Release notes](https://github.com/octokit/types.ts/releases)
- [Commits](https://github.com/octokit/types.ts/compare/v11.1.0...v12.0.0)

Updates `@types/adm-zip` from 0.5.1 to 0.5.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/adm-zip)

Updates `@types/semver` from 7.5.2 to 7.5.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/semver)

Updates `@types/sinon` from 10.0.16 to 10.0.17
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/sinon)

Updates `eslint` from 8.49.0 to 8.50.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.49.0...v8.50.0)

Updates `eslint-import-resolver-typescript` from 3.6.0 to 3.6.1
- [Release notes](https://github.com/import-js/eslint-import-resolver-typescript/releases)
- [Changelog](https://github.com/import-js/eslint-import-resolver-typescript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/import-js/eslint-import-resolver-typescript/compare/v3.6.0...v3.6.1)

---
updated-dependencies:
- dependency-name: "@octokit/types"
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm
- dependency-name: "@types/adm-zip"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/semver"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: "@types/sinon"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
- dependency-name: eslint-import-resolver-typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update checked-in dependencies

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
dependabot[bot] 2023-09-26 10:34:03 -07:00 committed by GitHub
parent 4818fdd8ec
commit 27cb1e1de5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
80 changed files with 117979 additions and 1193 deletions

2
node_modules/eslint/README.md generated vendored
View file

@ -289,7 +289,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
<p><a href="#"><img src="https://images.opencollective.com/2021-frameworks-fund/logo.png" alt="Chrome Frameworks Fund" height="undefined"></a> <a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
<p><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> <a href="https://opensource.siemens.com"><img src="https://avatars.githubusercontent.com/u/624020?v=4" alt="Siemens" 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://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" 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://github.com/about"><img src="https://avatars.githubusercontent.com/u/9919?v=4" alt="GitHub" 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://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" 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-->
## Technology Sponsors

View file

@ -507,7 +507,7 @@ const eslintrcKeys = [
// Full schema
//-----------------------------------------------------------------------------
exports.flatConfigSchema = {
const flatConfigSchema = {
// eslintrc-style keys that should always error
...Object.fromEntries(eslintrcKeys.map(key => [key, createEslintrcErrorSchema(key)])),
@ -533,3 +533,13 @@ exports.flatConfigSchema = {
plugins: pluginsSchema,
rules: rulesSchema
};
//-----------------------------------------------------------------------------
// Exports
//-----------------------------------------------------------------------------
module.exports = {
flatConfigSchema,
assertIsRuleSeverity,
assertIsRuleOptions
};

View file

@ -42,7 +42,8 @@ const
ruleReplacements = require("../../conf/replacements.json");
const { getRuleFromConfig } = require("../config/flat-config-helpers");
const { FlatConfigArray } = require("../config/flat-config-array");
const { RuleValidator } = require("../config/rule-validator");
const { assertIsRuleOptions, assertIsRuleSeverity } = require("../config/flat-config-schema");
const debug = require("debug")("eslint:linter");
const MAX_AUTOFIX_PASSES = 10;
const DEFAULT_PARSER_NAME = "espree";
@ -50,7 +51,6 @@ const DEFAULT_ECMA_VERSION = 5;
const commentParser = new ConfigCommentParser();
const DEFAULT_ERROR_LOC = { start: { line: 1, column: 0 }, end: { line: 1, column: 1 } };
const parserSymbol = Symbol.for("eslint.RuleTester.parser");
const globals = require("../../conf/globals");
//------------------------------------------------------------------------------
// Typedefs
@ -145,29 +145,6 @@ function isEspree(parser) {
return !!(parser === espree || parser[parserSymbol] === espree);
}
/**
* Retrieves globals for the given ecmaVersion.
* @param {number} ecmaVersion The version to retrieve globals for.
* @returns {Object} The globals for the given ecmaVersion.
*/
function getGlobalsForEcmaVersion(ecmaVersion) {
switch (ecmaVersion) {
case 3:
return globals.es3;
case 5:
return globals.es5;
default:
if (ecmaVersion < 2015) {
return globals[`es${ecmaVersion + 2009}`];
}
return globals[`es${ecmaVersion}`];
}
}
/**
* Ensures that variables representing built-in properties of the Global Object,
* and any globals declared by special block comments, are present in the global
@ -361,13 +338,13 @@ function extractDirectiveComment(value) {
* Parses comments in file to extract file-specific config of rules, globals
* and environments and merges them with global config; also code blocks
* where reporting is disabled or enabled and merges them with reporting config.
* @param {ASTNode} ast The top node of the AST.
* @param {SourceCode} sourceCode The SourceCode object to get comments from.
* @param {function(string): {create: Function}} ruleMapper A map from rule IDs to defined rules
* @param {string|null} warnInlineConfig If a string then it should warn directive comments as disabled. The string value is the config name what the setting came from.
* @returns {{configuredRules: Object, enabledGlobals: {value:string,comment:Token}[], exportedVariables: Object, problems: LintMessage[], disableDirectives: DisableDirective[]}}
* A collection of the directive comments that were found, along with any problems that occurred when parsing
*/
function getDirectiveComments(ast, ruleMapper, warnInlineConfig) {
function getDirectiveComments(sourceCode, ruleMapper, warnInlineConfig) {
const configuredRules = {};
const enabledGlobals = Object.create(null);
const exportedVariables = {};
@ -377,7 +354,7 @@ function getDirectiveComments(ast, ruleMapper, warnInlineConfig) {
builtInRules: Rules
});
ast.comments.filter(token => token.type !== "Shebang").forEach(comment => {
sourceCode.getInlineConfigNodes().filter(token => token.type !== "Shebang").forEach(comment => {
const { directivePart, justificationPart } = extractDirectiveComment(comment.value);
const match = directivesPattern.exec(directivePart);
@ -511,6 +488,69 @@ function getDirectiveComments(ast, ruleMapper, warnInlineConfig) {
};
}
/**
* Parses comments in file to extract disable directives.
* @param {SourceCode} sourceCode The SourceCode object to get comments from.
* @param {function(string): {create: Function}} ruleMapper A map from rule IDs to defined rules
* @returns {{problems: LintMessage[], disableDirectives: DisableDirective[]}}
* A collection of the directive comments that were found, along with any problems that occurred when parsing
*/
function getDirectiveCommentsForFlatConfig(sourceCode, ruleMapper) {
const problems = [];
const disableDirectives = [];
sourceCode.getInlineConfigNodes().filter(token => token.type !== "Shebang").forEach(comment => {
const { directivePart, justificationPart } = extractDirectiveComment(comment.value);
const match = directivesPattern.exec(directivePart);
if (!match) {
return;
}
const directiveText = match[1];
const lineCommentSupported = /^eslint-disable-(next-)?line$/u.test(directiveText);
if (comment.type === "Line" && !lineCommentSupported) {
return;
}
if (directiveText === "eslint-disable-line" && comment.loc.start.line !== comment.loc.end.line) {
const message = `${directiveText} comment should not span multiple lines.`;
problems.push(createLintingProblem({
ruleId: null,
message,
loc: comment.loc
}));
return;
}
const directiveValue = directivePart.slice(match.index + directiveText.length);
switch (directiveText) {
case "eslint-disable":
case "eslint-enable":
case "eslint-disable-next-line":
case "eslint-disable-line": {
const directiveType = directiveText.slice("eslint-".length);
const options = { commentToken: comment, type: directiveType, value: directiveValue, justification: justificationPart, ruleMapper };
const { directives, directiveProblems } = createDisableDirectives(options);
disableDirectives.push(...directives);
problems.push(...directiveProblems);
break;
}
// no default
}
});
return {
problems,
disableDirectives
};
}
/**
* Normalize ECMAScript version from the initial config
* @param {Parser} parser The parser which uses this options.
@ -1313,7 +1353,7 @@ class Linter {
const sourceCode = slots.lastSourceCode;
const commentDirectives = options.allowInlineConfig
? getDirectiveComments(sourceCode.ast, ruleId => getRule(slots, ruleId), options.warnInlineConfig)
? getDirectiveComments(sourceCode, ruleId => getRule(slots, ruleId), options.warnInlineConfig)
: { configuredRules: {}, enabledGlobals: {}, exportedVariables: {}, problems: [], disableDirectives: [] };
// augment global scope with declared global variables
@ -1324,7 +1364,6 @@ class Linter {
);
const configuredRules = Object.assign({}, config.rules, commentDirectives.configuredRules);
let lintingProblems;
try {
@ -1540,19 +1579,6 @@ class Linter {
languageOptions.ecmaVersion
);
/*
* add configured globals and language globals
*
* using Object.assign instead of object spread for performance reasons
* https://github.com/eslint/eslint/issues/16302
*/
const configuredGlobals = Object.assign(
{},
getGlobalsForEcmaVersion(languageOptions.ecmaVersion),
languageOptions.sourceType === "commonjs" ? globals.commonjs : void 0,
languageOptions.globals
);
// double check that there is a parser to avoid mysterious error messages
if (!languageOptions.parser) {
throw new TypeError(`No parser specified for ${options.filename}`);
@ -1608,25 +1634,113 @@ class Linter {
}
const sourceCode = slots.lastSourceCode;
const commentDirectives = options.allowInlineConfig
? getDirectiveComments(
sourceCode.ast,
ruleId => getRuleFromConfig(ruleId, config),
options.warnInlineConfig
/*
* Make adjustments based on the language options. For JavaScript,
* this is primarily about adding variables into the global scope
* to account for ecmaVersion and configured globals.
*/
sourceCode.applyLanguageOptions(languageOptions);
const mergedInlineConfig = {
rules: {}
};
const inlineConfigProblems = [];
/*
* Inline config can be either enabled or disabled. If disabled, it's possible
* to detect the inline config and emit a warning (though this is not required).
* So we first check to see if inline config is allowed at all, and if so, we
* need to check if it's a warning or not.
*/
if (options.allowInlineConfig) {
// if inline config should warn then add the warnings
if (options.warnInlineConfig) {
sourceCode.getInlineConfigNodes().forEach(node => {
inlineConfigProblems.push(createLintingProblem({
ruleId: null,
message: `'${sourceCode.text.slice(node.range[0], node.range[1])}' has no effect because you have 'noInlineConfig' setting in ${options.warnInlineConfig}.`,
loc: node.loc,
severity: 1
}));
});
} else {
const inlineConfigResult = sourceCode.applyInlineConfig();
inlineConfigProblems.push(
...inlineConfigResult.problems
.map(createLintingProblem)
.map(problem => {
problem.fatal = true;
return problem;
})
);
// next we need to verify information about the specified rules
const ruleValidator = new RuleValidator();
for (const { config: inlineConfig, node } of inlineConfigResult.configs) {
Object.keys(inlineConfig.rules).forEach(ruleId => {
const rule = getRuleFromConfig(ruleId, config);
const ruleValue = inlineConfig.rules[ruleId];
if (!rule) {
inlineConfigProblems.push(createLintingProblem({ ruleId, loc: node.loc }));
return;
}
try {
const ruleOptions = Array.isArray(ruleValue) ? ruleValue : [ruleValue];
assertIsRuleOptions(ruleId, ruleValue);
assertIsRuleSeverity(ruleId, ruleOptions[0]);
ruleValidator.validate({
plugins: config.plugins,
rules: {
[ruleId]: ruleOptions
}
});
mergedInlineConfig.rules[ruleId] = ruleValue;
} catch (err) {
let baseMessage = err.message.slice(
err.message.startsWith("Key \"rules\":")
? err.message.indexOf(":", 12) + 1
: err.message.indexOf(":") + 1
).trim();
if (err.messageTemplate) {
baseMessage += ` You passed "${ruleValue}".`;
}
inlineConfigProblems.push(createLintingProblem({
ruleId,
message: `Inline configuration for rule "${ruleId}" is invalid:\n\t${baseMessage}\n`,
loc: node.loc
}));
}
});
}
}
}
const commentDirectives = options.allowInlineConfig && !options.warnInlineConfig
? getDirectiveCommentsForFlatConfig(
sourceCode,
ruleId => getRuleFromConfig(ruleId, config)
)
: { configuredRules: {}, enabledGlobals: {}, exportedVariables: {}, problems: [], disableDirectives: [] };
// augment global scope with declared global variables
addDeclaredGlobals(
sourceCode.scopeManager.scopes[0],
configuredGlobals,
{ exportedVariables: commentDirectives.exportedVariables, enabledGlobals: commentDirectives.enabledGlobals }
);
const configuredRules = Object.assign({}, config.rules, commentDirectives.configuredRules);
: { problems: [], disableDirectives: [] };
const configuredRules = Object.assign({}, config.rules, mergedInlineConfig.rules);
let lintingProblems;
sourceCode.finalize();
try {
lintingProblems = runRules(
sourceCode,
@ -1667,6 +1781,7 @@ class Linter {
disableFixes: options.disableFixes,
problems: lintingProblems
.concat(commentDirectives.problems)
.concat(inlineConfigProblems)
.sort((problemA, problemB) => problemA.line - problemB.line || problemA.column - problemB.column),
reportUnusedDisableDirectives: options.reportUnusedDisableDirectives
});

View file

@ -133,6 +133,15 @@ const suggestionObjectParameters = new Set([
]);
const friendlySuggestionObjectParameterList = `[${[...suggestionObjectParameters].map(key => `'${key}'`).join(", ")}]`;
const forbiddenMethods = [
"applyInlineConfig",
"applyLanguageOptions",
"finalize"
];
/** @type {Map<string,WeakSet>} */
const forbiddenMethodCalls = new Map(forbiddenMethods.map(methodName => ([methodName, new WeakSet()])));
const hasOwnProperty = Function.call.bind(Object.hasOwnProperty);
/**
@ -291,6 +300,34 @@ function emitCodePathCurrentSegmentsWarning(ruleName) {
}
}
/**
* Function to replace forbidden `SourceCode` methods. Allows just one call per method.
* @param {string} methodName The name of the method to forbid.
* @param {Function} prototype The prototype with the original method to call.
* @returns {Function} The function that throws the error.
*/
function throwForbiddenMethodError(methodName, prototype) {
const original = prototype[methodName];
return function(...args) {
const called = forbiddenMethodCalls.get(methodName);
/* eslint-disable no-invalid-this -- needed to operate as a method. */
if (!called.has(this)) {
called.add(this);
return original.apply(this, args);
}
/* eslint-enable no-invalid-this -- not needed past this point */
throw new Error(
`\`SourceCode#${methodName}()\` cannot be called inside a rule.`
);
};
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
@ -498,6 +535,7 @@ class FlatRuleTester {
}
const baseConfig = [
{ files: ["**"] }, // Make sure the default config matches for all files
{
plugins: {
@ -679,11 +717,6 @@ class FlatRuleTester {
}
}
// Verify the code.
const { getComments } = SourceCode.prototype;
const originalCurrentSegments = Object.getOwnPropertyDescriptor(CodePath.prototype, "currentSegments");
let messages;
// check for validation errors
try {
configs.normalizeSync();
@ -693,6 +726,11 @@ class FlatRuleTester {
throw error;
}
// Verify the code.
const { getComments, applyLanguageOptions, applyInlineConfig, finalize } = SourceCode.prototype;
const originalCurrentSegments = Object.getOwnPropertyDescriptor(CodePath.prototype, "currentSegments");
let messages;
try {
SourceCode.prototype.getComments = getCommentsDeprecation;
Object.defineProperty(CodePath.prototype, "currentSegments", {
@ -702,10 +740,17 @@ class FlatRuleTester {
}
});
forbiddenMethods.forEach(methodName => {
SourceCode.prototype[methodName] = throwForbiddenMethodError(methodName, SourceCode.prototype);
});
messages = linter.verify(code, configs, filename);
} finally {
SourceCode.prototype.getComments = getComments;
Object.defineProperty(CodePath.prototype, "currentSegments", originalCurrentSegments);
SourceCode.prototype.applyInlineConfig = applyInlineConfig;
SourceCode.prototype.applyLanguageOptions = applyLanguageOptions;
SourceCode.prototype.finalize = finalize;
}

View file

@ -163,6 +163,12 @@ const suggestionObjectParameters = new Set([
]);
const friendlySuggestionObjectParameterList = `[${[...suggestionObjectParameters].map(key => `'${key}'`).join(", ")}]`;
const forbiddenMethods = [
"applyInlineConfig",
"applyLanguageOptions",
"finalize"
];
const hasOwnProperty = Function.call.bind(Object.hasOwnProperty);
const DEPRECATED_SOURCECODE_PASSTHROUGHS = {
@ -186,7 +192,12 @@ const DEPRECATED_SOURCECODE_PASSTHROUGHS = {
getTokens: "getTokens",
getTokensAfter: "getTokensAfter",
getTokensBefore: "getTokensBefore",
getTokensBetween: "getTokensBetween"
getTokensBetween: "getTokensBetween",
getScope: "getScope",
getAncestors: "getAncestors",
getDeclaredVariables: "getDeclaredVariables",
markVariableAsUsed: "markVariableAsUsed"
};
/**
@ -330,6 +341,19 @@ function getCommentsDeprecation() {
);
}
/**
* Function to replace forbidden `SourceCode` methods.
* @param {string} methodName The name of the method to forbid.
* @returns {Function} The function that throws the error.
*/
function throwForbiddenMethodError(methodName) {
return () => {
throw new Error(
`\`SourceCode#${methodName}()\` cannot be called inside a rule.`
);
};
}
/**
* Emit a deprecation warning if function-style format is being used.
* @param {string} ruleName Name of the rule.
@ -391,6 +415,22 @@ function emitCodePathCurrentSegmentsWarning(ruleName) {
}
}
/**
* Emit a deprecation warning if `context.parserServices` is used.
* @param {string} ruleName Name of the rule.
* @returns {void}
*/
function emitParserServicesWarning(ruleName) {
if (!emitParserServicesWarning[`warned-${ruleName}`]) {
emitParserServicesWarning[`warned-${ruleName}`] = true;
process.emitWarning(
`"${ruleName}" rule is using \`context.parserServices\`, which is deprecated and will be removed in ESLint v9. Please use \`sourceCode.parserServices\` instead.`,
"DeprecationWarning"
);
}
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
@ -622,26 +662,37 @@ class RuleTester {
freezeDeeply(context.settings);
freezeDeeply(context.parserOptions);
const newContext = Object.freeze(
Object.create(
context,
Object.fromEntries(Object.keys(DEPRECATED_SOURCECODE_PASSTHROUGHS).map(methodName => [
methodName,
{
value(...args) {
// wrap all deprecated methods
const newContext = Object.create(
context,
Object.fromEntries(Object.keys(DEPRECATED_SOURCECODE_PASSTHROUGHS).map(methodName => [
methodName,
{
value(...args) {
// emit deprecation warning
emitDeprecatedContextMethodWarning(ruleName, methodName);
// emit deprecation warning
emitDeprecatedContextMethodWarning(ruleName, methodName);
// call the original method
return context[methodName].call(this, ...args);
},
enumerable: true
}
]))
)
// call the original method
return context[methodName].call(this, ...args);
},
enumerable: true
}
]))
);
// emit warning about context.parserServices
const parserServices = context.parserServices;
Object.defineProperty(newContext, "parserServices", {
get() {
emitParserServicesWarning(ruleName);
return parserServices;
}
});
Object.freeze(newContext);
return (typeof rule === "function" ? rule : rule.create)(newContext);
}
}));
@ -761,7 +812,7 @@ class RuleTester {
validate(config, "rule-tester", id => (id === ruleName ? rule : null));
// Verify the code.
const { getComments } = SourceCode.prototype;
const { getComments, applyLanguageOptions, applyInlineConfig, finalize } = SourceCode.prototype;
const originalCurrentSegments = Object.getOwnPropertyDescriptor(CodePath.prototype, "currentSegments");
let messages;
@ -774,10 +825,17 @@ class RuleTester {
}
});
forbiddenMethods.forEach(methodName => {
SourceCode.prototype[methodName] = throwForbiddenMethodError(methodName);
});
messages = linter.verify(code, config, filename);
} finally {
SourceCode.prototype.getComments = getComments;
Object.defineProperty(CodePath.prototype, "currentSegments", originalCurrentSegments);
SourceCode.prototype.applyInlineConfig = applyInlineConfig;
SourceCode.prototype.applyLanguageOptions = applyLanguageOptions;
SourceCode.prototype.finalize = finalize;
}
const fatalErrorMessage = messages.find(m => m.fatal);

View file

@ -136,6 +136,76 @@ function getArrayMethodName(node) {
return null;
}
/**
* Checks if the given node is a void expression.
* @param {ASTNode} node The node to check.
* @returns {boolean} - `true` if the node is a void expression
*/
function isExpressionVoid(node) {
return node.type === "UnaryExpression" && node.operator === "void";
}
/**
* Fixes the linting error by prepending "void " to the given node
* @param {Object} sourceCode context given by context.sourceCode
* @param {ASTNode} node The node to fix.
* @param {Object} fixer The fixer object provided by ESLint.
* @returns {Array<Object>} - An array of fix objects to apply to the node.
*/
function voidPrependFixer(sourceCode, node, fixer) {
const requiresParens =
// prepending `void ` will fail if the node has a lower precedence than void
astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression", operator: "void" }) &&
// check if there are parentheses around the node to avoid redundant parentheses
!astUtils.isParenthesised(sourceCode, node);
// avoid parentheses issues
const returnOrArrowToken = sourceCode.getTokenBefore(
node,
node.parent.type === "ArrowFunctionExpression"
? astUtils.isArrowToken
// isReturnToken
: token => token.type === "Keyword" && token.value === "return"
);
const firstToken = sourceCode.getTokenAfter(returnOrArrowToken);
const prependSpace =
// is return token, as => allows void to be adjacent
returnOrArrowToken.value === "return" &&
// If two tokens (return and "(") are adjacent
returnOrArrowToken.range[1] === firstToken.range[0];
return [
fixer.insertTextBefore(firstToken, `${prependSpace ? " " : ""}void ${requiresParens ? "(" : ""}`),
fixer.insertTextAfter(node, requiresParens ? ")" : "")
];
}
/**
* Fixes the linting error by `wrapping {}` around the given node's body.
* @param {Object} sourceCode context given by context.sourceCode
* @param {ASTNode} node The node to fix.
* @param {Object} fixer The fixer object provided by ESLint.
* @returns {Array<Object>} - An array of fix objects to apply to the node.
*/
function curlyWrapFixer(sourceCode, node, fixer) {
const arrowToken = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken);
const firstToken = sourceCode.getTokenAfter(arrowToken);
const lastToken = sourceCode.getLastToken(node);
return [
fixer.insertTextBefore(firstToken, "{"),
fixer.insertTextAfter(lastToken, "}")
];
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
@ -151,6 +221,9 @@ module.exports = {
url: "https://eslint.org/docs/latest/rules/array-callback-return"
},
// eslint-disable-next-line eslint-plugin/require-meta-has-suggestions -- false positive
hasSuggestions: true,
schema: [
{
type: "object",
@ -162,6 +235,10 @@ module.exports = {
checkForEach: {
type: "boolean",
default: false
},
allowVoid: {
type: "boolean",
default: false
}
},
additionalProperties: false
@ -172,13 +249,15 @@ module.exports = {
expectedAtEnd: "{{arrayMethodName}}() expects a value to be returned at the end of {{name}}.",
expectedInside: "{{arrayMethodName}}() expects a return value from {{name}}.",
expectedReturnValue: "{{arrayMethodName}}() expects a return value from {{name}}.",
expectedNoReturnValue: "{{arrayMethodName}}() expects no useless return value from {{name}}."
expectedNoReturnValue: "{{arrayMethodName}}() expects no useless return value from {{name}}.",
wrapBraces: "Wrap the expression in `{}`.",
prependVoid: "Prepend `void` to the expression."
}
},
create(context) {
const options = context.options[0] || { allowImplicit: false, checkForEach: false };
const options = context.options[0] || { allowImplicit: false, checkForEach: false, allowVoid: false };
const sourceCode = context.sourceCode;
let funcInfo = {
@ -205,26 +284,56 @@ module.exports = {
return;
}
let messageId = null;
const messageAndSuggestions = { messageId: "", suggest: [] };
if (funcInfo.arrayMethodName === "forEach") {
if (options.checkForEach && node.type === "ArrowFunctionExpression" && node.expression) {
messageId = "expectedNoReturnValue";
if (options.allowVoid) {
if (isExpressionVoid(node.body)) {
return;
}
messageAndSuggestions.messageId = "expectedNoReturnValue";
messageAndSuggestions.suggest = [
{
messageId: "wrapBraces",
fix(fixer) {
return curlyWrapFixer(sourceCode, node, fixer);
}
},
{
messageId: "prependVoid",
fix(fixer) {
return voidPrependFixer(sourceCode, node.body, fixer);
}
}
];
} else {
messageAndSuggestions.messageId = "expectedNoReturnValue";
messageAndSuggestions.suggest = [{
messageId: "wrapBraces",
fix(fixer) {
return curlyWrapFixer(sourceCode, node, fixer);
}
}];
}
}
} else {
if (node.body.type === "BlockStatement" && isAnySegmentReachable(funcInfo.currentSegments)) {
messageId = funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside";
messageAndSuggestions.messageId = funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside";
}
}
if (messageId) {
if (messageAndSuggestions.messageId) {
const name = astUtils.getFunctionNameWithKind(node);
context.report({
node,
loc: astUtils.getFunctionHeadLoc(node, sourceCode),
messageId,
data: { name, arrayMethodName: fullMethodName(funcInfo.arrayMethodName) }
messageId: messageAndSuggestions.messageId,
data: { name, arrayMethodName: fullMethodName(funcInfo.arrayMethodName) },
suggest: messageAndSuggestions.suggest.length !== 0 ? messageAndSuggestions.suggest : null
});
}
}
@ -285,30 +394,46 @@ module.exports = {
funcInfo.hasReturn = true;
let messageId = null;
const messageAndSuggestions = { messageId: "", suggest: [] };
if (funcInfo.arrayMethodName === "forEach") {
// if checkForEach: true, returning a value at any path inside a forEach is not allowed
if (options.checkForEach && node.argument) {
messageId = "expectedNoReturnValue";
if (options.allowVoid) {
if (isExpressionVoid(node.argument)) {
return;
}
messageAndSuggestions.messageId = "expectedNoReturnValue";
messageAndSuggestions.suggest = [{
messageId: "prependVoid",
fix(fixer) {
return voidPrependFixer(sourceCode, node.argument, fixer);
}
}];
} else {
messageAndSuggestions.messageId = "expectedNoReturnValue";
}
}
} else {
// if allowImplicit: false, should also check node.argument
if (!options.allowImplicit && !node.argument) {
messageId = "expectedReturnValue";
messageAndSuggestions.messageId = "expectedReturnValue";
}
}
if (messageId) {
if (messageAndSuggestions.messageId) {
context.report({
node,
messageId,
messageId: messageAndSuggestions.messageId,
data: {
name: astUtils.getFunctionNameWithKind(funcInfo.node),
arrayMethodName: fullMethodName(funcInfo.arrayMethodName)
}
},
suggest: messageAndSuggestions.suggest.length !== 0 ? messageAndSuggestions.suggest : null
});
}
},

View file

@ -175,6 +175,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
"no-new-wrappers": () => require("./no-new-wrappers"),
"no-nonoctal-decimal-escape": () => require("./no-nonoctal-decimal-escape"),
"no-obj-calls": () => require("./no-obj-calls"),
"no-object-constructor": () => require("./no-object-constructor"),
"no-octal": () => require("./no-octal"),
"no-octal-escape": () => require("./no-octal-escape"),
"no-param-reassign": () => require("./no-param-reassign"),

View file

@ -13,27 +13,34 @@ const { isValidWithUnicodeFlag } = require("./utils/regular-expressions");
// Helpers
//------------------------------------------------------------------------------
/**
* @typedef {import('@eslint-community/regexpp').AST.Character} Character
* @typedef {import('@eslint-community/regexpp').AST.CharacterClassElement} CharacterClassElement
*/
/**
* Iterate character sequences of a given nodes.
*
* CharacterClassRange syntax can steal a part of character sequence,
* so this function reverts CharacterClassRange syntax and restore the sequence.
* @param {import('@eslint-community/regexpp').AST.CharacterClassElement[]} nodes The node list to iterate character sequences.
* @returns {IterableIterator<number[]>} The list of character sequences.
* @param {CharacterClassElement[]} nodes The node list to iterate character sequences.
* @returns {IterableIterator<Character[]>} The list of character sequences.
*/
function *iterateCharacterSequence(nodes) {
/** @type {Character[]} */
let seq = [];
for (const node of nodes) {
switch (node.type) {
case "Character":
seq.push(node.value);
seq.push(node);
break;
case "CharacterClassRange":
seq.push(node.min.value);
seq.push(node.min);
yield seq;
seq = [node.max.value];
seq = [node.max];
break;
case "CharacterSet":
@ -55,32 +62,74 @@ function *iterateCharacterSequence(nodes) {
}
}
/**
* Checks whether the given character node is a Unicode code point escape or not.
* @param {Character} char the character node to check.
* @returns {boolean} `true` if the character node is a Unicode code point escape.
*/
function isUnicodeCodePointEscape(char) {
return /^\\u\{[\da-f]+\}$/iu.test(char.raw);
}
/**
* Each function returns `true` if it detects that kind of problem.
* @type {Record<string, (chars: Character[]) => boolean>}
*/
const hasCharacterSequence = {
surrogatePairWithoutUFlag(chars) {
return chars.some((c, i) => i !== 0 && isSurrogatePair(chars[i - 1], c));
return chars.some((c, i) => {
if (i === 0) {
return false;
}
const c1 = chars[i - 1];
return (
isSurrogatePair(c1.value, c.value) &&
!isUnicodeCodePointEscape(c1) &&
!isUnicodeCodePointEscape(c)
);
});
},
surrogatePair(chars) {
return chars.some((c, i) => {
if (i === 0) {
return false;
}
const c1 = chars[i - 1];
return (
isSurrogatePair(c1.value, c.value) &&
(
isUnicodeCodePointEscape(c1) ||
isUnicodeCodePointEscape(c)
)
);
});
},
combiningClass(chars) {
return chars.some((c, i) => (
i !== 0 &&
isCombiningCharacter(c) &&
!isCombiningCharacter(chars[i - 1])
isCombiningCharacter(c.value) &&
!isCombiningCharacter(chars[i - 1].value)
));
},
emojiModifier(chars) {
return chars.some((c, i) => (
i !== 0 &&
isEmojiModifier(c) &&
!isEmojiModifier(chars[i - 1])
isEmojiModifier(c.value) &&
!isEmojiModifier(chars[i - 1].value)
));
},
regionalIndicatorSymbol(chars) {
return chars.some((c, i) => (
i !== 0 &&
isRegionalIndicatorSymbol(c) &&
isRegionalIndicatorSymbol(chars[i - 1])
isRegionalIndicatorSymbol(c.value) &&
isRegionalIndicatorSymbol(chars[i - 1].value)
));
},
@ -90,9 +139,9 @@ const hasCharacterSequence = {
return chars.some((c, i) => (
i !== 0 &&
i !== lastIndex &&
c === 0x200d &&
chars[i - 1] !== 0x200d &&
chars[i + 1] !== 0x200d
c.value === 0x200d &&
chars[i - 1].value !== 0x200d &&
chars[i + 1].value !== 0x200d
));
}
};
@ -120,6 +169,7 @@ module.exports = {
messages: {
surrogatePairWithoutUFlag: "Unexpected surrogate pair in character class. Use 'u' flag.",
surrogatePair: "Unexpected surrogate pair in character class.",
combiningClass: "Unexpected combined character in character class.",
emojiModifier: "Unexpected modified Emoji in character class.",
regionalIndicatorSymbol: "Unexpected national flag in character class.",

View file

@ -1,6 +1,7 @@
/**
* @fileoverview A rule to disallow calls to the Object constructor
* @author Matt DuVall <http://www.mattduvall.com/>
* @deprecated in ESLint v8.50.0
*/
"use strict";
@ -26,6 +27,12 @@ module.exports = {
url: "https://eslint.org/docs/latest/rules/no-new-object"
},
deprecated: true,
replacedBy: [
"no-object-constructor"
],
schema: [],
messages: {

118
node_modules/eslint/lib/rules/no-object-constructor.js generated vendored Normal file
View file

@ -0,0 +1,118 @@
/**
* @fileoverview Rule to disallow calls to the `Object` constructor without an argument
* @author Francesco Trotta
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const { getVariableByName, isArrowToken } = require("./utils/ast-utils");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Tests if a node appears at the beginning of an ancestor ExpressionStatement node.
* @param {ASTNode} node The node to check.
* @returns {boolean} Whether the node appears at the beginning of an ancestor ExpressionStatement node.
*/
function isStartOfExpressionStatement(node) {
const start = node.range[0];
let ancestor = node;
while ((ancestor = ancestor.parent) && ancestor.range[0] === start) {
if (ancestor.type === "ExpressionStatement") {
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('../shared/types').Rule} */
module.exports = {
meta: {
type: "suggestion",
docs: {
description: "Disallow calls to the `Object` constructor without an argument",
recommended: false,
url: "https://eslint.org/docs/latest/rules/no-object-constructor"
},
hasSuggestions: true,
schema: [],
messages: {
preferLiteral: "The object literal notation {} is preferable.",
useLiteral: "Replace with '{{replacement}}'."
}
},
create(context) {
const sourceCode = context.sourceCode;
/**
* Determines whether or not an object literal that replaces a specified node needs to be enclosed in parentheses.
* @param {ASTNode} node The node to be replaced.
* @returns {boolean} Whether or not parentheses around the object literal are required.
*/
function needsParentheses(node) {
if (isStartOfExpressionStatement(node)) {
return true;
}
const prevToken = sourceCode.getTokenBefore(node);
if (prevToken && isArrowToken(prevToken)) {
return true;
}
return false;
}
/**
* Reports on nodes where the `Object` constructor is called without arguments.
* @param {ASTNode} node The node to evaluate.
* @returns {void}
*/
function check(node) {
if (node.callee.type !== "Identifier" || node.callee.name !== "Object" || node.arguments.length) {
return;
}
const variable = getVariableByName(sourceCode.getScope(node), "Object");
if (variable && variable.identifiers.length === 0) {
const replacement = needsParentheses(node) ? "({})" : "{}";
context.report({
node,
messageId: "preferLiteral",
suggest: [
{
messageId: "useLiteral",
data: { replacement },
fix: fixer => fixer.replaceText(node, replacement)
}
]
});
}
}
return {
CallExpression: check,
NewExpression: check
};
}
};

View file

@ -12,7 +12,15 @@ const
{ isCommentToken } = require("@eslint-community/eslint-utils"),
TokenStore = require("./token-store"),
astUtils = require("../shared/ast-utils"),
Traverser = require("../shared/traverser");
Traverser = require("../shared/traverser"),
globals = require("../../conf/globals"),
{
directivesPattern
} = require("../shared/directives"),
/* eslint-disable-next-line n/no-restricted-require -- Too messy to figure out right now. */
ConfigCommentParser = require("../linter/config-comment-parser"),
eslintScope = require("eslint-scope");
//------------------------------------------------------------------------------
// Type Definitions
@ -24,6 +32,8 @@ const
// Private
//------------------------------------------------------------------------------
const commentParser = new ConfigCommentParser();
/**
* Validates that the given AST has the required information.
* @param {ASTNode} ast The Program node of the AST to check.
@ -49,6 +59,29 @@ function validate(ast) {
}
}
/**
* Retrieves globals for the given ecmaVersion.
* @param {number} ecmaVersion The version to retrieve globals for.
* @returns {Object} The globals for the given ecmaVersion.
*/
function getGlobalsForEcmaVersion(ecmaVersion) {
switch (ecmaVersion) {
case 3:
return globals.es3;
case 5:
return globals.es5;
default:
if (ecmaVersion < 2015) {
return globals[`es${ecmaVersion + 2009}`];
}
return globals[`es${ecmaVersion}`];
}
}
/**
* Check to see if its a ES6 export declaration.
* @param {ASTNode} astNode An AST node.
@ -83,6 +116,36 @@ function sortedMerge(tokens, comments) {
return result;
}
/**
* Normalizes a value for a global in a config
* @param {(boolean|string|null)} configuredValue The value given for a global in configuration or in
* a global directive comment
* @returns {("readable"|"writeable"|"off")} The value normalized as a string
* @throws Error if global value is invalid
*/
function normalizeConfigGlobal(configuredValue) {
switch (configuredValue) {
case "off":
return "off";
case true:
case "true":
case "writeable":
case "writable":
return "writable";
case null:
case false:
case "false":
case "readable":
case "readonly":
return "readonly";
default:
throw new Error(`'${configuredValue}' is not a valid configuration for a global (use 'readonly', 'writable', or 'off')`);
}
}
/**
* Determines if two nodes or tokens overlap.
* @param {ASTNode|Token} first The first node or token to check.
@ -145,6 +208,116 @@ function isSpaceBetween(sourceCode, first, second, checkInsideOfJSXText) {
return false;
}
//-----------------------------------------------------------------------------
// Directive Comments
//-----------------------------------------------------------------------------
/**
* Extract the directive and the justification from a given directive comment and trim them.
* @param {string} value The comment text to extract.
* @returns {{directivePart: string, justificationPart: string}} The extracted directive and justification.
*/
function extractDirectiveComment(value) {
const match = /\s-{2,}\s/u.exec(value);
if (!match) {
return { directivePart: value.trim(), justificationPart: "" };
}
const directive = value.slice(0, match.index).trim();
const justification = value.slice(match.index + match[0].length).trim();
return { directivePart: directive, justificationPart: justification };
}
/**
* Ensures that variables representing built-in properties of the Global Object,
* and any globals declared by special block comments, are present in the global
* scope.
* @param {Scope} globalScope The global scope.
* @param {Object|undefined} configGlobals The globals declared in configuration
* @param {Object|undefined} inlineGlobals The globals declared in the source code
* @returns {void}
*/
function addDeclaredGlobals(globalScope, configGlobals = {}, inlineGlobals = {}) {
// Define configured global variables.
for (const id of new Set([...Object.keys(configGlobals), ...Object.keys(inlineGlobals)])) {
/*
* `normalizeConfigGlobal` will throw an error if a configured global value is invalid. However, these errors would
* typically be caught when validating a config anyway (validity for inline global comments is checked separately).
*/
const configValue = configGlobals[id] === void 0 ? void 0 : normalizeConfigGlobal(configGlobals[id]);
const commentValue = inlineGlobals[id] && inlineGlobals[id].value;
const value = commentValue || configValue;
const sourceComments = inlineGlobals[id] && inlineGlobals[id].comments;
if (value === "off") {
continue;
}
let variable = globalScope.set.get(id);
if (!variable) {
variable = new eslintScope.Variable(id, globalScope);
globalScope.variables.push(variable);
globalScope.set.set(id, variable);
}
variable.eslintImplicitGlobalSetting = configValue;
variable.eslintExplicitGlobal = sourceComments !== void 0;
variable.eslintExplicitGlobalComments = sourceComments;
variable.writeable = (value === "writable");
}
/*
* "through" contains all references which definitions cannot be found.
* Since we augment the global scope using configuration, we need to update
* references and remove the ones that were added by configuration.
*/
globalScope.through = globalScope.through.filter(reference => {
const name = reference.identifier.name;
const variable = globalScope.set.get(name);
if (variable) {
/*
* Links the variable and the reference.
* And this reference is removed from `Scope#through`.
*/
reference.resolved = variable;
variable.references.push(reference);
return false;
}
return true;
});
}
/**
* Sets the given variable names as exported so they won't be triggered by
* the `no-unused-vars` rule.
* @param {eslint.Scope} globalScope The global scope to define exports in.
* @param {Record<string,string>} variables An object whose keys are the variable
* names to export.
* @returns {void}
*/
function markExportedVariables(globalScope, variables) {
Object.keys(variables).forEach(name => {
const variable = globalScope.set.get(name);
if (variable) {
variable.eslintUsed = true;
variable.eslintExported = true;
}
});
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
@ -187,7 +360,9 @@ class SourceCode extends TokenStore {
* General purpose caching for the class.
*/
this[caches] = new Map([
["scopes", new WeakMap()]
["scopes", new WeakMap()],
["vars", new Map()],
["configNodes", void 0]
]);
/**
@ -266,7 +441,7 @@ class SourceCode extends TokenStore {
// Cache for comments found using getComments().
this._commentCache = new WeakMap();
// don't allow modification of this object
// don't allow further modification of this object
Object.freeze(this);
Object.freeze(this.lines);
}
@ -724,6 +899,178 @@ class SourceCode extends TokenStore {
}
/**
* Returns an array of all inline configuration nodes found in the
* source code.
* @returns {Array<Token>} An array of all inline configuration nodes.
*/
getInlineConfigNodes() {
// check the cache first
let configNodes = this[caches].get("configNodes");
if (configNodes) {
return configNodes;
}
// calculate fresh config nodes
configNodes = this.ast.comments.filter(comment => {
// shebang comments are never directives
if (comment.type === "Shebang") {
return false;
}
const { directivePart } = extractDirectiveComment(comment.value);
const directiveMatch = directivesPattern.exec(directivePart);
if (!directiveMatch) {
return false;
}
// only certain comment types are supported as line comments
return comment.type !== "Line" || !!/^eslint-disable-(next-)?line$/u.test(directiveMatch[1]);
});
this[caches].set("configNodes", configNodes);
return configNodes;
}
/**
* Applies language options sent in from the core.
* @param {Object} languageOptions The language options for this run.
* @returns {void}
*/
applyLanguageOptions(languageOptions) {
/*
* Add configured globals and language globals
*
* Using Object.assign instead of object spread for performance reasons
* https://github.com/eslint/eslint/issues/16302
*/
const configGlobals = Object.assign(
{},
getGlobalsForEcmaVersion(languageOptions.ecmaVersion),
languageOptions.sourceType === "commonjs" ? globals.commonjs : void 0,
languageOptions.globals
);
const varsCache = this[caches].get("vars");
varsCache.set("configGlobals", configGlobals);
}
/**
* Applies configuration found inside of the source code. This method is only
* called when ESLint is running with inline configuration allowed.
* @returns {{problems:Array<Problem>,configs:{config:FlatConfigArray,node:ASTNode}}} Information
* that ESLint needs to further process the inline configuration.
*/
applyInlineConfig() {
const problems = [];
const configs = [];
const exportedVariables = {};
const inlineGlobals = Object.create(null);
this.getInlineConfigNodes().forEach(comment => {
const { directivePart } = extractDirectiveComment(comment.value);
const match = directivesPattern.exec(directivePart);
const directiveText = match[1];
const directiveValue = directivePart.slice(match.index + directiveText.length);
switch (directiveText) {
case "exported":
Object.assign(exportedVariables, commentParser.parseStringConfig(directiveValue, comment));
break;
case "globals":
case "global":
for (const [id, { value }] of Object.entries(commentParser.parseStringConfig(directiveValue, comment))) {
let normalizedValue;
try {
normalizedValue = normalizeConfigGlobal(value);
} catch (err) {
problems.push({
ruleId: null,
loc: comment.loc,
message: err.message
});
continue;
}
if (inlineGlobals[id]) {
inlineGlobals[id].comments.push(comment);
inlineGlobals[id].value = normalizedValue;
} else {
inlineGlobals[id] = {
comments: [comment],
value: normalizedValue
};
}
}
break;
case "eslint": {
const parseResult = commentParser.parseJsonConfig(directiveValue, comment.loc);
if (parseResult.success) {
configs.push({
config: {
rules: parseResult.config
},
node: comment
});
} else {
problems.push(parseResult.error);
}
break;
}
// no default
}
});
// save all the new variables for later
const varsCache = this[caches].get("vars");
varsCache.set("inlineGlobals", inlineGlobals);
varsCache.set("exportedVariables", exportedVariables);
return {
configs,
problems
};
}
/**
* Called by ESLint core to indicate that it has finished providing
* information. We now add in all the missing variables and ensure that
* state-changing methods cannot be called by rules.
* @returns {void}
*/
finalize() {
// Step 1: ensure that all of the necessary variables are up to date
const varsCache = this[caches].get("vars");
const globalScope = this.scopeManager.scopes[0];
const configGlobals = varsCache.get("configGlobals");
const inlineGlobals = varsCache.get("inlineGlobals");
const exportedVariables = varsCache.get("exportedVariables");
addDeclaredGlobals(globalScope, configGlobals, inlineGlobals);
if (exportedVariables) {
markExportedVariables(globalScope, exportedVariables);
}
}
}
module.exports = SourceCode;

4
node_modules/eslint/package.json generated vendored
View file

@ -1,6 +1,6 @@
{
"name": "eslint",
"version": "8.49.0",
"version": "8.50.0",
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
"description": "An AST-based pattern checker for JavaScript.",
"bin": {
@ -63,7 +63,7 @@
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.2",
"@eslint/js": "8.49.0",
"@eslint/js": "8.50.0",
"@humanwhocodes/config-array": "^0.11.11",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",