Socket
Socket
Sign inDemoInstall

eslint

Package Overview
Dependencies
97
Maintainers
4
Versions
356
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 9.0.0-alpha.0 to 9.0.0-alpha.1

conf/ecma-version.js

2

lib/cli-engine/cli-engine.js

@@ -735,3 +735,3 @@ /**

static outputFixes(report) {
report.results.filter(result => Object.prototype.hasOwnProperty.call(result, "output")).forEach(result => {
report.results.filter(result => Object.hasOwn(result, "output")).forEach(result => {
fs.writeFileSync(result.filePath, result.output);

@@ -738,0 +738,0 @@ });

@@ -167,3 +167,3 @@ /**

setCachedLintResults(filePath, config, result) {
if (result && Object.prototype.hasOwnProperty.call(result, "output")) {
if (result && Object.hasOwn(result, "output")) {
return;

@@ -185,3 +185,3 @@ }

*/
if (Object.prototype.hasOwnProperty.call(resultToSerialize, "source")) {
if (Object.hasOwn(resultToSerialize, "source")) {
resultToSerialize.source = null;

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

@@ -288,21 +288,19 @@ /**

if (output) {
if (outputFile) {
const filePath = path.resolve(process.cwd(), outputFile);
if (outputFile) {
const filePath = path.resolve(process.cwd(), outputFile);
if (await isDirectory(filePath)) {
log.error("Cannot write to output file path, it is a directory: %s", outputFile);
return false;
}
if (await isDirectory(filePath)) {
log.error("Cannot write to output file path, it is a directory: %s", outputFile);
return false;
}
try {
await mkdir(path.dirname(filePath), { recursive: true });
await writeFile(filePath, output);
} catch (ex) {
log.error("There was a problem writing the output file:\n%s", ex);
return false;
}
} else {
log.info(output);
try {
await mkdir(path.dirname(filePath), { recursive: true });
await writeFile(filePath, output);
} catch (ex) {
log.error("There was a problem writing the output file:\n%s", ex);
return false;
}
} else if (output) {
log.info(output);
}

@@ -309,0 +307,0 @@

@@ -174,3 +174,3 @@ /**

? ruleIds.join(" or ")
: `${ruleIds.slice(0, ruleIds.length - 1).join(", ")}, or ${ruleIds[ruleIds.length - 1]}`,
: `${ruleIds.slice(0, ruleIds.length - 1).join(", ")}, or ${ruleIds.at(-1)}`,
fix: {

@@ -346,3 +346,3 @@ range,

problem.suppressions = suppressions;
usedDisableDirectives.add(disableDirectivesForProblem[disableDirectivesForProblem.length - 1]);
usedDisableDirectives.add(disableDirectivesForProblem.at(-1));
}

@@ -349,0 +349,0 @@ }

@@ -129,16 +129,2 @@ /**

/**
* Tracks the traversal of the code path through each segment. This array
* starts empty and segments are added or removed as the code path is
* traversed. This array always ends up empty at the end of a code path
* traversal. The `CodePathState` uses this to track its progress through
* the code path.
* This is a passthrough to the underlying `CodePathState`.
* @type {CodePathSegment[]}
* @deprecated
*/
get currentSegments() {
return this.internal.currentSegments;
}
/**
* Traverses all segments in this code path.

@@ -184,5 +170,5 @@ *

// set up initial location information
let record = null;
let index = 0;
let end = 0;
let record;
let index;
let end;
let segment = null;

@@ -215,3 +201,3 @@

} else {
skippedSegment = stack[stack.length - 2][0];
skippedSegment = stack.at(-2)[0];
}

@@ -257,3 +243,3 @@ },

*/
record = stack[stack.length - 1];
record = stack.at(-1);
segment = record[0];

@@ -260,0 +246,0 @@ index = record[1];

@@ -210,3 +210,3 @@ /**

return list.length === 0 ? [] : list[list.length - 1];
return list.length === 0 ? [] : list.at(-1);
}

@@ -213,0 +213,0 @@

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

let items = {};
// Parses a JSON-like comment by the same way as parsing CLI option.
try {
items = levn.parse("Object", string) || {};
const items = levn.parse("Object", string) || {};

@@ -106,7 +104,11 @@ // Some tests say that it should ignore invalid comments such as `/*eslint no-alert:abc*/`.

*/
items = {};
const normalizedString = string.replace(/([-a-zA-Z0-9/]+):/gu, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/u, "$1,");
try {
items = JSON.parse(`{${normalizedString}}`);
const items = JSON.parse(`{${normalizedString}}`);
return {
success: true,
config: items
};
} catch (ex) {

@@ -129,7 +131,2 @@ debug("Manual parsing failed.");

}
return {
success: true,
config: items
};
}

@@ -136,0 +133,0 @@

@@ -163,3 +163,3 @@ /**

const start = fixes[0].range[0];
const end = fixes[fixes.length - 1].range[1];
const end = fixes.at(-1).range[1];
let text = "";

@@ -347,3 +347,3 @@ let lastPos = Number.MIN_SAFE_INTEGER;

}
if (!messages || !Object.prototype.hasOwnProperty.call(messages, id)) {
if (!messages || !Object.hasOwn(messages, id)) {
throw new TypeError(`context.report() called with a messageId of '${id}' which is not present in the 'messages' config: ${JSON.stringify(messages, null, 2)}`);

@@ -350,0 +350,0 @@ }

@@ -110,3 +110,3 @@ /**

messages.forEach(problem => {
if (Object.prototype.hasOwnProperty.call(problem, "fix")) {
if (Object.hasOwn(problem, "fix")) {
fixes.push(problem);

@@ -113,0 +113,0 @@ } else {

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

{ getRuleOptionsSchema } = require("../config/flat-config-helpers"),
{ Linter, SourceCodeFixer, interpolate } = require("../linter"),
CodePath = require("../linter/code-path-analysis/code-path");
{ Linter, SourceCodeFixer, interpolate } = require("../linter");

@@ -279,17 +278,2 @@ const { FlatConfigArray } = require("../config/flat-config-array");

/**
* Emit a deprecation warning if rule uses CodePath#currentSegments.
* @param {string} ruleName Name of the rule.
* @returns {void}
*/
function emitCodePathCurrentSegmentsWarning(ruleName) {
if (!emitCodePathCurrentSegmentsWarning[`warned-${ruleName}`]) {
emitCodePathCurrentSegmentsWarning[`warned-${ruleName}`] = true;
process.emitWarning(
`"${ruleName}" rule uses CodePath#currentSegments and will stop working in ESLint v9. Please read the documentation for how to update your code: https://eslint.org/docs/latest/extend/code-path-analysis#usage-examples`,
"DeprecationWarning"
);
}
}
/**
* Function to replace forbidden `SourceCode` methods. Allows just one call per method.

@@ -758,13 +742,5 @@ * @param {string} methodName The name of the method to forbid.

const { applyLanguageOptions, applyInlineConfig, finalize } = SourceCode.prototype;
const originalCurrentSegments = Object.getOwnPropertyDescriptor(CodePath.prototype, "currentSegments");
let messages;
try {
Object.defineProperty(CodePath.prototype, "currentSegments", {
get() {
emitCodePathCurrentSegmentsWarning(ruleName);
return originalCurrentSegments.get.call(this);
}
});
forbiddenMethods.forEach(methodName => {

@@ -776,3 +752,2 @@ SourceCode.prototype[methodName] = throwForbiddenMethodError(methodName, SourceCode.prototype);

} finally {
Object.defineProperty(CodePath.prototype, "currentSegments", originalCurrentSegments);
SourceCode.prototype.applyInlineConfig = applyInlineConfig;

@@ -779,0 +754,0 @@ SourceCode.prototype.applyLanguageOptions = applyLanguageOptions;

@@ -77,3 +77,3 @@ /**

let multiline = false;
let minItems = 0;
let minItems;

@@ -80,0 +80,0 @@ if (option) {

@@ -202,3 +202,3 @@ /**

firstElement = node.elements[0],
lastElement = node.elements[node.elements.length - 1];
lastElement = node.elements.at(-1);

@@ -205,0 +205,0 @@ const openingBracketMustBeSpaced =

@@ -82,3 +82,3 @@ /**

// Defines a predicate to check whether or not a given reference is outside of valid scope.
const scopeRange = stack[stack.length - 1];
const scopeRange = stack.at(-1);

@@ -85,0 +85,0 @@ /**

@@ -150,3 +150,3 @@ /**

// find the last item in the block
const lastItem = closestBlock.body[closestBlock.body.length - 1];
const lastItem = closestBlock.body.at(-1);

@@ -172,3 +172,3 @@ // if the callback is the last thing in a block that might be ok

// but only if the callback is immediately before
if (isCallbackExpression(node, closestBlock.body[closestBlock.body.length - 2])) {
if (isCallbackExpression(node, closestBlock.body.at(-2))) {
return;

@@ -175,0 +175,0 @@ }

@@ -157,3 +157,3 @@ /**

function last(array) {
return array[array.length - 1];
return array.at(-1);
}

@@ -160,0 +160,0 @@

@@ -69,3 +69,3 @@ /**

if (context.options.length === 2 && Object.prototype.hasOwnProperty.call(context.options[1], "exceptions")) {
if (context.options.length === 2 && Object.hasOwn(context.options[1], "exceptions")) {
const keys = Object.keys(context.options[1].exceptions);

@@ -222,3 +222,3 @@

? sourceCode.getTokenBefore(tokenAfterItem)
: sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1];
: sourceCode.ast.tokens.at(-1);
} else {

@@ -225,0 +225,0 @@ previousItemToken = currentItemToken;

@@ -67,3 +67,3 @@ /**

typeof option === "object" &&
(Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
(Object.hasOwn(option, "maximum") || Object.hasOwn(option, "max"))
) {

@@ -70,0 +70,0 @@ THRESHOLD = option.maximum || option.max;

@@ -112,3 +112,3 @@ /**

case "SequenceExpression": {
const lastExpression = node.expressions[node.expressions.length - 1];
const lastExpression = node.expressions.at(-1);

@@ -115,0 +115,0 @@ return isPossibleConstructor(lastExpression);

@@ -57,3 +57,3 @@ /**

function last(collection) {
return collection[collection.length - 1];
return collection.at(-1);
}

@@ -60,0 +60,0 @@

@@ -48,3 +48,3 @@ /**

src = sourceCode.getText(),
lastLine = sourceCode.lines[sourceCode.lines.length - 1],
lastLine = sourceCode.lines.at(-1),
location = {

@@ -93,3 +93,3 @@ column: lastLine.length,

const secondLastLine = sourceCode.lines[sourceCode.lines.length - 2];
const secondLastLine = sourceCode.lines.at(-2);

@@ -96,0 +96,0 @@ // File is newline-terminated, but shouldn't be

@@ -221,3 +221,3 @@ /**

const rightParen = node.params.length
? sourceCode.getTokenAfter(node.params[node.params.length - 1], astUtils.isClosingParenToken)
? sourceCode.getTokenAfter(node.params.at(-1), astUtils.isClosingParenToken)
: sourceCode.getTokenAfter(leftParen);

@@ -238,3 +238,3 @@

const rightParen = node.params.length
? sourceCode.getTokenAfter(node.params[node.params.length - 1], astUtils.isClosingParenToken)
? sourceCode.getTokenAfter(node.params.at(-1), astUtils.isClosingParenToken)
: sourceCode.getTokenAfter(firstToken);

@@ -241,0 +241,0 @@

@@ -792,3 +792,3 @@ /**

// Skip last block line check if last item in same line
if (elements[elements.length - 1].loc.end.line === node.loc.end.line) {
if (elements.at(-1).loc.end.line === node.loc.end.line) {
return;

@@ -834,3 +834,3 @@ }

let indent;
let nodesToCheck = [];
let nodesToCheck;

@@ -878,3 +878,3 @@ /*

return node.declarations.reduce((finalCollection, elem) => {
const lastElem = finalCollection[finalCollection.length - 1];
const lastElem = finalCollection.at(-1);

@@ -898,3 +898,3 @@ if ((elem.loc.start.line !== node.loc.start.line && !lastElem) ||

const nodeIndent = getNodeIndent(node).goodChar;
const lastElement = elements[elements.length - 1];
const lastElement = elements.at(-1);

@@ -1006,3 +1006,3 @@ const elementsIndent = nodeIndent + indentSize * options.VariableDeclarator[node.kind];

VariableDeclaration(node) {
if (node.declarations[node.declarations.length - 1].loc.start.line > node.declarations[0].loc.start.line) {
if (node.declarations.at(-1).loc.start.line > node.declarations[0].loc.start.line) {
checkIndentInVariableDeclarations(node);

@@ -1009,0 +1009,0 @@ }

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

"no-use-before-define": () => require("./no-use-before-define"),
"no-useless-assignment": () => require("./no-useless-assignment"),
"no-useless-backreference": () => require("./no-useless-backreference"),

@@ -234,0 +235,0 @@ "no-useless-call": () => require("./no-useless-call"),

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

function last(arr) {
return arr[arr.length - 1];
return arr.at(-1);
}

@@ -493,3 +493,3 @@

let messageId = "";
let messageId;

@@ -496,0 +496,0 @@ if (isExtra) {

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

if (Object.prototype.hasOwnProperty.call(options, "applyDefaultIgnorePatterns")) {
if (Object.hasOwn(options, "applyDefaultIgnorePatterns")) {
applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns;

@@ -74,0 +74,0 @@ } else {

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

const lastDirective = directives[directives.length - 1];
const lastDirective = directives.at(-1);
const statements = node.type === "Program" ? node.body : node.body.body;

@@ -178,3 +178,3 @@

*/
if (lastDirective === statements[statements.length - 1] && !lastDirective.trailingComments) {
if (lastDirective === statements.at(-1) && !lastDirective.trailingComments) {
return;

@@ -181,0 +181,0 @@ }

@@ -64,3 +64,3 @@ /**

typeof option === "object" &&
(Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
(Object.hasOwn(option, "maximum") || Object.hasOwn(option, "max"))
) {

@@ -67,0 +67,0 @@ maxDepth = option.maximum || option.max;

@@ -127,3 +127,3 @@ /**

// The options object must be the last option specified…
const options = Object.assign({}, context.options[context.options.length - 1]);
const options = Object.assign({}, context.options.at(-1));

@@ -294,3 +294,3 @@ // …but max code length…

// push a unique node only
if (comments[comments.length - 1] !== containingNode.parent) {
if (comments.at(-1) !== containingNode.parent) {
comments.push(containingNode.parent);

@@ -349,3 +349,3 @@ }

if (commentsIndex < comments.length) {
let comment = null;
let comment;

@@ -352,0 +352,0 @@ // iterate over comments until we find one past the current line

@@ -80,3 +80,3 @@ /**

typeof option === "object" &&
Object.prototype.hasOwnProperty.call(option, "max")
Object.hasOwn(option, "max")
) {

@@ -152,3 +152,3 @@ max = option.max;

*/
if (lines.length > 1 && lines[lines.length - 1].text === "") {
if (lines.length > 1 && lines.at(-1).text === "") {
lines.pop();

@@ -179,3 +179,3 @@ }

line: sourceCode.lines.length,
column: sourceCode.lines[sourceCode.lines.length - 1].length
column: sourceCode.lines.at(-1).length
}

@@ -182,0 +182,0 @@ };

@@ -62,3 +62,3 @@ /**

typeof option === "object" &&
(Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
(Object.hasOwn(option, "maximum") || Object.hasOwn(option, "max"))
) {

@@ -65,0 +65,0 @@ THRESHOLD = option.maximum || option.max;

@@ -66,3 +66,3 @@ /**

typeof option === "object" &&
(Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
(Object.hasOwn(option, "maximum") || Object.hasOwn(option, "max"))
) {

@@ -69,0 +69,0 @@ numParams = option.maximum || option.max;

@@ -82,3 +82,3 @@ /**

typeof option === "object" &&
(Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
(Object.hasOwn(option, "maximum") || Object.hasOwn(option, "max"))
) {

@@ -85,0 +85,0 @@ maxStatements = option.maximum || option.max;

@@ -116,3 +116,3 @@ /**

lines.slice(1, -1).every(line => /^\s* /u.test(line)) &&
/^\s*$/u.test(lines[lines.length - 1]);
/^\s*$/u.test(lines.at(-1));
}

@@ -276,7 +276,7 @@

start: firstComment.loc.start,
end: commentGroup[commentGroup.length - 1].loc.end
end: commentGroup.at(-1).loc.end
},
messageId: "expectedBlock",
fix(fixer) {
const range = [firstComment.range[0], commentGroup[commentGroup.length - 1].range[1]];
const range = [firstComment.range[0], commentGroup.at(-1).range[1]];

@@ -306,3 +306,3 @@ return commentLines.some(value => value.startsWith("/"))

if (!/^\s*$/u.test(lines[lines.length - 1])) {
if (!/^\s*$/u.test(lines.at(-1))) {
context.report({

@@ -414,3 +414,3 @@ loc: {

start: firstComment.loc.start,
end: commentGroup[commentGroup.length - 1].loc.end
end: commentGroup.at(-1).loc.end
},

@@ -420,3 +420,3 @@ messageId: "expectedBlock",

return fixer.replaceTextRange(
[firstComment.range[0], commentGroup[commentGroup.length - 1].range[1]],
[firstComment.range[0], commentGroup.at(-1).range[1]],
convertToBlock(firstComment, commentLines)

@@ -467,3 +467,3 @@ );

) {
commentGroups[commentGroups.length - 1].push(comment);
commentGroups.at(-1).push(comment);
} else {

@@ -470,0 +470,0 @@ commentGroups.push([comment]);

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

/* c8 ignore start */
if (Object.prototype.hasOwnProperty.call(obj, key) && !Array.isArray(obj[key])) {
if (Object.hasOwn(obj, key) && !Array.isArray(obj[key])) {
throw new TypeError(`${key}, if provided, must be an Array`);

@@ -46,0 +46,0 @@ }/* c8 ignore stop */

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

return fixer.replaceTextRange([lastToken.range[1], nextToken.range[0]], `${linesBetween.slice(0, -1).join("")}\n${linesBetween[linesBetween.length - 1]}`);
return fixer.replaceTextRange([lastToken.range[1], nextToken.range[0]], `${linesBetween.slice(0, -1).join("")}\n${linesBetween.at(-1)}`);
}

@@ -221,0 +221,0 @@ });

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

const leadingComments = sourceCode.getCommentsBefore(node);
const lastLeadingComment = leadingComments[leadingComments.length - 1];
const lastLeadingComment = leadingComments.at(-1);
const tokenBefore = sourceCode.getTokenBefore(node);

@@ -172,0 +172,0 @@

@@ -106,3 +106,3 @@ /**

case "SequenceExpression": {
const last = node.expressions[node.expressions.length - 1];
const last = node.expressions.at(-1);

@@ -252,3 +252,3 @@ return hasConstantNullishness(scope, last, nonNullish);

case "SequenceExpression": {
const last = node.expressions[node.expressions.length - 1];
const last = node.expressions.at(-1);

@@ -304,3 +304,3 @@ return hasConstantLooseBooleanComparison(scope, last);

case "SequenceExpression": {
const last = node.expressions[node.expressions.length - 1];
const last = node.expressions.at(-1);

@@ -382,3 +382,3 @@ return hasConstantStrictBooleanComparison(scope, last);

*/
return Object.hasOwnProperty.call(globals.builtin, node.callee.name) &&
return Object.hasOwn(globals.builtin, node.callee.name) &&
isReferenceToGlobalVariable(scope, node.callee);

@@ -391,3 +391,3 @@ }

case "SequenceExpression": {
const last = node.expressions[node.expressions.length - 1];
const last = node.expressions.at(-1);

@@ -394,0 +394,0 @@ return isAlwaysNew(scope, last);

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

ReturnStatement(node) {
const last = stack[stack.length - 1];
const last = stack.at(-1);

@@ -46,0 +46,0 @@ if (!last.parent) {

@@ -45,3 +45,3 @@ /**

function getState(name, isStatic) {
const stateMap = stack[stack.length - 1];
const stateMap = stack.at(-1);
const key = `$${name}`; // to avoid "__proto__".

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

const state = getState(name, node.static);
let isDuplicate = false;
let isDuplicate;

@@ -89,0 +89,0 @@ if (kind === "get") {

@@ -273,3 +273,3 @@ /**

const body = node.body,
lastChildNode = body[body.length - 1];
lastChildNode = body.at(-1);

@@ -276,0 +276,0 @@ return lastChildNode && checkForReturn(lastChildNode);

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

const parent = node.parent;
let kind = "";
let kind;

@@ -77,3 +77,3 @@ if (node.type === "ArrowFunctionExpression") {

// Detects prefix.
let prefix = "";
let prefix;

@@ -80,0 +80,0 @@ if (node.generator) {

@@ -190,3 +190,3 @@ /**

(node.consequent.length > 0 || (!allowEmptyCase && hasBlankLinesBetween(node, nextToken))) &&
node.parent.cases[node.parent.cases.length - 1] !== node) {
node.parent.cases.at(-1) !== node) {
fallthroughCase = node;

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

@@ -59,2 +59,11 @@ /**

enum: ["functions", "both"]
},
{
type: "object",
properties: {
blockScopedFunctions: {
enum: ["allow", "disallow"]
}
},
additionalProperties: false
}

@@ -70,2 +79,6 @@ ],

const sourceCode = context.sourceCode;
const ecmaVersion = context.languageOptions.ecmaVersion;
const blockScopedFunctions = context.options[1]?.blockScopedFunctions ?? "allow";
/**

@@ -102,3 +115,11 @@ * Ensure that a given node is at a program or function body's root.

FunctionDeclaration: check,
FunctionDeclaration(node) {
const isInStrictCode = sourceCode.getScope(node).upper.isStrict;
if (blockScopedFunctions === "allow" && ecmaVersion >= 2015 && isInStrictCode) {
return;
}
check(node);
},
VariableDeclaration(node) {

@@ -105,0 +126,0 @@ if (context.options[0] === "both" && node.kind === "var") {

@@ -77,3 +77,3 @@ /**

stack.getCurrent = function() {
const current = this[this.length - 1];
const current = this.at(-1);

@@ -80,0 +80,0 @@ if (!current.init) {

@@ -81,3 +81,3 @@ /**

if (loneBlocks[loneBlocks.length - 1] === block) {
if (loneBlocks.at(-1) === block) {
loneBlocks.pop();

@@ -105,3 +105,3 @@ }

"BlockStatement:exit"(node) {
if (loneBlocks.length > 0 && loneBlocks[loneBlocks.length - 1] === node) {
if (loneBlocks.length > 0 && loneBlocks.at(-1) === node) {
loneBlocks.pop();

@@ -108,0 +108,0 @@ report(node);

@@ -67,3 +67,3 @@ /**

const rawString = getRaw(node).toUpperCase();
let base = 0;
let base;

@@ -70,0 +70,0 @@ if (rawString.startsWith("0B")) {

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

/**

@@ -77,76 +76,122 @@ * Checks whether the given character node is a Unicode code point escape or not.

/**
* Each function returns `true` if it detects that kind of problem.
* @type {Record<string, (chars: Character[]) => boolean>}
* Each function returns matched characters if it detects that kind of problem.
* @type {Record<string, (chars: Character[]) => IterableIterator<Character[]>>}
*/
const hasCharacterSequence = {
surrogatePairWithoutUFlag(chars) {
return chars.some((c, i) => {
if (i === 0) {
return false;
const findCharacterSequences = {
*surrogatePairWithoutUFlag(chars) {
for (const [index, char] of chars.entries()) {
if (index === 0) {
continue;
}
const c1 = chars[i - 1];
const previous = chars[index - 1];
return (
isSurrogatePair(c1.value, c.value) &&
!isUnicodeCodePointEscape(c1) &&
!isUnicodeCodePointEscape(c)
);
});
if (
isSurrogatePair(previous.value, char.value) &&
!isUnicodeCodePointEscape(previous) &&
!isUnicodeCodePointEscape(char)
) {
yield [previous, char];
}
}
},
surrogatePair(chars) {
return chars.some((c, i) => {
if (i === 0) {
return false;
*surrogatePair(chars) {
for (const [index, char] of chars.entries()) {
if (index === 0) {
continue;
}
const c1 = chars[i - 1];
const previous = chars[index - 1];
return (
isSurrogatePair(c1.value, c.value) &&
if (
isSurrogatePair(previous.value, char.value) &&
(
isUnicodeCodePointEscape(c1) ||
isUnicodeCodePointEscape(c)
isUnicodeCodePointEscape(previous) ||
isUnicodeCodePointEscape(char)
)
);
});
) {
yield [previous, char];
}
}
},
combiningClass(chars) {
return chars.some((c, i) => (
i !== 0 &&
isCombiningCharacter(c.value) &&
!isCombiningCharacter(chars[i - 1].value)
));
*combiningClass(chars) {
for (const [index, char] of chars.entries()) {
if (index === 0) {
continue;
}
const previous = chars[index - 1];
if (
isCombiningCharacter(char.value) &&
!isCombiningCharacter(previous.value)
) {
yield [previous, char];
}
}
},
emojiModifier(chars) {
return chars.some((c, i) => (
i !== 0 &&
isEmojiModifier(c.value) &&
!isEmojiModifier(chars[i - 1].value)
));
*emojiModifier(chars) {
for (const [index, char] of chars.entries()) {
if (index === 0) {
continue;
}
const previous = chars[index - 1];
if (
isEmojiModifier(char.value) &&
!isEmojiModifier(previous.value)
) {
yield [previous, char];
}
}
},
regionalIndicatorSymbol(chars) {
return chars.some((c, i) => (
i !== 0 &&
isRegionalIndicatorSymbol(c.value) &&
isRegionalIndicatorSymbol(chars[i - 1].value)
));
*regionalIndicatorSymbol(chars) {
for (const [index, char] of chars.entries()) {
if (index === 0) {
continue;
}
const previous = chars[index - 1];
if (
isRegionalIndicatorSymbol(char.value) &&
isRegionalIndicatorSymbol(previous.value)
) {
yield [previous, char];
}
}
},
zwj(chars) {
const lastIndex = chars.length - 1;
*zwj(chars) {
let sequence = null;
return chars.some((c, i) => (
i !== 0 &&
i !== lastIndex &&
c.value === 0x200d &&
chars[i - 1].value !== 0x200d &&
chars[i + 1].value !== 0x200d
));
for (const [index, char] of chars.entries()) {
if (index === 0 || index === chars.length - 1) {
continue;
}
if (
char.value === 0x200d &&
chars[index - 1].value !== 0x200d &&
chars[index + 1].value !== 0x200d
) {
if (sequence) {
if (sequence.at(-1) === chars[index - 1]) {
sequence.push(char, chars[index + 1]); // append to the sequence
} else {
yield sequence;
sequence = chars.slice(index - 1, index + 2);
}
} else {
sequence = chars.slice(index - 1, index + 2);
}
}
}
if (sequence) {
yield sequence;
}
}
};
const kinds = Object.keys(hasCharacterSequence);
const kinds = Object.keys(findCharacterSequences);

@@ -187,2 +232,58 @@ //------------------------------------------------------------------------------

/**
* Generates a granular loc for context.report, if directly calculable.
* @param {Character[]} chars Individual characters being reported on.
* @param {Node} node Parent string node to report within.
* @returns {Object | null} Granular loc for context.report, if directly calculable.
* @see https://github.com/eslint/eslint/pull/17515
*/
function generateReportLocation(chars, node) {
// Limit to to literals and expression-less templates with raw values === their value.
switch (node.type) {
case "TemplateLiteral":
if (node.expressions.length || sourceCode.getText(node).slice(1, -1) !== node.quasis[0].value.cooked) {
return null;
}
break;
case "Literal":
if (typeof node.value === "string" && node.value !== node.raw.slice(1, -1)) {
return null;
}
break;
default:
return null;
}
return {
start: sourceCode.getLocFromIndex(node.range[0] + 1 + chars[0].start),
end: sourceCode.getLocFromIndex(node.range[0] + 1 + chars.at(-1).end)
};
}
/**
* Finds the report loc(s) for a range of matches.
* @param {Character[][]} matches Characters that should trigger a report.
* @param {Node} node The node to report.
* @returns {Object | null} Node loc(s) for context.report.
*/
function getNodeReportLocations(matches, node) {
const locs = [];
for (const chars of matches) {
const loc = generateReportLocation(chars, node);
// If a report can't match to a range, don't report any others
if (!loc) {
return [node.loc];
}
locs.push(loc);
}
return locs;
}
/**
* Verify a given regular expression.

@@ -214,3 +315,3 @@ * @param {Node} node The node to report.

const foundKinds = new Set();
const foundKindMatches = new Map();

@@ -221,5 +322,8 @@ visitRegExpAST(patternNode, {

for (const kind of kinds) {
if (hasCharacterSequence[kind](chars)) {
foundKinds.add(kind);
if (foundKindMatches.has(kind)) {
foundKindMatches.get(kind).push(...findCharacterSequences[kind](chars));
} else {
foundKindMatches.set(kind, [...findCharacterSequences[kind](chars)]);
}
}

@@ -230,3 +334,3 @@ }

for (const kind of foundKinds) {
for (const [kind, matches] of foundKindMatches) {
let suggest;

@@ -241,7 +345,12 @@

context.report({
node,
messageId: kind,
suggest
});
const locs = getNodeReportLocations(matches, node);
for (const loc of locs) {
context.report({
node,
loc,
messageId: kind,
suggest
});
}
}

@@ -277,3 +386,3 @@ }

if (typeof pattern === "string") {
verify(refNode, pattern, flags || "", fixer => {
verify(patternNode, pattern, flags || "", fixer => {

@@ -280,0 +389,0 @@ if (!isValidWithUnicodeFlag(context.languageOptions.ecmaVersion, pattern)) {

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

// Swallow the final newline, as some editors add it automatically and we don't want it to cause an issue
const allLines = sourceCode.lines[sourceCode.lines.length - 1] === "" ? sourceCode.lines.slice(0, -1) : sourceCode.lines;
const allLines = sourceCode.lines.at(-1) === "" ? sourceCode.lines.slice(0, -1) : sourceCode.lines;
const templateLiteralLines = new Set();

@@ -76,0 +76,0 @@

@@ -100,3 +100,3 @@ /**

function isRestricted(name) {
return Object.prototype.hasOwnProperty.call(restrictedGlobalMessages, name);
return Object.hasOwn(restrictedGlobalMessages, name);
}

@@ -103,0 +103,0 @@

@@ -161,3 +161,3 @@ /**

typeof options[0] === "object" &&
(Object.prototype.hasOwnProperty.call(options[0], "paths") || Object.prototype.hasOwnProperty.call(options[0], "patterns"));
(Object.hasOwn(options[0], "paths") || Object.hasOwn(options[0], "patterns"));

@@ -207,3 +207,3 @@ const restrictedPaths = (isPathAndPatternsObject ? options[0].paths : context.options) || [];

function checkRestrictedPathAndReport(importSource, importNames, node) {
if (!Object.prototype.hasOwnProperty.call(restrictedPathMessages, importSource)) {
if (!Object.hasOwn(restrictedPathMessages, importSource)) {
return;

@@ -210,0 +210,0 @@ }

@@ -93,3 +93,3 @@ /**

typeof options[0] === "object" &&
(Object.prototype.hasOwnProperty.call(options[0], "paths") || Object.prototype.hasOwnProperty.call(options[0], "patterns"));
(Object.hasOwn(options[0], "paths") || Object.hasOwn(options[0], "patterns"));

@@ -182,3 +182,3 @@ const restrictedPaths = (isPathAndPatternsObject ? options[0].paths : context.options) || [];

function isRestrictedPath(name) {
return Object.prototype.hasOwnProperty.call(restrictedPathMessages, name);
return Object.hasOwn(restrictedPathMessages, name);
}

@@ -185,0 +185,0 @@

@@ -121,3 +121,3 @@ /**

}
if (node.parent.type === "SequenceExpression" && node === node.parent.expressions[node.parent.expressions.length - 1]) {
if (node.parent.type === "SequenceExpression" && node === node.parent.expressions.at(-1)) {
return isInTailCallPosition(node.parent);

@@ -124,0 +124,0 @@ }

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

let totalLength = 0,
fixRange = [];
let totalLength = 0;

@@ -181,3 +180,3 @@ for (let i = 0, ii = lines.length; i < ii; i++) {

fixRange = [rangeStart, rangeEnd];
const fixRange = [rangeStart, rangeEnd];

@@ -184,0 +183,0 @@ if (!ignoreComments || !commentLineNumbers.has(lineNumber)) {

@@ -79,3 +79,3 @@ /**

function invertExpression(node) {
if (node.type === "BinaryExpression" && Object.prototype.hasOwnProperty.call(OPERATOR_INVERSES, node.operator)) {
if (node.type === "BinaryExpression" && Object.hasOwn(OPERATOR_INVERSES, node.operator)) {
const operatorToken = sourceCode.getFirstTokenBetween(

@@ -82,0 +82,0 @@ node.left,

@@ -97,3 +97,3 @@ /**

checkUndefinedShortCircuit(
node.expressions[node.expressions.length - 1],
node.expressions.at(-1),
reportFunc

@@ -100,0 +100,0 @@ );

@@ -144,3 +144,3 @@ /**

pattern = config.argsIgnorePattern.toString();
} else if (defType !== "Parameter" && config.varsIgnorePattern) {
} else if (defType !== "Parameter" && defType !== "CatchClause" && config.varsIgnorePattern) {
type = "vars";

@@ -222,3 +222,3 @@ pattern = config.varsIgnorePattern.toString();

node.parent.type === "ObjectPattern" &&
REST_PROPERTY_TYPE.test(node.parent.properties[node.parent.properties.length - 1].type);
REST_PROPERTY_TYPE.test(node.parent.properties.at(-1).type);
}

@@ -328,3 +328,3 @@

if (parent.type === "SequenceExpression") {
const isLastExpression = parent.expressions[parent.expressions.length - 1] === node;
const isLastExpression = parent.expressions.at(-1) === node;

@@ -398,3 +398,3 @@ if (!isLastExpression) {

case "SequenceExpression":
if (parent.expressions[parent.expressions.length - 1] !== node) {
if (parent.expressions.at(-1) !== node) {
return false;

@@ -630,6 +630,4 @@ }

}
}
} else if (type === "Parameter") {
if (type === "Parameter") {
// skip any setter argument

@@ -696,3 +694,3 @@ if ((def.node.parent.type === "Property" || def.node.parent.type === "MethodDefinition") && def.node.parent.kind === "set") {

if (writeReferences.length > 0) {
referenceToReport = writeReferences[writeReferences.length - 1];
referenceToReport = writeReferences.at(-1);
}

@@ -699,0 +697,0 @@

@@ -141,3 +141,3 @@ /**

messageId = "backward";
} else if (groupCut[groupCut.length - 1].type === "Alternative") {
} else if (groupCut.at(-1).type === "Alternative") {

@@ -144,0 +144,0 @@ // group's and bref's ancestor nodes below the lowest common ancestor are sibling alternatives => they're disjunctive.

@@ -220,3 +220,3 @@ /**

function getClosingBraceOfObject(node) {
const lastProperty = node.properties[node.properties.length - 1];
const lastProperty = node.properties.at(-1);

@@ -255,3 +255,3 @@ return sourceCode.getTokenAfter(lastProperty, astUtils.isClosingBraceToken);

let firstSpecifier = node.specifiers[0];
const lastSpecifier = node.specifiers[node.specifiers.length - 1];
const lastSpecifier = node.specifiers.at(-1);

@@ -284,3 +284,3 @@ if (lastSpecifier.type !== "ImportSpecifier") {

const firstSpecifier = node.specifiers[0],
lastSpecifier = node.specifiers[node.specifiers.length - 1],
lastSpecifier = node.specifiers.at(-1),
first = sourceCode.getTokenBefore(firstSpecifier),

@@ -287,0 +287,0 @@ last = sourceCode.getTokenAfter(lastSpecifier, astUtils.isNotCommaToken),

@@ -66,3 +66,3 @@ /**

const firstTokenOfFirstProperty = sourceCode.getFirstToken(node.properties[0]);
const lastTokenOfLastProperty = sourceCode.getLastToken(node.properties[node.properties.length - 1]);
const lastTokenOfLastProperty = sourceCode.getLastToken(node.properties.at(-1));

@@ -69,0 +69,0 @@ if (firstTokenOfFirstProperty.loc.end.line === lastTokenOfLastProperty.loc.start.line) {

@@ -112,3 +112,3 @@ /**

options.const = { uninitialized: mode.const, initialized: mode.const };
if (Object.prototype.hasOwnProperty.call(mode, "uninitialized")) {
if (Object.hasOwn(mode, "uninitialized")) {
options.var.uninitialized = mode.uninitialized;

@@ -118,3 +118,3 @@ options.let.uninitialized = mode.uninitialized;

}
if (Object.prototype.hasOwnProperty.call(mode, "initialized")) {
if (Object.hasOwn(mode, "initialized")) {
options.var.initialized = mode.initialized;

@@ -221,7 +221,7 @@ options.let.initialized = mode.initialized;

if (statementType === "var") {
currentScope = functionStack[functionStack.length - 1];
currentScope = functionStack.at(-1);
} else if (statementType === "let") {
currentScope = blockStack[blockStack.length - 1].let;
currentScope = blockStack.at(-1).let;
} else if (statementType === "const") {
currentScope = blockStack[blockStack.length - 1].const;
currentScope = blockStack.at(-1).const;
}

@@ -228,0 +228,0 @@ return currentScope;

@@ -87,9 +87,9 @@ /**

} else {
if (Object.prototype.hasOwnProperty.call(typeOptions, "blocks")) {
if (Object.hasOwn(typeOptions, "blocks")) {
options.blocks = typeOptions.blocks === "always";
}
if (Object.prototype.hasOwnProperty.call(typeOptions, "switches")) {
if (Object.hasOwn(typeOptions, "switches")) {
options.switches = typeOptions.switches === "always";
}
if (Object.prototype.hasOwnProperty.call(typeOptions, "classes")) {
if (Object.hasOwn(typeOptions, "classes")) {
options.classes = typeOptions.classes === "always";

@@ -99,3 +99,3 @@ }

if (Object.prototype.hasOwnProperty.call(exceptOptions, "allowSingleLineBlocks")) {
if (Object.hasOwn(exceptOptions, "allowSingleLineBlocks")) {
options.allowSingleLineBlocks = exceptOptions.allowSingleLineBlocks === true;

@@ -282,3 +282,3 @@ }

if (Object.prototype.hasOwnProperty.call(options, "switches")) {
if (Object.hasOwn(options, "switches")) {
rule.SwitchStatement = function(node) {

@@ -292,3 +292,3 @@ if (node.cases.length === 0) {

if (Object.prototype.hasOwnProperty.call(options, "blocks")) {
if (Object.hasOwn(options, "blocks")) {
rule.BlockStatement = function(node) {

@@ -303,3 +303,3 @@ if (node.body.length === 0) {

if (Object.prototype.hasOwnProperty.call(options, "classes")) {
if (Object.hasOwn(options, "classes")) {
rule.ClassBody = function(node) {

@@ -306,0 +306,0 @@ if (node.body.length === 0) {

@@ -223,3 +223,3 @@ /**

ThisExpression() {
const info = stack[stack.length - 1];
const info = stack.at(-1);

@@ -232,3 +232,3 @@ if (info) {

Super() {
const info = stack[stack.length - 1];
const info = stack.at(-1);

@@ -241,3 +241,3 @@ if (info) {

MetaProperty(node) {
const info = stack[stack.length - 1];
const info = stack.at(-1);

@@ -244,0 +244,0 @@ if (info && checkMetaProperty(node, "new", "target")) {

@@ -108,3 +108,3 @@ /**

const isReflectCall = (node.callee.object || {}).name === "Reflect";
const hasReflectSubstitute = Object.prototype.hasOwnProperty.call(reflectSubstitutes, methodName);
const hasReflectSubstitute = Object.hasOwn(reflectSubstitutes, methodName);
const userConfiguredException = exceptions.includes(methodName);

@@ -111,0 +111,0 @@

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

function isRegexLiteral(node) {
return node.type === "Literal" && Object.prototype.hasOwnProperty.call(node, "regex");
return node.type === "Literal" && Object.hasOwn(node, "regex");
}

@@ -40,0 +40,0 @@

@@ -116,3 +116,3 @@ /**

if (node.type === "TemplateLiteral") {
return node.expressions.length && node.quasis.length && node.quasis[node.quasis.length - 1].range[0] === node.quasis[node.quasis.length - 1].range[1];
return node.expressions.length && node.quasis.length && node.quasis.at(-1).range[0] === node.quasis.at(-1).range[1];
}

@@ -119,0 +119,0 @@ return node.type !== "Literal" || typeof node.value !== "string";

@@ -136,4 +136,4 @@ /**

const tokens = sourceCode.getTokens(node);
const lastToken = tokens[tokens.length - 1]; // Parenthesis.
const secondToLastToken = tokens[tokens.length - 2]; // May or may not be a comma.
const lastToken = tokens.at(-1); // Parenthesis.
const secondToLastToken = tokens.at(-2); // May or may not be a comma.
const hasTrailingComma = secondToLastToken.type === "Punctuator" && secondToLastToken.value === ",";

@@ -140,0 +140,0 @@

@@ -68,3 +68,3 @@ /**

return nodeList !== null && nodeList[nodeList.length - 1] === node; // before `}` or etc.
return nodeList !== null && nodeList.at(-1) === node; // before `}` or etc.
}

@@ -71,0 +71,0 @@

@@ -211,3 +211,3 @@ /**

return fixer.replaceTextRange(
[importSpecifiers[0].range[0], importSpecifiers[importSpecifiers.length - 1].range[1]],
[importSpecifiers[0].range[0], importSpecifiers.at(-1).range[1]],
importSpecifiers

@@ -214,0 +214,0 @@

@@ -188,3 +188,3 @@ /**

// check blank line between the current node and the last token
if (!isBlankLineBetweenNodes && (node.loc.start.line - tokens[tokens.length - 1].loc.end.line > 1)) {
if (!isBlankLineBetweenNodes && (node.loc.start.line - tokens.at(-1).loc.end.line > 1)) {
isBlankLineBetweenNodes = true;

@@ -191,0 +191,0 @@ }

@@ -69,3 +69,3 @@ /**

return fixer.replaceTextRange(
[idDeclarations[0].range[0], idDeclarations[idDeclarations.length - 1].range[1]],
[idDeclarations[0].range[0], idDeclarations.at(-1).range[1]],
idDeclarations

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

@@ -90,3 +90,3 @@ /**

function overrideExistsForOperator(operator) {
return options.overrides && Object.prototype.hasOwnProperty.call(options.overrides, operator);
return options.overrides && Object.hasOwn(options.overrides, operator);
}

@@ -93,0 +93,0 @@

@@ -176,3 +176,3 @@ /**

isParentGlobal = scopes.length === 0 && classScopes.length === 0,
isParentStrict = scopes.length > 0 && scopes[scopes.length - 1],
isParentStrict = scopes.length > 0 && scopes.at(-1),
isStrict = useStrictDirectives.length > 0;

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

@@ -82,3 +82,3 @@ /**

const node = after ? leftToken : rightToken;
let messageId = "";
let messageId;

@@ -85,0 +85,0 @@ if (spaceRequired) {

@@ -418,6 +418,6 @@ /**

while ((match = lineEndingPattern.exec(this.text))) {
this.lines.push(this.text.slice(this.lineStartIndices[this.lineStartIndices.length - 1], match.index));
this.lines.push(this.text.slice(this.lineStartIndices.at(-1), match.index));
this.lineStartIndices.push(match.index + match[0].length);
}
this.lines.push(this.text.slice(this.lineStartIndices[this.lineStartIndices.length - 1]));
this.lines.push(this.text.slice(this.lineStartIndices.at(-1)));

@@ -627,3 +627,3 @@ // don't allow further modification of this object

if (index === this.text.length) {
return { line: this.lines.length, column: this.lines[this.lines.length - 1].length };
return { line: this.lines.length, column: this.lines.at(-1).length };
}

@@ -635,3 +635,3 @@

*/
const lineNumber = index >= this.lineStartIndices[this.lineStartIndices.length - 1]
const lineNumber = index >= this.lineStartIndices.at(-1)
? this.lineStartIndices.length

@@ -638,0 +638,0 @@ : this.lineStartIndices.findIndex(el => index < el);

@@ -40,4 +40,4 @@ /**

let commentIndex = 0;
let nextStart = 0;
let range = null;
let nextStart;
let range;

@@ -44,0 +44,0 @@ while (tokenIndex < tokens.length || commentIndex < comments.length) {

{
"name": "eslint",
"version": "9.0.0-alpha.0",
"version": "9.0.0-alpha.1",
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",

@@ -70,3 +70,3 @@ "description": "An AST-based pattern checker for JavaScript.",

"@eslint/js": "9.0.0-alpha.0",
"@humanwhocodes/config-array": "^0.11.13",
"@humanwhocodes/config-array": "^0.11.14",
"@humanwhocodes/module-importer": "^1.0.1",

@@ -79,3 +79,3 @@ "@nodelib/fs.walk": "^1.2.8",

"escape-string-regexp": "^4.0.0",
"eslint-scope": "^7.2.2",
"eslint-scope": "^8.0.0",
"eslint-visitor-keys": "^3.4.3",

@@ -132,3 +132,3 @@ "espree": "^9.6.1",

"fs-teardown": "^0.1.3",
"glob": "^7.1.6",
"glob": "^10.0.0",
"got": "^11.8.3",

@@ -135,0 +135,0 @@ "gray-matter": "^4.0.3",

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

</td><td align="center" valign="top" width="11%">
<a href="https://github.com/JoshuaKGoldberg">
<img src="https://github.com/JoshuaKGoldberg.png?s=75" width="75" height="75" alt="Josh Goldberg ✨'s Avatar"><br />
Josh Goldberg ✨
</a>
</td><td align="center" valign="top" width="11%">
<a href="https://github.com/fasttime">

@@ -250,0 +255,0 @@ <img src="https://github.com/fasttime.png?s=75" width="75" height="75" alt="Francesco Trotta's Avatar"><br />

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

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

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

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc