eslint-plugin-perfectionist
Version:
ESLint plugin for sorting various data such as objects, imports, types, enums, JSX props, etc.
167 lines (166 loc) • 5.05 kB
JavaScript
import { matches } from '../../utils/matches.js'
import { computeIdentifierNameDetails } from './compute-identifier-name-details.js'
import { computeDependencyName } from './compute-dependency-name.js'
import { AST_NODE_TYPES } from '@typescript-eslint/utils'
/**
* Computes the dependencies of a class member AST node.
*
* @deprecated - To remove when experimental dependency detection is the only.
* @param params - Parameters object.
* @param params.ignoreCallbackDependenciesPatterns - Patterns to ignore
* callback dependencies.
* @param params.useExperimentalDependencyDetection - Whether to use
* experimental dependency detection.
* @param params.isMemberStatic - Indicates if the member is static.
* @param params.expression - The AST node expression to analyze.
* @param params.className - The name of the class, if available.
* @returns The names of the dependencies.
*/
function computeDependencies({
ignoreCallbackDependenciesPatterns,
useExperimentalDependencyDetection,
isMemberStatic,
expression,
className,
}) {
if (useExperimentalDependencyDetection) {
return []
}
let dependencies = []
traverseNode(expression)
return dependencies
function checkNode(nodeValue) {
switch (nodeValue.type) {
case AST_NODE_TYPES.ConditionalExpression:
traverseNode(nodeValue.test)
traverseNode(nodeValue.consequent)
traverseNode(nodeValue.alternate)
break
case AST_NODE_TYPES.MemberExpression:
dependencies.push(
...computeMemberExpressionDependencies({
memberExpression: nodeValue,
isMemberStatic,
className,
}),
)
break
case AST_NODE_TYPES.CallExpression:
if (!('name' in nodeValue.callee)) {
traverseNode(nodeValue.arguments)
break
}
if (
matches(nodeValue.callee.name, ignoreCallbackDependenciesPatterns)
) {
break
}
traverseNode(nodeValue.arguments)
break
case AST_NODE_TYPES.NewExpression:
traverseNode(nodeValue.arguments)
break
case AST_NODE_TYPES.Property:
traverseNode(nodeValue.key)
traverseNode(nodeValue.value)
break
default:
break
}
if ('argument' in nodeValue && nodeValue.argument) {
traverseNode(nodeValue.argument)
}
if ('body' in nodeValue && nodeValue.body) {
traverseNode(nodeValue.body)
}
if ('callee' in nodeValue) {
traverseNode(nodeValue.callee)
}
if ('declarations' in nodeValue) {
traverseNode(nodeValue.declarations)
}
if ('elements' in nodeValue) {
traverseNode(
nodeValue.elements.filter(currentNode => currentNode !== null),
)
}
if (
'expression' in nodeValue &&
typeof nodeValue.expression !== 'boolean'
) {
traverseNode(nodeValue.expression)
}
if ('expressions' in nodeValue) {
traverseNode(nodeValue.expressions)
}
if ('init' in nodeValue && nodeValue.init) {
traverseNode(nodeValue.init)
}
if ('left' in nodeValue) {
traverseNode(nodeValue.left)
}
if ('object' in nodeValue) {
traverseNode(nodeValue.object)
}
if ('properties' in nodeValue) {
traverseNode(nodeValue.properties)
}
if ('right' in nodeValue) {
traverseNode(nodeValue.right)
}
}
function traverseNode(nodeValue) {
if (Array.isArray(nodeValue)) {
for (let nodeItem of nodeValue) {
traverseNode(nodeItem)
}
} else {
checkNode(nodeValue)
}
}
}
function computeMemberExpressionDependencies({
memberExpression,
isMemberStatic,
className,
}) {
switch (memberExpression.object.type) {
case AST_NODE_TYPES.ThisExpression:
return computeIdentifierOrThisExpressionDependencies()
case AST_NODE_TYPES.Identifier:
return memberExpression.object.name === className ?
computeIdentifierOrThisExpressionDependencies()
: []
default:
return []
}
function computeIdentifierOrThisExpressionDependencies() {
let dependency = computeDependencyFromProperty()
/* v8 ignore next 2 -- @preserve Unhandled cases */
if (!dependency) {
return []
}
return [dependency]
}
function computeDependencyFromProperty() {
switch (memberExpression.property.type) {
case AST_NODE_TYPES.PrivateIdentifier:
case AST_NODE_TYPES.Identifier:
case AST_NODE_TYPES.Literal: {
let { nameWithoutStartingHash, hasPrivateHash } =
computeIdentifierNameDetails(memberExpression.property)
return computeDependencyName({
isStatic:
isMemberStatic ||
memberExpression.object.type === AST_NODE_TYPES.Identifier,
nodeNameWithoutStartingHash: nameWithoutStartingHash,
hasPrivateHash,
})
}
/* v8 ignore next 2 -- @preserve Unhandled cases */
default:
return null
}
}
}
export { computeDependencies }