[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 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
|
* @param {Scope.Definition} requireUsingReference
|
||||||
@@ -97,19 +12,4 @@ export function getModuleNameFromRequireAssignDeclaration(requireUsingReference)
|
|||||||
|
|
||||||
return moduleImported;
|
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