@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
68 lines • 3.43 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.markNonStandardEvaluationEdges = markNonStandardEvaluationEdges;
exports.processKnownFunctionCall = processKnownFunctionCall;
const processor_1 = require("../../../../processor");
const common_1 = require("./common");
const identifier_1 = require("../../../../environments/identifier");
const graph_1 = require("../../../../graph/graph");
const edge_1 = require("../../../../graph/edge");
const logger_1 = require("../../../../logger");
const vertex_1 = require("../../../../graph/vertex");
const log_1 = require("../../../../../util/log");
function markNonStandardEvaluationEdges(markAsNSE, callArgs, finalGraph, rootId) {
for (const nse of markAsNSE) {
if (nse < callArgs.length) {
const arg = callArgs[nse];
if (arg !== undefined) {
finalGraph.addEdge(rootId, arg.entryPoint, edge_1.EdgeType.NonStandardEvaluation);
}
}
else {
logger_1.dataflowLogger.warn(`Trying to mark argument ${nse} as non-standard-evaluation, but only ${callArgs.length} arguments are available`);
}
}
}
function processKnownFunctionCall({ name, args, rootId, data, reverseOrder = false, markAsNSE = undefined, forceArgs, patchData = d => d, hasUnknownSideEffect }, indicesCollection = undefined) {
const functionName = (0, processor_1.processDataflowFor)(name, data);
const finalGraph = new graph_1.DataflowGraph(data.completeAst.idMap);
const functionCallName = name.content;
(0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Processing known function call ${functionCallName} with ${args.length} arguments`);
const processArgs = reverseOrder ? [...args].reverse() : args;
const { finalEnv, callArgs, remainingReadInArgs, processedArguments } = (0, common_1.processAllArguments)({ functionName, args: processArgs, data, finalGraph, functionRootId: rootId, patchData, forceArgs });
if (markAsNSE) {
markNonStandardEvaluationEdges(markAsNSE, processedArguments, finalGraph, rootId);
}
finalGraph.addVertex({
tag: vertex_1.VertexType.FunctionCall,
id: rootId,
environment: data.environment,
name: functionCallName,
/* will be overwritten accordingly */
onlyBuiltin: false,
cds: data.controlDependencies,
args: reverseOrder ? [...callArgs].reverse() : callArgs,
indicesCollection: indicesCollection,
});
if (hasUnknownSideEffect) {
finalGraph.markIdForUnknownSideEffects(rootId);
}
const inIds = remainingReadInArgs;
const fnRef = { nodeId: rootId, name: functionCallName, controlDependencies: data.controlDependencies, type: identifier_1.ReferenceType.Function };
inIds.push(fnRef);
return {
information: {
unknownReferences: [],
in: inIds,
/* we do not keep the argument out as it has been linked by the function */
out: functionName.out,
graph: finalGraph,
environment: finalEnv,
entryPoint: rootId,
exitPoints: [{ nodeId: rootId, type: 0 /* ExitPointType.Default */, controlDependencies: data.controlDependencies }]
},
processedArguments: reverseOrder ? [...processedArguments].reverse() : processedArguments,
fnRef
};
}
//# sourceMappingURL=known-call-handling.js.map