@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
64 lines • 3.24 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.UnnamedFunctionCallOrigin = exports.UnnamedFunctionCallPrefix = void 0;
exports.processUnnamedFunctionCall = processUnnamedFunctionCall;
const processor_1 = require("../../../../processor");
const common_1 = require("./common");
const linker_1 = require("../../../linker");
const edge_1 = require("../../../../graph/edge");
const graph_1 = require("../../../../graph/graph");
const vertex_1 = require("../../../../graph/vertex");
const type_1 = require("../../../../../r-bridge/lang-4.x/ast/model/type");
const logger_1 = require("../../../../logger");
const identifier_1 = require("../../../../environments/identifier");
exports.UnnamedFunctionCallPrefix = 'unnamed-function-call-';
exports.UnnamedFunctionCallOrigin = 'unnamed';
function processUnnamedFunctionCall(functionCall, data) {
const calledFunction = (0, processor_1.processDataflowFor)(functionCall.calledFunction, data);
const finalGraph = new graph_1.DataflowGraph(data.completeAst.idMap);
const functionRootId = functionCall.info.id;
const calledRootId = functionCall.calledFunction.info.id;
const functionCallName = `${exports.UnnamedFunctionCallPrefix}${functionRootId}`;
logger_1.dataflowLogger.debug(`Using ${functionRootId} as root for the unnamed function call`);
// we know that it calls the toplevel:
finalGraph.addEdge(functionRootId, calledRootId, edge_1.EdgeType.Calls | edge_1.EdgeType.Reads);
// keep the defined function
finalGraph.mergeWith(calledFunction.graph);
const { finalEnv, callArgs, remainingReadInArgs } = (0, common_1.processAllArguments)({
functionName: calledFunction,
args: functionCall.arguments,
data,
finalGraph,
functionRootId
/* we know the call is right there and fully resolved, there is no need to artificially force arguments as we identify them within the subtree */
});
finalGraph.addVertex({
tag: vertex_1.VertexType.FunctionCall,
id: functionRootId,
environment: data.environment,
name: functionCallName,
/* can never be a direct built-in-call */
onlyBuiltin: false,
cds: data.controlDependencies,
args: callArgs, // same reference
origin: [exports.UnnamedFunctionCallOrigin]
});
let inIds = remainingReadInArgs;
inIds.push({ nodeId: functionRootId, name: functionCallName, controlDependencies: data.controlDependencies, type: identifier_1.ReferenceType.Function });
if (functionCall.calledFunction.type === type_1.RType.FunctionDefinition) {
(0, linker_1.linkArgumentsOnCall)(callArgs, functionCall.calledFunction.parameters, finalGraph);
}
// push the called function to the ids:
inIds = inIds.concat(calledFunction.in, calledFunction.unknownReferences);
return {
unknownReferences: [],
in: inIds,
// we do not keep the argument out as it has been linked by the function
out: calledFunction.out,
graph: finalGraph,
environment: finalEnv,
entryPoint: functionCall.info.id,
exitPoints: calledFunction.exitPoints
};
}
//# sourceMappingURL=unnamed-call-handling.js.map