eslint
Advanced tools
Comparing version 8.27.0 to 8.28.0
@@ -29,2 +29,3 @@ /** | ||
const Minimatch = minimatch.Minimatch; | ||
const MINIMATCH_OPTIONS = { dot: true }; | ||
@@ -80,3 +81,3 @@ //----------------------------------------------------------------------------- | ||
this.basePath = basePath; | ||
this.patternsToCheck = unmatchedPatterns; | ||
this.unmatchedPatterns = unmatchedPatterns; | ||
this.patterns = patterns; | ||
@@ -163,3 +164,3 @@ this.rawPatterns = rawPatterns; | ||
const matcher = new Minimatch(patternToUse); | ||
const matcher = new Minimatch(patternToUse, MINIMATCH_OPTIONS); | ||
@@ -263,3 +264,3 @@ const fsWalkSettings = { | ||
return new minimatch.Minimatch(patternToUse); | ||
return new Minimatch(patternToUse, MINIMATCH_OPTIONS); | ||
}); | ||
@@ -344,5 +345,4 @@ | ||
/** | ||
* Checks to see if there are any ignored results for a given search. This | ||
* happens either when there are unmatched patterns during a search or if | ||
* a search returns no results. | ||
* Throws an error for unmatched patterns. The error will only contain information about the first one. | ||
* Checks to see if there are any ignored results for a given search. | ||
* @param {Object} options The options for this function. | ||
@@ -354,36 +354,31 @@ * @param {string} options.basePath The directory to search. | ||
* as the user inputted them. Used for errors. | ||
* @param {Array<string>} options.patternsToCheck An array of glob patterns | ||
* to use for this check. | ||
* @returns {void} | ||
* @throws {NoFilesFoundError} If there is a pattern that doesn't match | ||
* any files and `errorOnUnmatchedPattern` is true. | ||
* @throws {AllFilesIgnoredError} If there is a pattern that matches files | ||
* when there are no ignores. | ||
* @param {Array<string>} options.unmatchedPatterns A non-empty array of glob patterns | ||
* that were unmatched in the original search. | ||
* @returns {void} Always throws an error. | ||
* @throws {NoFilesFoundError} If the first unmatched pattern | ||
* doesn't match any files even when there are no ignores. | ||
* @throws {AllFilesIgnoredError} If the first unmatched pattern | ||
* matches some files when there are no ignores. | ||
*/ | ||
async function checkForIgnoredResults({ | ||
async function throwErrorForUnmatchedPatterns({ | ||
basePath, | ||
patterns, | ||
rawPatterns, | ||
patternsToCheck = patterns | ||
unmatchedPatterns | ||
}) { | ||
for (const pattern of patternsToCheck) { | ||
const pattern = unmatchedPatterns[0]; | ||
const rawPattern = rawPatterns[patterns.indexOf(pattern)]; | ||
const patternHasMatch = await globMatch({ | ||
basePath, | ||
pattern | ||
}); | ||
const patternHasMatch = await globMatch({ | ||
basePath, | ||
pattern | ||
}); | ||
if (patternHasMatch) { | ||
throw new AllFilesIgnoredError( | ||
rawPatterns[patterns.indexOf(pattern)] | ||
); | ||
} | ||
if (patternHasMatch) { | ||
throw new AllFilesIgnoredError(rawPattern); | ||
} | ||
// if we get here there are truly no matches | ||
throw new NoFilesFoundError( | ||
rawPatterns[patterns.indexOf(patternsToCheck[0])], | ||
true | ||
); | ||
throw new NoFilesFoundError(rawPattern, true); | ||
} | ||
@@ -455,5 +450,5 @@ | ||
await checkForIgnoredResults({ | ||
await throwErrorForUnmatchedPatterns({ | ||
...currentSearch, | ||
patternsToCheck: error.patternsToCheck | ||
unmatchedPatterns: error.unmatchedPatterns | ||
}); | ||
@@ -460,0 +455,0 @@ |
@@ -18,3 +18,3 @@ /** | ||
docs: { | ||
description: "Enforce \"for\" loop update clause moving the counter in the right direction.", | ||
description: "Enforce \"for\" loop update clause moving the counter in the right direction", | ||
recommended: true, | ||
@@ -21,0 +21,0 @@ url: "https://eslint.org/docs/rules/for-direction" |
@@ -338,2 +338,15 @@ /** | ||
/** | ||
* Determines if the given property is key-value property. | ||
* @param {ASTNode} property Property node to check. | ||
* @returns {boolean} Whether the property is a key-value property. | ||
*/ | ||
function isKeyValueProperty(property) { | ||
return !( | ||
(property.method || | ||
property.shorthand || | ||
property.kind !== "init" || property.type !== "Property") // Could be "ExperimentalSpreadProperty" or "SpreadElement" | ||
); | ||
} | ||
/** | ||
* Checks whether a property is a member of the property group it follows. | ||
@@ -346,5 +359,5 @@ * @param {ASTNode} lastMember The last Property known to be in the group. | ||
const groupEndLine = lastMember.loc.start.line, | ||
candidateStartLine = candidate.loc.start.line; | ||
candidateValueStartLine = (isKeyValueProperty(candidate) ? candidate.value : candidate).loc.start.line; | ||
if (candidateStartLine - groupEndLine <= 1) { | ||
if (candidateValueStartLine - groupEndLine <= 1) { | ||
return true; | ||
@@ -363,3 +376,3 @@ } | ||
leadingComments[0].loc.start.line - groupEndLine <= 1 && | ||
candidateStartLine - last(leadingComments).loc.end.line <= 1 | ||
candidateValueStartLine - last(leadingComments).loc.end.line <= 1 | ||
) { | ||
@@ -378,15 +391,2 @@ for (let i = 1; i < leadingComments.length; i++) { | ||
/** | ||
* Determines if the given property is key-value property. | ||
* @param {ASTNode} property Property node to check. | ||
* @returns {boolean} Whether the property is a key-value property. | ||
*/ | ||
function isKeyValueProperty(property) { | ||
return !( | ||
(property.method || | ||
property.shorthand || | ||
property.kind !== "init" || property.type !== "Property") // Could be "ExperimentalSpreadProperty" or "SpreadElement" | ||
); | ||
} | ||
/** | ||
* Starting from the given a node (a property.key node here) looks forward | ||
@@ -393,0 +393,0 @@ * until it finds the last token before a colon punctuator and returns it. |
@@ -75,2 +75,20 @@ /** | ||
/** | ||
* Checks whether the given node logically represents multiplication by a fraction of `1`. | ||
* For example, `a * 1` in `a * 1 / b` is technically multiplication by `1`, but the | ||
* whole expression can be logically interpreted as `a * (1 / b)` rather than `(a * 1) / b`. | ||
* @param {BinaryExpression} node A BinaryExpression node to check. | ||
* @param {SourceCode} sourceCode The source code object. | ||
* @returns {boolean} Whether or not the node is a multiplying by a fraction of `1`. | ||
*/ | ||
function isMultiplyByFractionOfOne(node, sourceCode) { | ||
return node.type === "BinaryExpression" && | ||
node.operator === "*" && | ||
(node.right.type === "Literal" && node.right.value === 1) && | ||
node.parent.type === "BinaryExpression" && | ||
node.parent.operator === "/" && | ||
node.parent.left === node && | ||
!astUtils.isParenthesised(sourceCode, node); | ||
} | ||
/** | ||
* Checks whether the result of a node is numeric or not | ||
@@ -294,3 +312,4 @@ * @param {ASTNode} node The node to test | ||
operatorAllowed = options.allow.includes("*"); | ||
const nonNumericOperand = !operatorAllowed && options.number && isMultiplyByOne(node) && getNonNumericOperand(node); | ||
const nonNumericOperand = !operatorAllowed && options.number && isMultiplyByOne(node) && !isMultiplyByFractionOfOne(node, sourceCode) && | ||
getNonNumericOperand(node); | ||
@@ -297,0 +316,0 @@ if (nonNumericOperand) { |
@@ -68,2 +68,6 @@ /** | ||
default: false | ||
}, | ||
ignoreClassFieldInitialValues: { | ||
type: "boolean", | ||
default: false | ||
} | ||
@@ -86,3 +90,4 @@ }, | ||
ignoreArrayIndexes = !!config.ignoreArrayIndexes, | ||
ignoreDefaultValues = !!config.ignoreDefaultValues; | ||
ignoreDefaultValues = !!config.ignoreDefaultValues, | ||
ignoreClassFieldInitialValues = !!config.ignoreClassFieldInitialValues; | ||
@@ -112,2 +117,13 @@ const okTypes = detectObjects ? [] : ["ObjectExpression", "Property", "AssignmentExpression"]; | ||
/** | ||
* Returns whether the number is the initial value of a class field. | ||
* @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node | ||
* @returns {boolean} true if the number is the initial value of a class field. | ||
*/ | ||
function isClassFieldInitialValue(fullNumberNode) { | ||
const parent = fullNumberNode.parent; | ||
return parent.type === "PropertyDefinition" && parent.value === fullNumberNode; | ||
} | ||
/** | ||
* Returns whether the given node is used as a radix within parseInt() or Number.parseInt() | ||
@@ -200,2 +216,3 @@ * @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node | ||
(ignoreDefaultValues && isDefaultValue(fullNumberNode)) || | ||
(ignoreClassFieldInitialValues && isClassFieldInitialValue(fullNumberNode)) || | ||
isParseIntRadix(fullNumberNode) || | ||
@@ -202,0 +219,0 @@ isJSXNumber(fullNumberNode) || |
@@ -19,3 +19,3 @@ /** | ||
const nonCallableGlobals = ["Atomics", "JSON", "Math", "Reflect"]; | ||
const nonCallableGlobals = ["Atomics", "JSON", "Math", "Reflect", "Intl"]; | ||
@@ -22,0 +22,0 @@ /** |
@@ -250,3 +250,3 @@ /** | ||
description: | ||
"Disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead.", | ||
"Disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead", | ||
recommended: false, | ||
@@ -253,0 +253,0 @@ url: "https://eslint.org/docs/rules/prefer-object-spread" |
@@ -100,3 +100,3 @@ /** | ||
const npmBinArgs = ["bin", "-g"]; | ||
const npmLsArgs = ["ls", "--depth=0", "--json", "eslint"]; | ||
const npmLsArgs = ["ls", "--depth=0", "--json", pkg]; | ||
@@ -103,0 +103,0 @@ if (global) { |
{ | ||
"name": "eslint", | ||
"version": "8.27.0", | ||
"version": "8.28.0", | ||
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>", | ||
@@ -5,0 +5,0 @@ "description": "An AST-based pattern checker for JavaScript.", |
2845523
67537