[fetch] get cals
This commit is contained in:
100
src/js/calls.mjs
100
src/js/calls.mjs
@@ -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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user