refactor(javascript): share Babel child traversal
This commit is contained in:
parent
617cd84d27
commit
0f10499245
|
|
@ -26,7 +26,10 @@ import {
|
|||
import { evaluateSemanticExpression } from "./javascriptSemanticValues.js";
|
||||
import { range } from "./javascriptStaticAnalysisHelpers.js";
|
||||
import { semanticReturnCoverage } from "./javascriptSemanticCoverage.js";
|
||||
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
|
||||
import {
|
||||
childNodes,
|
||||
traverseJavaScriptAst,
|
||||
} from "./javascriptSemanticTraversal.js";
|
||||
|
||||
interface ReturnExpression {
|
||||
readonly node: t.Node | null;
|
||||
|
|
@ -145,15 +148,6 @@ const directReturnExpressions = (callable: t.Node): ReturnExpression[] => {
|
|||
return output;
|
||||
};
|
||||
|
||||
const childNodes = (node: t.Node): t.Node[] =>
|
||||
(t.VISITOR_KEYS[node.type] ?? []).flatMap((key) => {
|
||||
const value: unknown = Reflect.get(node, key);
|
||||
if (t.isNode(value)) return [value];
|
||||
return Array.isArray(value)
|
||||
? value.filter((item): item is t.Node => t.isNode(item))
|
||||
: [];
|
||||
});
|
||||
|
||||
const callableIdsForBinding = (
|
||||
binding: JavaScriptSemanticBindingState,
|
||||
state: JavaScriptSemanticAnalysisState,
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ interface TraversalFrame {
|
|||
nextIndex: number;
|
||||
}
|
||||
|
||||
const childNodes = (node: t.Node): t.Node[] => {
|
||||
/** Return child Babel nodes in visitor-key order. */
|
||||
export const childNodes = (node: t.Node): t.Node[] => {
|
||||
const keys = t.VISITOR_KEYS[node.type];
|
||||
if (keys === undefined) return [];
|
||||
const children: t.Node[] = [];
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import type {
|
|||
Node,
|
||||
StringLiteral,
|
||||
} from "@babel/types";
|
||||
import { traverseJavaScriptAst } from "./javascript/javascriptSemanticTraversal.js";
|
||||
import {
|
||||
isCallExpression,
|
||||
isExportAllDeclaration,
|
||||
|
|
@ -15,7 +16,6 @@ import {
|
|||
isImportDeclaration,
|
||||
isImportExpression,
|
||||
isMemberExpression,
|
||||
isNode,
|
||||
isStringLiteral,
|
||||
isTSExternalModuleReference,
|
||||
isTSImportEqualsDeclaration,
|
||||
|
|
@ -201,39 +201,6 @@ const isRequireCallee = (callee: Node | null | undefined): boolean => {
|
|||
return false;
|
||||
};
|
||||
|
||||
const collectModuleExpressions = (
|
||||
node: unknown,
|
||||
targets: Array<CallExpression | ImportExpression>,
|
||||
): void => {
|
||||
if (node === null || node === undefined) return;
|
||||
if (typeof node !== "object") return;
|
||||
if (Array.isArray(node)) {
|
||||
for (const item of node) collectModuleExpressions(item, targets);
|
||||
return;
|
||||
}
|
||||
if (!isNode(node)) return;
|
||||
if (isCallExpression(node) || isImportExpression(node)) {
|
||||
targets.push(node);
|
||||
}
|
||||
for (const value of Object.values(node)) {
|
||||
if (
|
||||
value !== null &&
|
||||
value !== undefined &&
|
||||
typeof value === "object" &&
|
||||
!isSourceLocation(value)
|
||||
) {
|
||||
collectModuleExpressions(value, targets);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const isSourceLocation = (value: unknown): boolean =>
|
||||
typeof value === "object" &&
|
||||
value !== null &&
|
||||
"start" in value &&
|
||||
"end" in value &&
|
||||
!("type" in value);
|
||||
|
||||
const extractRequireAndDynamicImports = (
|
||||
body: readonly Node[],
|
||||
from_path: string,
|
||||
|
|
@ -241,7 +208,12 @@ const extractRequireAndDynamicImports = (
|
|||
): void => {
|
||||
const expressions: Array<CallExpression | ImportExpression> = [];
|
||||
for (const statement of body)
|
||||
collectModuleExpressions(statement, expressions);
|
||||
traverseJavaScriptAst(statement, {
|
||||
enter: (node) => {
|
||||
if (isCallExpression(node) || isImportExpression(node))
|
||||
expressions.push(node);
|
||||
},
|
||||
});
|
||||
|
||||
for (const call of expressions) {
|
||||
if (isImportExpression(call)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue