[fetch] get cals

This commit is contained in:
2025-08-02 14:17:22 +01:00
parent 41551467d8
commit e018f253f1

View File

@@ -1,90 +1,5 @@
import { Syntax } from 'esprima';
import esquery from 'esquery';
import { getASTAndScope, getSetOfIdentifierReferencesForRequireUses } from '../ast/analysis.mjs';
import { LibraryCallsRecorder } from '../libcalls.mjs';
import { tagASTNode, getTagKey, untagASTNode } from '../ast/tag.mjs';
import { ExpressionArrayVisitor } from '../ast/visitors.mjs';
import assert from 'assert';
import assert from 'assert';
import { logCallList, sliceAndWriteCalls } from '../index.mjs';
/**
*
* @param {import('eslint').Scope.ScopeManager} scopeManager
* @returns
*/
export function getRequireCallsAndConstantArgs(scopeManager) {
const requireReferencesIdentifierSet = getSetOfIdentifierReferencesForRequireUses(scopeManager);
const callRecorder = new LibraryCallsRecorder();
// all the variables, what part of require module they're using
for (const scope of scopeManager.scopes) {
for (const [variableName, variable] of scope.set) {
// FIXME raise error if more than one but has import
const declareDefinesOfVariable = variable.defs.filter(e => e.node.type === Syntax.VariableDeclarator && e.node.init.type === Syntax.CallExpression);
// uses this variable
const declarationNodesUsingRequireList = declareDefinesOfVariable.filter(e => requireReferencesIdentifierSet.has(e.node.init.callee));
if (declarationNodesUsingRequireList.length > 1) {
console.error(`Import variable ${variableName} has been defined twice, skipping`);
continue;
} else if (declarationNodesUsingRequireList.length === 0) {
console.log(`Skipping unused import variable ${variableName}`);
continue;
}
const declarationNodeUsingRequire = declarationNodesUsingRequireList[0]; // we know its singleton from above
//
const moduleImportedName = getModuleNameFromRequireAssignDeclaration(declarationNodeUsingRequire);
const importPortion = getModuleImportPortionFromDefinition(declarationNodeUsingRequire, variableName);
for (const importVariableReference of variable.references) {
tagASTNode(importVariableReference, variableName, moduleImportedName);
const simpleCallExpressionsOfVariableInBlockList = esquery.query(importVariableReference.from.block, `CallExpression:has(>[tag="${importVariableReference.identifier[getTagKey()]}"])`);
for (const simpleCallExpressionOfVariableInBlock of simpleCallExpressionsOfVariableInBlockList) {
const argumentsGathered = gatherArgumentsFromTheCallExpression(importVariableReference, simpleCallExpressionOfVariableInBlock, importVariableReference.from.block, scopeManager);
callRecorder.pushToMap(moduleImportedName, importPortion, argumentsGathered);
}
untagASTNode(importVariableReference, variableName, moduleImportedName)
}
}
}
return callRecorder.calls;
}
/**
*
* @param {import('eslint').Scope.Definition} declaratorDefinition
*/
export function getModuleImportPortionFromDefinition(declaratorDefinition, variableName) {
const node = declaratorDefinition.node;
// console.log(`Req type`, node.type);
// FIXME - import portion calculations correctly
if (node.id.type === 'ObjectPattern') {
// console.log("Obj");
// const nodeName = node.id.properties.filter(e=>e.key.value.name==='x')
// TODO allow re-naming
return "." + variableName;
} else {
return '.';
}
}
/**
*
* @param {import('eslint').Scope.Reference} importVariableReference
* @param {import('estree').CallExpression} callExpressionNode
* @param {ReturnType<esquery>[0]} contextOfUse
* @param {import('eslint').Scope.ScopeManager} scopeManager
*/
export function gatherArgumentsFromTheCallExpression(importVariableReference, callExpressionNode, contextOfUse, scopeManager) {
const expressionArrayVisitor = new ExpressionArrayVisitor(scopeManager);
expressionArrayVisitor.visit(callExpressionNode);
const { arguments: constantArguments } = expressionArrayVisitor;
return constantArguments;
}
/**
*
* @param {Scope.Definition} requireUsingReference
@@ -97,19 +12,4 @@ export function getModuleNameFromRequireAssignDeclaration(requireUsingReference)
return moduleImported;
}
// import tsc from 'typescript'
/**
* Call parameter generation
*/
function mainOld() {
const FILE_PATH = './test_src/index.cjs';
const { scopeManager, _parsedModAST } = getASTAndScope(FILE_PATH);
assert(scopeManager.scopes.length >= 2, "expected atleast global and module scope");
assert(scopeManager.scopes[1].type === 'function', "expected the 'module' scope to have function scope");
const calls = getRequireCallsAndConstantArgs(scopeManager);
logCallList(calls);
sliceAndWriteCalls(calls, FILE_PATH);
}