@eslint-react/ast
Advanced tools
Comparing version
'use strict'; | ||
var types = require('@typescript-eslint/types'); | ||
var eff = require('@eslint-react/eff'); | ||
var types = require('@typescript-eslint/types'); | ||
var utils = require('@typescript-eslint/utils'); | ||
@@ -9,52 +9,19 @@ var typescriptEstree = require('@typescript-eslint/typescript-estree'); | ||
// src/find-parent-node.ts | ||
function findParentNode(node, test) { | ||
if (node == null) return eff._; | ||
let parent = node.parent; | ||
while (parent != null && parent.type !== types.AST_NODE_TYPES.Program) { | ||
if (test(parent)) { | ||
return parent; | ||
} | ||
parent = parent.parent; | ||
} | ||
return eff._; | ||
// src/ast-array-method.ts | ||
function isArrayFromCall(node, loose = true) { | ||
if (node.type !== types.AST_NODE_TYPES.CallExpression) return false; | ||
if (node.callee.type !== types.AST_NODE_TYPES.MemberExpression) return false; | ||
if (node.callee.property.type !== types.AST_NODE_TYPES.Identifier) return false; | ||
const name = node.callee.property.name; | ||
return name === "from" || loose && name.startsWith("from"); | ||
} | ||
function getFunctionInitPath(node) { | ||
if (node.type === types.AST_NODE_TYPES.FunctionDeclaration) { | ||
return [node]; | ||
} | ||
const { parent } = node; | ||
switch (true) { | ||
case parent.type === types.AST_NODE_TYPES.VariableDeclarator: | ||
return [parent.parent, parent, node]; | ||
case (parent.type === types.AST_NODE_TYPES.CallExpression && parent.parent.type === types.AST_NODE_TYPES.VariableDeclarator): | ||
return [parent.parent.parent, parent.parent, parent, node]; | ||
case (parent.type === types.AST_NODE_TYPES.CallExpression && parent.parent.type === types.AST_NODE_TYPES.CallExpression && parent.parent.parent.type === types.AST_NODE_TYPES.VariableDeclarator): | ||
return [parent.parent.parent.parent, parent.parent.parent, parent.parent, parent, node]; | ||
case (parent.type === types.AST_NODE_TYPES.Property && parent.parent.type === types.AST_NODE_TYPES.ObjectExpression && parent.parent.parent.type === types.AST_NODE_TYPES.VariableDeclarator): | ||
return [parent.parent.parent.parent, parent.parent.parent, parent.parent, parent, node]; | ||
case (parent.type === types.AST_NODE_TYPES.MethodDefinition && parent.parent.parent.type === types.AST_NODE_TYPES.ClassDeclaration): | ||
return [parent.parent.parent, parent.parent, parent, node]; | ||
case (parent.type === types.AST_NODE_TYPES.PropertyDefinition && parent.parent.parent.type === types.AST_NODE_TYPES.ClassDeclaration): | ||
return [parent.parent.parent, parent.parent, parent, node]; | ||
} | ||
return eff._; | ||
function isArrayMapCall(node, loose = true) { | ||
if (node.type !== types.AST_NODE_TYPES.CallExpression) return false; | ||
if (node.callee.type !== types.AST_NODE_TYPES.MemberExpression) return false; | ||
if (node.callee.property.type !== types.AST_NODE_TYPES.Identifier) return false; | ||
const name = node.callee.property.name; | ||
return name === "map" || loose && name.endsWith("Map"); | ||
} | ||
function hasCallInFunctionInitPath(callName, initPath) { | ||
return initPath.some((n) => { | ||
if (n.type !== types.AST_NODE_TYPES.CallExpression) { | ||
return false; | ||
} | ||
switch (n.callee.type) { | ||
case types.AST_NODE_TYPES.Identifier: | ||
return n.callee.name === callName; | ||
case types.AST_NODE_TYPES.MemberExpression: | ||
return "name" in n.callee.property && n.callee.property.name === callName; | ||
default: | ||
return false; | ||
} | ||
}); | ||
} | ||
// src/get-array-method-callback-index-param-position.ts | ||
// src/ast-array-method-callback.ts | ||
var indexParamPosition = /* @__PURE__ */ new Map([ | ||
@@ -228,50 +195,14 @@ ["every", 1], | ||
// src/get-ecma-expression.ts | ||
function getEcmaExpression(node) { | ||
// src/ast-expression.ts | ||
function getJSExpression(node) { | ||
if (isTypeExpression(node)) { | ||
return getEcmaExpression(node.expression); | ||
return getJSExpression(node.expression); | ||
} | ||
return node; | ||
} | ||
function getFunctionIdentifier(node) { | ||
switch (true) { | ||
// function MaybeComponent() {} | ||
case ("id" in node && node.id != null): | ||
return node.id; | ||
// const whatever = function MaybeComponent() {}; | ||
case (node.parent.type === types.AST_NODE_TYPES.VariableDeclarator && node.parent.init === node && node.parent.id.type === types.AST_NODE_TYPES.Identifier): | ||
return node.parent.id; | ||
// MaybeComponent = () => {}; | ||
case (node.parent.type === types.AST_NODE_TYPES.AssignmentExpression && node.parent.right === node && node.parent.operator === "=" && node.parent.left.type === types.AST_NODE_TYPES.Identifier): | ||
return node.parent.left; | ||
// {MaybeComponent: () => {}} | ||
// {MaybeComponent() {}} | ||
case (node.parent.type === types.AST_NODE_TYPES.Property && node.parent.value === node && !node.parent.computed && node.parent.key.type === types.AST_NODE_TYPES.Identifier): | ||
return node.parent.key; | ||
// class {MaybeComponent = () => {}} | ||
// class {MaybeComponent() {}} | ||
case (isMethodOrProperty(node.parent) && node.parent.value === node && node.parent.key.type === types.AST_NODE_TYPES.Identifier): | ||
return node.parent.key; | ||
// Follow spec convention for `IsAnonymousFunctionDefinition()` usage. | ||
// | ||
// const {MaybeComponent = () => {}} = {}; | ||
// ({MaybeComponent = () => {}} = {}); | ||
case (node.parent.type === types.AST_NODE_TYPES.AssignmentPattern && node.parent.right === node && node.parent.left.type === types.AST_NODE_TYPES.Identifier): | ||
return node.parent.left; | ||
// const MaybeComponent = (() => {})!; | ||
// const MaybeComponent = (() => {}) as FunctionComponent; | ||
// const MaybeComponent = (() => {}) satisfies FunctionComponent; | ||
case isTypeAssertionExpression(node.parent): | ||
return getFunctionIdentifier(node.parent); | ||
} | ||
return eff._; | ||
function isThisExpression(node) { | ||
return getJSExpression(node).type === types.AST_NODE_TYPES.ThisExpression; | ||
} | ||
// src/get-literal-value-type.ts | ||
function getLiteralValueType(input) { | ||
if (input === null) return "null"; | ||
return typeof input; | ||
} | ||
function getNestedExpressionsOfType(type) { | ||
const isNodeOfType = utils.ASTUtils.isNodeOfType(type); | ||
const isNodeOfType = is(type); | ||
return function(node) { | ||
@@ -323,31 +254,31 @@ const boundGetNestedExpressionsOfType = getNestedExpressionsOfType(type); | ||
} | ||
if (node.type === typescriptEstree.AST_NODE_TYPES.Property) { | ||
if (node.type === types.AST_NODE_TYPES.Property) { | ||
const chunk = boundGetNestedExpressionsOfType(node.value); | ||
expressions.push(...chunk); | ||
} | ||
if (node.type === typescriptEstree.AST_NODE_TYPES.SpreadElement) { | ||
if (node.type === types.AST_NODE_TYPES.SpreadElement) { | ||
const chunk = boundGetNestedExpressionsOfType(node.argument); | ||
expressions.push(...chunk); | ||
} | ||
if (node.type === typescriptEstree.AST_NODE_TYPES.MemberExpression) { | ||
if (node.type === types.AST_NODE_TYPES.MemberExpression) { | ||
const chunk = boundGetNestedExpressionsOfType(node.object); | ||
expressions.push(...chunk); | ||
} | ||
if (node.type === typescriptEstree.AST_NODE_TYPES.UnaryExpression) { | ||
if (node.type === types.AST_NODE_TYPES.UnaryExpression) { | ||
const chunk = boundGetNestedExpressionsOfType(node.argument); | ||
expressions.push(...chunk); | ||
} | ||
if (node.type === typescriptEstree.AST_NODE_TYPES.ChainExpression) { | ||
if (node.type === types.AST_NODE_TYPES.ChainExpression) { | ||
const chunk = boundGetNestedExpressionsOfType(node.expression); | ||
expressions.push(...chunk); | ||
} | ||
if (node.type === typescriptEstree.AST_NODE_TYPES.TSNonNullExpression) { | ||
if (node.type === types.AST_NODE_TYPES.TSNonNullExpression) { | ||
const chunk = boundGetNestedExpressionsOfType(node.expression); | ||
expressions.push(...chunk); | ||
} | ||
if (node.type === typescriptEstree.AST_NODE_TYPES.TSAsExpression) { | ||
if (node.type === types.AST_NODE_TYPES.TSAsExpression) { | ||
const chunk = boundGetNestedExpressionsOfType(node.expression); | ||
expressions.push(...chunk); | ||
} | ||
if (node.type === typescriptEstree.AST_NODE_TYPES.TSSatisfiesExpression) { | ||
if (node.type === types.AST_NODE_TYPES.TSSatisfiesExpression) { | ||
const chunk = boundGetNestedExpressionsOfType(node.expression); | ||
@@ -359,4 +290,87 @@ expressions.push(...chunk); | ||
} | ||
var getNestedNewExpressions = getNestedExpressionsOfType(typescriptEstree.AST_NODE_TYPES.NewExpression); | ||
var getNestedCallExpressions = getNestedExpressionsOfType(typescriptEstree.AST_NODE_TYPES.CallExpression); | ||
var getNestedNewExpressions = getNestedExpressionsOfType(types.AST_NODE_TYPES.NewExpression); | ||
var getNestedCallExpressions = getNestedExpressionsOfType(types.AST_NODE_TYPES.CallExpression); | ||
function getFunctionIdentifier(node) { | ||
switch (true) { | ||
// function MaybeComponent() {} | ||
case ("id" in node && node.id != null): | ||
return node.id; | ||
// const whatever = function MaybeComponent() {}; | ||
case (node.parent.type === types.AST_NODE_TYPES.VariableDeclarator && node.parent.init === node && node.parent.id.type === types.AST_NODE_TYPES.Identifier): | ||
return node.parent.id; | ||
// MaybeComponent = () => {}; | ||
case (node.parent.type === types.AST_NODE_TYPES.AssignmentExpression && node.parent.right === node && node.parent.operator === "=" && node.parent.left.type === types.AST_NODE_TYPES.Identifier): | ||
return node.parent.left; | ||
// {MaybeComponent: () => {}} | ||
// {MaybeComponent() {}} | ||
case (node.parent.type === types.AST_NODE_TYPES.Property && node.parent.value === node && !node.parent.computed && node.parent.key.type === types.AST_NODE_TYPES.Identifier): | ||
return node.parent.key; | ||
// class {MaybeComponent = () => {}} | ||
// class {MaybeComponent() {}} | ||
case (isMethodOrProperty(node.parent) && node.parent.value === node && node.parent.key.type === types.AST_NODE_TYPES.Identifier): | ||
return node.parent.key; | ||
// Follow spec convention for `IsAnonymousFunctionDefinition()` usage. | ||
// | ||
// const {MaybeComponent = () => {}} = {}; | ||
// ({MaybeComponent = () => {}} = {}); | ||
case (node.parent.type === types.AST_NODE_TYPES.AssignmentPattern && node.parent.right === node && node.parent.left.type === types.AST_NODE_TYPES.Identifier): | ||
return node.parent.left; | ||
// const MaybeComponent = (() => {})!; | ||
// const MaybeComponent = (() => {}) as FunctionComponent; | ||
// const MaybeComponent = (() => {}) satisfies FunctionComponent; | ||
case isTypeAssertionExpression(node.parent): | ||
return getFunctionIdentifier(node.parent); | ||
} | ||
return eff._; | ||
} | ||
function getFunctionInitPath(node) { | ||
if (node.type === types.AST_NODE_TYPES.FunctionDeclaration) { | ||
return [node]; | ||
} | ||
const { parent } = node; | ||
switch (true) { | ||
case parent.type === types.AST_NODE_TYPES.VariableDeclarator: | ||
return [parent.parent, parent, node]; | ||
case (parent.type === types.AST_NODE_TYPES.CallExpression && parent.parent.type === types.AST_NODE_TYPES.VariableDeclarator): | ||
return [parent.parent.parent, parent.parent, parent, node]; | ||
case (parent.type === types.AST_NODE_TYPES.CallExpression && parent.parent.type === types.AST_NODE_TYPES.CallExpression && parent.parent.parent.type === types.AST_NODE_TYPES.VariableDeclarator): | ||
return [parent.parent.parent.parent, parent.parent.parent, parent.parent, parent, node]; | ||
case (parent.type === types.AST_NODE_TYPES.Property && parent.parent.type === types.AST_NODE_TYPES.ObjectExpression && parent.parent.parent.type === types.AST_NODE_TYPES.VariableDeclarator): | ||
return [parent.parent.parent.parent, parent.parent.parent, parent.parent, parent, node]; | ||
case (parent.type === types.AST_NODE_TYPES.MethodDefinition && parent.parent.parent.type === types.AST_NODE_TYPES.ClassDeclaration): | ||
return [parent.parent.parent, parent.parent, parent, node]; | ||
case (parent.type === types.AST_NODE_TYPES.PropertyDefinition && parent.parent.parent.type === types.AST_NODE_TYPES.ClassDeclaration): | ||
return [parent.parent.parent, parent.parent, parent, node]; | ||
} | ||
return eff._; | ||
} | ||
function hasCallInFunctionInitPath(callName, initPath) { | ||
return initPath.some((n) => { | ||
if (n.type !== types.AST_NODE_TYPES.CallExpression) { | ||
return false; | ||
} | ||
switch (n.callee.type) { | ||
case types.AST_NODE_TYPES.Identifier: | ||
return n.callee.name === callName; | ||
case types.AST_NODE_TYPES.MemberExpression: | ||
return "name" in n.callee.property && n.callee.property.name === callName; | ||
default: | ||
return false; | ||
} | ||
}); | ||
} | ||
function isEmptyFunction(node) { | ||
return node.body.type === types.AST_NODE_TYPES.BlockStatement && node.body.body.length === 0; | ||
} | ||
function findParentNode(node, test) { | ||
if (node == null) return eff._; | ||
let parent = node.parent; | ||
while (parent != null && parent.type !== types.AST_NODE_TYPES.Program) { | ||
if (test(parent)) { | ||
return parent; | ||
} | ||
parent = parent.parent; | ||
} | ||
return eff._; | ||
} | ||
function getNestedIdentifiers(node) { | ||
@@ -425,58 +439,5 @@ const identifiers = []; | ||
} | ||
function getNestedReturnStatements(node) { | ||
const statements = []; | ||
const boundaryNode = isFunction(node) ? node : findParentNode(node, isFunction); | ||
typescriptEstree.simpleTraverse(node, { | ||
enter(node2) { | ||
if (node2.type !== types.AST_NODE_TYPES.ReturnStatement) { | ||
return; | ||
} | ||
const parentFunction = findParentNode(node2, isFunction); | ||
if (parentFunction !== boundaryNode) { | ||
return; | ||
} | ||
statements.push(node2); | ||
} | ||
}); | ||
return statements; | ||
} | ||
function getPropertyName(node) { | ||
if (isTypeExpression(node)) { | ||
return getPropertyName(getEcmaExpression(node)); | ||
} | ||
if (node.type === types.AST_NODE_TYPES.Identifier || node.type === types.AST_NODE_TYPES.PrivateIdentifier) { | ||
return node.name; | ||
} | ||
if (node.type === types.AST_NODE_TYPES.Literal) { | ||
return String(node.value); | ||
} | ||
if (node.type === types.AST_NODE_TYPES.TemplateLiteral && node.expressions.length === 0) { | ||
return node.quasis[0]?.value.raw; | ||
} | ||
return eff._; | ||
} | ||
function isArrayFromCall(node, loose = true) { | ||
if (node.type !== types.AST_NODE_TYPES.CallExpression) return false; | ||
if (node.callee.type !== types.AST_NODE_TYPES.MemberExpression) return false; | ||
if (node.callee.property.type !== types.AST_NODE_TYPES.Identifier) return false; | ||
const name = node.callee.property.name; | ||
return name === "from" || loose && name.startsWith("from"); | ||
} | ||
function isArrayMapCall(node, loose = true) { | ||
if (node.type !== types.AST_NODE_TYPES.CallExpression) return false; | ||
if (node.callee.type !== types.AST_NODE_TYPES.MemberExpression) return false; | ||
if (node.callee.property.type !== types.AST_NODE_TYPES.Identifier) return false; | ||
const name = node.callee.property.name; | ||
return name === "map" || loose && name.endsWith("Map"); | ||
} | ||
function isEmptyFunction(node) { | ||
return node.body.type === types.AST_NODE_TYPES.BlockStatement && node.body.body.length === 0; | ||
} | ||
// src/is-multi-line.ts | ||
function isMultiLine(node) { | ||
return node.loc.start.line !== node.loc.end.line; | ||
} | ||
// src/is-line-break.ts | ||
function isLineBreak(node) { | ||
@@ -567,9 +528,54 @@ return isOneOf([types.AST_NODE_TYPES.Literal, types.AST_NODE_TYPES.JSXText])(node) && typeof node.value === "string" && node.value.trim() === "" && isMultiLine(node); | ||
} | ||
function isThisExpression(node) { | ||
return getEcmaExpression(node).type === types.AST_NODE_TYPES.ThisExpression; | ||
function getPropertyName(node) { | ||
if (isTypeExpression(node)) { | ||
return getPropertyName(getJSExpression(node)); | ||
} | ||
if (node.type === types.AST_NODE_TYPES.Identifier || node.type === types.AST_NODE_TYPES.PrivateIdentifier) { | ||
return node.name; | ||
} | ||
if (node.type === types.AST_NODE_TYPES.Literal) { | ||
return String(node.value); | ||
} | ||
if (node.type === types.AST_NODE_TYPES.TemplateLiteral && node.expressions.length === 0) { | ||
return node.quasis[0]?.value.raw; | ||
} | ||
return eff._; | ||
} | ||
function stringify(node, getText) { | ||
function getNestedReturnStatements(node) { | ||
const statements = []; | ||
const boundaryNode = isFunction(node) ? node : findParentNode(node, isFunction); | ||
typescriptEstree.simpleTraverse(node, { | ||
enter(node2) { | ||
if (node2.type !== types.AST_NODE_TYPES.ReturnStatement) { | ||
return; | ||
} | ||
const parentFunction = findParentNode(node2, isFunction); | ||
if (parentFunction !== boundaryNode) { | ||
return; | ||
} | ||
statements.push(node2); | ||
} | ||
}); | ||
return statements; | ||
} | ||
function getLiteralValueType(input) { | ||
if (input === null) return "null"; | ||
return typeof input; | ||
} | ||
function toReadableNodeType(node) { | ||
if (node.type === types.AST_NODE_TYPES.Literal) { | ||
if ("regex" in node) { | ||
return "RegExp literal"; | ||
} | ||
return `${getLiteralValueType(node.value)} literal`; | ||
} | ||
if (isJSX(node)) { | ||
return `JSX ${stringTs.toLowerCase(stringTs.delimiterCase(stringTs.replace(node.type, "JSX", ""), " "))}`; | ||
} | ||
return stringTs.toLowerCase(stringTs.delimiterCase(node.type, " ")); | ||
} | ||
function toString(node, getText) { | ||
switch (node.type) { | ||
case types.AST_NODE_TYPES.CallExpression: | ||
return stringify(node.callee, getText); | ||
return toString(node.callee, getText); | ||
case types.AST_NODE_TYPES.Identifier: | ||
@@ -581,3 +587,3 @@ case types.AST_NODE_TYPES.PrivateIdentifier: | ||
case types.AST_NODE_TYPES.JSXMemberExpression: | ||
return `${stringify(node.object, getText)}.${stringify(node.property, getText)}`; | ||
return `${toString(node.object, getText)}.${toString(node.property, getText)}`; | ||
case types.AST_NODE_TYPES.JSXNamespacedName: | ||
@@ -590,3 +596,3 @@ return `${node.namespace.name}:${node.name.name}`; | ||
case types.AST_NODE_TYPES.MemberExpression: | ||
return `${stringify(node.object, getText)}.${stringify(node.property, getText)}`; | ||
return `${toString(node.object, getText)}.${toString(node.property, getText)}`; | ||
default: | ||
@@ -596,14 +602,2 @@ return getText(node); | ||
} | ||
function toReadableNodeType(node) { | ||
if (node.type === types.AST_NODE_TYPES.Literal) { | ||
if ("regex" in node) { | ||
return "RegExp literal"; | ||
} | ||
return `${getLiteralValueType(node.value)} literal`; | ||
} | ||
if (isJSX(node)) { | ||
return `JSX ${stringTs.toLowerCase(stringTs.delimiterCase(stringTs.replace(node.type, "JSX", ""), " "))}`; | ||
} | ||
return stringTs.toLowerCase(stringTs.delimiterCase(node.type, " ")); | ||
} | ||
@@ -613,6 +607,5 @@ exports.findParentNode = findParentNode; | ||
exports.getClassIdentifier = getClassIdentifier; | ||
exports.getEcmaExpression = getEcmaExpression; | ||
exports.getFunctionIdentifier = getFunctionIdentifier; | ||
exports.getFunctionInitPath = getFunctionInitPath; | ||
exports.getLiteralValueType = getLiteralValueType; | ||
exports.getJSExpression = getJSExpression; | ||
exports.getNestedCallExpressions = getNestedCallExpressions; | ||
@@ -656,3 +649,3 @@ exports.getNestedExpressionsOfType = getNestedExpressionsOfType; | ||
exports.isTypeExpression = isTypeExpression; | ||
exports.stringify = stringify; | ||
exports.toReadableNodeType = toReadableNodeType; | ||
exports.toString = toString; |
{ | ||
"name": "@eslint-react/ast", | ||
"version": "1.48.1", | ||
"version": "1.48.2-beta.0", | ||
"description": "ESLint React's TSESTree AST utility module.", | ||
@@ -43,3 +43,3 @@ "homepage": "https://github.com/Rel1cx/eslint-react", | ||
"ts-pattern": "^5.7.0", | ||
"@eslint-react/eff": "1.48.1" | ||
"@eslint-react/eff": "1.48.2-beta.0" | ||
}, | ||
@@ -46,0 +46,0 @@ "devDependencies": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
95527
-61.58%1528
-58.69%1
Infinity%+ Added
- Removed