(
node: Node,
{
globals = defaultGlobals,
filterReference = (identifier: Identifier) => !globals.has(identifier.name),
filterDeclaration = () => true
}: {
globals?: Set<string>;
filterReference?: (identifier: Identifier) => any;
filterDeclaration?: (identifier: {name: string}) => any;
} = {}
)
| 45 | } |
| 46 | |
| 47 | export function findReferences( |
| 48 | node: Node, |
| 49 | { |
| 50 | globals = defaultGlobals, |
| 51 | filterReference = (identifier: Identifier) => !globals.has(identifier.name), |
| 52 | filterDeclaration = () => true |
| 53 | }: { |
| 54 | globals?: Set<string>; |
| 55 | filterReference?: (identifier: Identifier) => any; |
| 56 | filterDeclaration?: (identifier: {name: string}) => any; |
| 57 | } = {} |
| 58 | ): Identifier[] { |
| 59 | const locals = new Map<Node, Set<string>>(); |
| 60 | const references: Identifier[] = []; |
| 61 | |
| 62 | function hasLocal(node: Node, name: string): boolean { |
| 63 | const l = locals.get(node); |
| 64 | return l ? l.has(name) : false; |
| 65 | } |
| 66 | |
| 67 | function declareLocal(node: Node, id: {name: string}): void { |
| 68 | if (!filterDeclaration(id)) return; |
| 69 | const l = locals.get(node); |
| 70 | if (l) l.add(id.name); |
| 71 | else locals.set(node, new Set([id.name])); |
| 72 | } |
| 73 | |
| 74 | function declareClass(node: Class) { |
| 75 | if (node.id) declareLocal(node, node.id); |
| 76 | } |
| 77 | |
| 78 | function declareFunction(node: FunctionNode) { |
| 79 | node.params.forEach((param) => declarePattern(param, node)); |
| 80 | if (node.id) declareLocal(node, node.id); |
| 81 | if (node.type !== "ArrowFunctionExpression") declareLocal(node, {name: "arguments"}); |
| 82 | } |
| 83 | |
| 84 | function declareCatchClause(node: CatchClause) { |
| 85 | if (node.param) declarePattern(node.param, node); |
| 86 | } |
| 87 | |
| 88 | function declarePattern(node: Pattern, parent: Node) { |
| 89 | switch (node.type) { |
| 90 | case "Identifier": |
| 91 | declareLocal(parent, node); |
| 92 | break; |
| 93 | case "ObjectPattern": |
| 94 | node.properties.forEach((node) => declarePattern(node.type === "Property" ? node.value : node, parent)); |
| 95 | break; |
| 96 | case "ArrayPattern": |
| 97 | node.elements.forEach((node) => node && declarePattern(node, parent)); |
| 98 | break; |
| 99 | case "RestElement": |
| 100 | declarePattern(node.argument, parent); |
| 101 | break; |
| 102 | case "AssignmentPattern": |
| 103 | declarePattern(node.left, parent); |
| 104 | break; |
no outgoing calls
no test coverage detected