UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

70 lines 3.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 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"); const built_in_proc_name_1 = require("../../../../environments/built-in-proc-name"); exports.UnnamedFunctionCallPrefix = 'unnamed-fc-'; /** * Processes an unnamed function call. * For example `(function(x) { x + 1 })(5)` */ 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 reads the toplevel: finalGraph.addEdge(functionRootId, calledRootId, 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.cds, args: callArgs, // same reference origin: [built_in_proc_name_1.BuiltInProcName.Unnamed] }, data.ctx.env.makeCleanEnv()); let inIds = remainingReadInArgs; inIds.push({ nodeId: functionRootId, name: functionCallName, cds: data.cds, type: identifier_1.ReferenceType.Function }); // if we just call a nested fdef 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, hooks: calledFunction.hooks, }; } //# sourceMappingURL=unnamed-call-handling.js.map