eslint-utils
Advanced tools
Comparing version 2.1.0 to 3.0.0
260
index.js
@@ -84,2 +84,12 @@ /*! @author Toru Nagashima <https://github.com/mysticatea> */ | ||
/** | ||
* Checks if the given token is a PunctuatorToken with the given value | ||
* @param {Token} token - The token to check. | ||
* @param {string} value - The value to check. | ||
* @returns {boolean} `true` if the token is a PunctuatorToken with the given value. | ||
*/ | ||
function isPunctuatorTokenWithValue(token, value) { | ||
return token.type === "Punctuator" && token.value === value | ||
} | ||
/** | ||
* Checks if the given token is an arrow token or not. | ||
@@ -90,3 +100,3 @@ * @param {Token} token - The token to check. | ||
function isArrowToken(token) { | ||
return token.value === "=>" && token.type === "Punctuator" | ||
return isPunctuatorTokenWithValue(token, "=>") | ||
} | ||
@@ -100,3 +110,3 @@ | ||
function isCommaToken(token) { | ||
return token.value === "," && token.type === "Punctuator" | ||
return isPunctuatorTokenWithValue(token, ",") | ||
} | ||
@@ -110,3 +120,3 @@ | ||
function isSemicolonToken(token) { | ||
return token.value === ";" && token.type === "Punctuator" | ||
return isPunctuatorTokenWithValue(token, ";") | ||
} | ||
@@ -120,3 +130,3 @@ | ||
function isColonToken(token) { | ||
return token.value === ":" && token.type === "Punctuator" | ||
return isPunctuatorTokenWithValue(token, ":") | ||
} | ||
@@ -130,3 +140,3 @@ | ||
function isOpeningParenToken(token) { | ||
return token.value === "(" && token.type === "Punctuator" | ||
return isPunctuatorTokenWithValue(token, "(") | ||
} | ||
@@ -140,3 +150,3 @@ | ||
function isClosingParenToken(token) { | ||
return token.value === ")" && token.type === "Punctuator" | ||
return isPunctuatorTokenWithValue(token, ")") | ||
} | ||
@@ -150,3 +160,3 @@ | ||
function isOpeningBracketToken(token) { | ||
return token.value === "[" && token.type === "Punctuator" | ||
return isPunctuatorTokenWithValue(token, "[") | ||
} | ||
@@ -160,3 +170,3 @@ | ||
function isClosingBracketToken(token) { | ||
return token.value === "]" && token.type === "Punctuator" | ||
return isPunctuatorTokenWithValue(token, "]") | ||
} | ||
@@ -170,3 +180,3 @@ | ||
function isOpeningBraceToken(token) { | ||
return token.value === "{" && token.type === "Punctuator" | ||
return isPunctuatorTokenWithValue(token, "{") | ||
} | ||
@@ -180,3 +190,3 @@ | ||
function isClosingBraceToken(token) { | ||
return token.value === "}" && token.type === "Punctuator" | ||
return isPunctuatorTokenWithValue(token, "}") | ||
} | ||
@@ -190,7 +200,3 @@ | ||
function isCommentToken(token) { | ||
return ( | ||
token.type === "Line" || | ||
token.type === "Block" || | ||
token.type === "Shebang" | ||
) | ||
return ["Block", "Line", "Shebang"].includes(token.type) | ||
} | ||
@@ -240,3 +246,4 @@ | ||
parent.type === "Property" || | ||
parent.type === "MethodDefinition" | ||
parent.type === "MethodDefinition" || | ||
parent.type === "PropertyDefinition" | ||
) { | ||
@@ -251,8 +258,8 @@ start = parent.loc.start; | ||
return { | ||
start: Object.assign({}, start), | ||
end: Object.assign({}, end), | ||
start: { ...start }, | ||
end: { ...end }, | ||
} | ||
} | ||
/* globals BigInt, globalThis, global, self, window */ | ||
/* globals globalThis, global, self, window */ | ||
@@ -318,3 +325,3 @@ const globalObject = | ||
"WeakSet", | ||
]) | ||
]), | ||
); | ||
@@ -337,4 +344,4 @@ const callAllowed = new Set( | ||
...Object.getOwnPropertyNames(Math) | ||
.map(k => Math[k]) | ||
.filter(f => typeof f === "function"), | ||
.map((k) => Math[k]) | ||
.filter((f) => typeof f === "function"), | ||
Number, | ||
@@ -360,7 +367,6 @@ Number.isFinite, | ||
String.raw, | ||
Symbol, | ||
Symbol.for, | ||
Symbol.keyFor, | ||
unescape, | ||
].filter(f => typeof f === "function") | ||
].filter((f) => typeof f === "function"), | ||
); | ||
@@ -510,2 +516,5 @@ const callPassThrough = new Set([ | ||
if (calleeNode.type === "MemberExpression") { | ||
if (calleeNode.property.type === "PrivateIdentifier") { | ||
return null | ||
} | ||
const object = getStaticValueR(calleeNode.object, initialScope); | ||
@@ -519,5 +528,6 @@ if (object != null) { | ||
} | ||
const property = calleeNode.computed | ||
? getStaticValueR(calleeNode.property, initialScope) | ||
: { value: calleeNode.property.name }; | ||
const property = getStaticPropertyNameValue( | ||
calleeNode, | ||
initialScope, | ||
); | ||
@@ -629,2 +639,5 @@ if (property != null) { | ||
MemberExpression(node, initialScope) { | ||
if (node.property.type === "PrivateIdentifier") { | ||
return null | ||
} | ||
const object = getStaticValueR(node.object, initialScope); | ||
@@ -635,5 +648,3 @@ if (object != null) { | ||
} | ||
const property = node.computed | ||
? getStaticValueR(node.property, initialScope) | ||
: { value: node.property.name }; | ||
const property = getStaticPropertyNameValue(node, initialScope); | ||
@@ -677,5 +688,6 @@ if (property != null && !isGetter(object.value, property.value)) { | ||
} | ||
const key = propertyNode.computed | ||
? getStaticValueR(propertyNode.key, initialScope) | ||
: { value: propertyNode.key.name }; | ||
const key = getStaticPropertyNameValue( | ||
propertyNode, | ||
initialScope, | ||
); | ||
const value = getStaticValueR(propertyNode.value, initialScope); | ||
@@ -692,3 +704,3 @@ if (key == null || value == null) { | ||
propertyNode.argument, | ||
initialScope | ||
initialScope, | ||
); | ||
@@ -716,3 +728,3 @@ if (argument == null) { | ||
node.quasi.expressions, | ||
initialScope | ||
initialScope, | ||
); | ||
@@ -722,4 +734,4 @@ | ||
const func = tag.value; | ||
const strings = node.quasi.quasis.map(q => q.value.cooked); | ||
strings.raw = node.quasi.quasis.map(q => q.value.raw); | ||
const strings = node.quasi.quasis.map((q) => q.value.cooked); | ||
strings.raw = node.quasi.quasis.map((q) => q.value.raw); | ||
@@ -792,2 +804,29 @@ if (func === String.raw) { | ||
/** | ||
* Get the static value of property name from a MemberExpression node or a Property node. | ||
* @param {Node} node The node to get. | ||
* @param {Scope} [initialScope] The scope to start finding variable. Optional. If the node is a computed property node and this scope was given, this checks the computed property name by the `getStringIfConstant` function with the scope, and returns the value of it. | ||
* @returns {{value:any}|{value:undefined,optional?:true}|null} The static value of the property name of the node, or `null`. | ||
*/ | ||
function getStaticPropertyNameValue(node, initialScope) { | ||
const nameNode = node.type === "Property" ? node.key : node.property; | ||
if (node.computed) { | ||
return getStaticValueR(nameNode, initialScope) | ||
} | ||
if (nameNode.type === "Identifier") { | ||
return { value: nameNode.name } | ||
} | ||
if (nameNode.type === "Literal") { | ||
if (nameNode.bigint) { | ||
return { value: nameNode.bigint } | ||
} | ||
return { value: String(nameNode.value) } | ||
} | ||
return null | ||
} | ||
/** | ||
* Get the value of a given node if it's a static value. | ||
@@ -839,2 +878,5 @@ * @param {Node} node The node to get. | ||
} | ||
if (node.property.type === "PrivateIdentifier") { | ||
return null | ||
} | ||
return node.property.name | ||
@@ -844,2 +886,3 @@ | ||
case "MethodDefinition": | ||
case "PropertyDefinition": | ||
if (node.computed) { | ||
@@ -851,2 +894,5 @@ return getStringIfConstant(node.key, initialScope) | ||
} | ||
if (node.key.type === "PrivateIdentifier") { | ||
return null | ||
} | ||
return node.key.name | ||
@@ -863,10 +909,23 @@ | ||
* @param {ASTNode} node - The function node to get. | ||
* @param {SourceCode} [sourceCode] The source code object to get the code of computed property keys. | ||
* @returns {string} The name and kind of the function node. | ||
*/ | ||
function getFunctionNameWithKind(node) { | ||
// eslint-disable-next-line complexity | ||
function getFunctionNameWithKind(node, sourceCode) { | ||
const parent = node.parent; | ||
const tokens = []; | ||
const isObjectMethod = parent.type === "Property" && parent.value === node; | ||
const isClassMethod = | ||
parent.type === "MethodDefinition" && parent.value === node; | ||
const isClassFieldMethod = | ||
parent.type === "PropertyDefinition" && parent.value === node; | ||
if (parent.type === "MethodDefinition" && parent.static) { | ||
tokens.push("static"); | ||
// Modifiers. | ||
if (isClassMethod || isClassFieldMethod) { | ||
if (parent.static) { | ||
tokens.push("static"); | ||
} | ||
if (parent.key.type === "PrivateIdentifier") { | ||
tokens.push("private"); | ||
} | ||
} | ||
@@ -880,8 +939,4 @@ if (node.async) { | ||
if (node.type === "ArrowFunctionExpression") { | ||
tokens.push("arrow", "function"); | ||
} else if ( | ||
parent.type === "Property" || | ||
parent.type === "MethodDefinition" | ||
) { | ||
// Kinds. | ||
if (isObjectMethod || isClassMethod) { | ||
if (parent.kind === "constructor") { | ||
@@ -897,33 +952,43 @@ return "constructor" | ||
} | ||
} else if (isClassFieldMethod) { | ||
tokens.push("method"); | ||
} else { | ||
if (node.type === "ArrowFunctionExpression") { | ||
tokens.push("arrow"); | ||
} | ||
tokens.push("function"); | ||
} | ||
if (node.id) { | ||
// Names. | ||
if (isObjectMethod || isClassMethod || isClassFieldMethod) { | ||
if (parent.key.type === "PrivateIdentifier") { | ||
tokens.push(`#${parent.key.name}`); | ||
} else { | ||
const name = getPropertyName(parent); | ||
if (name) { | ||
tokens.push(`'${name}'`); | ||
} else if (sourceCode) { | ||
const keyText = sourceCode.getText(parent.key); | ||
if (!keyText.includes("\n")) { | ||
tokens.push(`[${keyText}]`); | ||
} | ||
} | ||
} | ||
} else if (node.id) { | ||
tokens.push(`'${node.id.name}'`); | ||
} else { | ||
const name = getPropertyName(parent); | ||
if (name) { | ||
tokens.push(`'${name}'`); | ||
} | ||
} else if ( | ||
parent.type === "VariableDeclarator" && | ||
parent.id && | ||
parent.id.type === "Identifier" | ||
) { | ||
tokens.push(`'${parent.id.name}'`); | ||
} else if ( | ||
(parent.type === "AssignmentExpression" || | ||
parent.type === "AssignmentPattern") && | ||
parent.left && | ||
parent.left.type === "Identifier" | ||
) { | ||
tokens.push(`'${parent.left.name}'`); | ||
} | ||
if (node.type === "ArrowFunctionExpression") { | ||
if ( | ||
parent.type === "VariableDeclarator" && | ||
parent.id && | ||
parent.id.type === "Identifier" | ||
) { | ||
tokens.push(`'${parent.id.name}'`); | ||
} | ||
if ( | ||
parent.type === "AssignmentExpression" && | ||
parent.left && | ||
parent.left.type === "Identifier" | ||
) { | ||
tokens.push(`'${parent.left.name}'`); | ||
} | ||
} | ||
return tokens.join(" ") | ||
@@ -952,3 +1017,3 @@ } | ||
"in", | ||
]) | ||
]), | ||
); | ||
@@ -1068,2 +1133,12 @@ const typeConversionUnaryOps = Object.freeze(new Set(["-", "+", "!", "~"])); | ||
}, | ||
PropertyDefinition(node, options, visitorKeys) { | ||
if ( | ||
options.considerImplicitTypeConversion && | ||
node.computed && | ||
node.key.type !== "Literal" | ||
) { | ||
return true | ||
} | ||
return this.$visitChildren(node, options, visitorKeys) | ||
}, | ||
UnaryExpression(node, options, visitorKeys) { | ||
@@ -1088,3 +1163,3 @@ if (node.operator === "delete") { | ||
}, | ||
}) | ||
}), | ||
); | ||
@@ -1105,3 +1180,3 @@ | ||
sourceCode, | ||
{ considerGetters = false, considerImplicitTypeConversion = false } = {} | ||
{ considerGetters = false, considerImplicitTypeConversion = false } = {}, | ||
) { | ||
@@ -1111,3 +1186,3 @@ return visitor.$visit( | ||
{ considerGetters, considerImplicitTypeConversion }, | ||
sourceCode.visitorKeys || evk.KEYS | ||
sourceCode.visitorKeys || evk.KEYS, | ||
) | ||
@@ -1132,3 +1207,3 @@ } | ||
parent.callee, | ||
isOpeningParenToken | ||
isOpeningParenToken, | ||
) | ||
@@ -1142,3 +1217,3 @@ } | ||
parent.body, | ||
isOpeningParenToken | ||
isOpeningParenToken, | ||
) | ||
@@ -1194,3 +1269,3 @@ } | ||
nodeOrSourceCode, | ||
optionalSourceCode | ||
optionalSourceCode, | ||
) { | ||
@@ -1211,3 +1286,7 @@ let times, node, sourceCode, maybeLeftParen, maybeRightParen; | ||
if (node == null) { | ||
if ( | ||
node == null || | ||
// `CatchClause.param` can't be parenthesized, example `try {} catch (error) {}` | ||
(node.parent.type === "CatchClause" && node.parent.param === node) | ||
) { | ||
return false | ||
@@ -1412,3 +1491,3 @@ } | ||
variable.defs.length !== 0 || | ||
variable.references.some(r => r.isWrite()) | ||
variable.references.some((r) => r.isWrite()) | ||
) | ||
@@ -1457,3 +1536,3 @@ } | ||
globalObjectNames = ["global", "globalThis", "self", "window"], | ||
} = {} | ||
} = {}, | ||
) { | ||
@@ -1485,3 +1564,3 @@ this.variableStack = []; | ||
nextTraceMap, | ||
true | ||
true, | ||
); | ||
@@ -1502,3 +1581,3 @@ } | ||
traceMap, | ||
false | ||
false, | ||
); | ||
@@ -1580,7 +1659,4 @@ } | ||
: this.mode === "legacy" | ||
? Object.assign( | ||
{ default: nextTraceMap }, | ||
nextTraceMap | ||
) | ||
: { default: nextTraceMap } | ||
? { default: nextTraceMap, ...nextTraceMap } | ||
: { default: nextTraceMap }, | ||
); | ||
@@ -1671,3 +1747,3 @@ | ||
path, | ||
nextTraceMap | ||
nextTraceMap, | ||
); | ||
@@ -1729,3 +1805,3 @@ } | ||
traceMap, | ||
false | ||
false, | ||
); | ||
@@ -1756,3 +1832,3 @@ } | ||
nextPath, | ||
nextTraceMap | ||
nextTraceMap, | ||
); | ||
@@ -1800,3 +1876,3 @@ } | ||
nextTraceMap, | ||
false | ||
false, | ||
); | ||
@@ -1812,3 +1888,3 @@ | ||
traceMap, | ||
false | ||
false, | ||
); | ||
@@ -1815,0 +1891,0 @@ return |
{ | ||
"name": "eslint-utils", | ||
"version": "2.1.0", | ||
"version": "3.0.0", | ||
"description": "Utilities for ESLint plugins.", | ||
"engines": { | ||
"node": ">=6" | ||
"node": "^10.0.0 || ^12.0.0 || >= 14.0.0" | ||
}, | ||
@@ -14,12 +14,19 @@ "sideEffects": false, | ||
], | ||
"exports": { | ||
".": { | ||
"import": "./index.mjs", | ||
"require": "./index.js" | ||
}, | ||
"./package.json": "./package.json" | ||
}, | ||
"dependencies": { | ||
"eslint-visitor-keys": "^1.1.0" | ||
"eslint-visitor-keys": "^2.0.0" | ||
}, | ||
"devDependencies": { | ||
"@mysticatea/eslint-plugin": "^12.0.0", | ||
"@mysticatea/eslint-plugin": "^13.0.0", | ||
"codecov": "^3.6.1", | ||
"dot-prop": "^4.2.0", | ||
"eslint": "^6.5.1", | ||
"eslint": "^7.24.0", | ||
"esm": "^3.2.25", | ||
"espree": "^6.1.1", | ||
"espree": "github:eslint/espree#1c744b3a602b783926344811a9459b92afe57444", | ||
"mocha": "^6.2.2", | ||
@@ -29,2 +36,3 @@ "npm-run-all": "^4.1.5", | ||
"opener": "^1.5.1", | ||
"prettier": "~2.3.0", | ||
"rimraf": "^3.0.0", | ||
@@ -37,2 +45,5 @@ "rollup": "^1.25.0", | ||
}, | ||
"peerDependencies": { | ||
"eslint": ">=5" | ||
}, | ||
"scripts": { | ||
@@ -46,4 +57,6 @@ "prebuild": "npm run -s clean", | ||
"docs:watch": "vuepress dev docs", | ||
"lint": "eslint src test", | ||
"test": "run-s lint build test:mocha", | ||
"format": "npm run -s format:prettier -- --write", | ||
"format:prettier": "prettier docs/.vuepress/config.js src/**/*.js test/**/*.js rollup.config.js .vscode/*.json *.json .github/**/*.yml *.yml docs/**/*.md *.md", | ||
"lint": "eslint docs/.vuepress/config.js src test rollup.config.js", | ||
"test": "run-s \"format:prettier -- --check\" lint build test:mocha", | ||
"test:mocha": "nyc mocha --reporter dot \"test/*.js\"", | ||
@@ -50,0 +63,0 @@ "preversion": "npm test && npm run -s build", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
358383
3517
2
17
+ Added@eslint-community/eslint-utils@4.4.0(transitive)
+ Added@eslint-community/regexpp@4.10.0(transitive)
+ Added@eslint/eslintrc@3.0.2(transitive)
+ Added@eslint/js@9.2.0(transitive)
+ Added@humanwhocodes/config-array@0.13.0(transitive)
+ Added@humanwhocodes/module-importer@1.0.1(transitive)
+ Added@humanwhocodes/object-schema@2.0.3(transitive)
+ Added@humanwhocodes/retry@0.2.4(transitive)
+ Added@nodelib/fs.scandir@2.1.5(transitive)
+ Added@nodelib/fs.stat@2.0.5(transitive)
+ Added@nodelib/fs.walk@1.2.8(transitive)
+ Addedacorn@8.11.3(transitive)
+ Addedacorn-jsx@5.3.2(transitive)
+ Addedajv@6.12.6(transitive)
+ Addedansi-regex@5.0.1(transitive)
+ Addedansi-styles@4.3.0(transitive)
+ Addedargparse@2.0.1(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedcallsites@3.1.0(transitive)
+ Addedchalk@4.1.2(transitive)
+ Addedcolor-convert@2.0.1(transitive)
+ Addedcolor-name@1.1.4(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedcross-spawn@7.0.3(transitive)
+ Addeddebug@4.3.4(transitive)
+ Addeddeep-is@0.1.4(transitive)
+ Addedescape-string-regexp@4.0.0(transitive)
+ Addedeslint@9.2.0(transitive)
+ Addedeslint-scope@8.0.1(transitive)
+ Addedeslint-visitor-keys@2.1.03.4.34.0.0(transitive)
+ Addedespree@10.0.1(transitive)
+ Addedesquery@1.5.0(transitive)
+ Addedesrecurse@4.3.0(transitive)
+ Addedestraverse@5.3.0(transitive)
+ Addedesutils@2.0.3(transitive)
+ Addedfast-deep-equal@3.1.3(transitive)
+ Addedfast-json-stable-stringify@2.1.0(transitive)
+ Addedfast-levenshtein@2.0.6(transitive)
+ Addedfastq@1.17.1(transitive)
+ Addedfile-entry-cache@8.0.0(transitive)
+ Addedfind-up@5.0.0(transitive)
+ Addedflat-cache@4.0.1(transitive)
+ Addedflatted@3.3.1(transitive)
+ Addedglob-parent@6.0.2(transitive)
+ Addedglobals@14.0.0(transitive)
+ Addedhas-flag@4.0.0(transitive)
+ Addedignore@5.3.1(transitive)
+ Addedimport-fresh@3.3.0(transitive)
+ Addedimurmurhash@0.1.4(transitive)
+ Addedis-extglob@2.1.1(transitive)
+ Addedis-glob@4.0.3(transitive)
+ Addedis-path-inside@3.0.3(transitive)
+ Addedisexe@2.0.0(transitive)
+ Addedjs-yaml@4.1.0(transitive)
+ Addedjson-buffer@3.0.1(transitive)
+ Addedjson-schema-traverse@0.4.1(transitive)
+ Addedjson-stable-stringify-without-jsonify@1.0.1(transitive)
+ Addedkeyv@4.5.4(transitive)
+ Addedlevn@0.4.1(transitive)
+ Addedlocate-path@6.0.0(transitive)
+ Addedlodash.merge@4.6.2(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedms@2.1.2(transitive)
+ Addednatural-compare@1.4.0(transitive)
+ Addedoptionator@0.9.4(transitive)
+ Addedp-limit@3.1.0(transitive)
+ Addedp-locate@5.0.0(transitive)
+ Addedparent-module@1.0.1(transitive)
+ Addedpath-exists@4.0.0(transitive)
+ Addedpath-key@3.1.1(transitive)
+ Addedprelude-ls@1.2.1(transitive)
+ Addedpunycode@2.3.1(transitive)
+ Addedqueue-microtask@1.2.3(transitive)
+ Addedresolve-from@4.0.0(transitive)
+ Addedreusify@1.0.4(transitive)
+ Addedrun-parallel@1.2.0(transitive)
+ Addedshebang-command@2.0.0(transitive)
+ Addedshebang-regex@3.0.0(transitive)
+ Addedstrip-ansi@6.0.1(transitive)
+ Addedstrip-json-comments@3.1.1(transitive)
+ Addedsupports-color@7.2.0(transitive)
+ Addedtext-table@0.2.0(transitive)
+ Addedtype-check@0.4.0(transitive)
+ Addeduri-js@4.4.1(transitive)
+ Addedwhich@2.0.2(transitive)
+ Addedword-wrap@1.2.5(transitive)
+ Addedyocto-queue@0.1.0(transitive)
- Removedeslint-visitor-keys@1.3.0(transitive)
Updatedeslint-visitor-keys@^2.0.0