|
1 |
| -import type { TSESTree as T, TSESLint } from "@typescript-eslint/utils"; |
| 1 | +import { TSESTree as T, TSESLint, ASTUtils } from "@typescript-eslint/utils"; |
| 2 | +const { findVariable } = ASTUtils; |
2 | 3 |
|
3 | 4 | const domElementRegex = /^[a-z]/;
|
4 | 5 | export const isDOMElementName = (name: string): boolean => domElementRegex.test(name);
|
@@ -42,6 +43,32 @@ export function findParent(node: T.Node, predicate: (node: T.Node) => boolean):
|
42 | 43 | return node.parent ? find(node.parent, predicate) : null;
|
43 | 44 | }
|
44 | 45 |
|
| 46 | +// Try to resolve a variable to its definition |
| 47 | +export function trace(node: T.Node, initialScope: TSESLint.Scope.Scope): T.Node { |
| 48 | + if (node.type === "Identifier") { |
| 49 | + const variable = findVariable(initialScope, node); |
| 50 | + if (!variable) return node; |
| 51 | + |
| 52 | + const def = variable.defs[0]; |
| 53 | + switch (def.type) { |
| 54 | + case "FunctionName": |
| 55 | + case "ClassName": |
| 56 | + case "ImportBinding": |
| 57 | + return def.node; |
| 58 | + case "Variable": |
| 59 | + if ( |
| 60 | + ((def.node.parent as T.VariableDeclaration).kind === "const" || |
| 61 | + variable.references.every((ref) => ref.init || ref.isReadOnly())) && |
| 62 | + def.node.id.type === "Identifier" && |
| 63 | + def.node.init |
| 64 | + ) { |
| 65 | + return trace(def.node.init, initialScope); |
| 66 | + } |
| 67 | + } |
| 68 | + } |
| 69 | + return node; |
| 70 | +} |
| 71 | + |
45 | 72 | export type FunctionNode = T.FunctionExpression | T.ArrowFunctionExpression | T.FunctionDeclaration;
|
46 | 73 | const FUNCTION_TYPES = ["FunctionExpression", "ArrowFunctionExpression", "FunctionDeclaration"];
|
47 | 74 | export const isFunctionNode = (node: T.Node | null | undefined): node is FunctionNode =>
|
@@ -95,12 +122,9 @@ export const trackImports = (fromModule = /^solid-js(?:\/?|\b)/) => {
|
95 | 122 | }
|
96 | 123 | }
|
97 | 124 | };
|
98 |
| - const matchImport = (imports: string | Array<string>, str: string) => { |
| 125 | + const matchImport = (imports: string | Array<string>, str: string): string | undefined => { |
99 | 126 | const importArr = Array.isArray(imports) ? imports : [imports];
|
100 |
| - return importArr |
101 |
| - .map((i) => importMap.get(i)) |
102 |
| - .filter(Boolean) |
103 |
| - .includes(str); |
| 127 | + return importArr.find((i) => importMap.get(i) === str); |
104 | 128 | };
|
105 | 129 | return { matchImport, handleImportDeclaration };
|
106 | 130 | };
|
|
0 commit comments