@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
53 lines • 3.04 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.linkReadsForArgument = linkReadsForArgument;
exports.processFunctionArgument = processFunctionArgument;
const processor_1 = require("../../../processor");
const collect_1 = require("../../../../r-bridge/lang-4.x/ast/model/collect");
const graph_1 = require("../../../graph/graph");
const type_1 = require("../../../../r-bridge/lang-4.x/ast/model/type");
const edge_1 = require("../../../graph/edge");
const vertex_1 = require("../../../graph/vertex");
function linkReadsForArgument(root, ingoingRefs, graph) {
const allIdsBeforeArguments = new Set((0, collect_1.collectAllIds)(root, n => n.type === type_1.RType.Argument && n.info.id !== root.info.id));
const ingoingBeforeArgs = ingoingRefs.filter(r => allIdsBeforeArguments.has(r.nodeId));
for (const ref of ingoingBeforeArgs) {
// link against the root reference currently I do not know how to deal with nested function calls otherwise
graph.addEdge(root.info.id, ref, edge_1.EdgeType.Reads);
}
}
function processFunctionArgument(argument, data) {
const name = argument.name === undefined ? undefined : (0, processor_1.processDataflowFor)(argument.name, data);
const value = argument.value === undefined ? undefined : (0, processor_1.processDataflowFor)(argument.value, data);
// we do not keep the graph of the name, as this is no node that should ever exist
const graph = value?.graph ?? new graph_1.DataflowGraph(data.completeAst.idMap);
const argumentName = argument.name?.content;
let entryPoint = value?.entryPoint;
if (argumentName) {
graph.addVertex({
tag: vertex_1.VertexType.Use,
id: argument.info.id,
cds: data.controlDependencies
});
entryPoint = argument.info.id;
}
const ingoingRefs = [...value?.unknownReferences ?? [], ...value?.in ?? [], ...(name === undefined ? [] : [...name.in])];
if (entryPoint && argument.value?.type === type_1.RType.FunctionDefinition) {
graph.addEdge(entryPoint, argument.value.info.id, edge_1.EdgeType.Reads);
}
else if (argumentName) {
// we only need to link against those which are not already bound to another function call argument
linkReadsForArgument(argument, [...ingoingRefs, ...value?.out ?? [] /* value may perform definitions */], graph);
}
return {
unknownReferences: [],
// active nodes of the name will be lost as they are only used to reference the corresponding parameter
in: ingoingRefs.filter(r => r.name !== undefined),
out: [...value?.out ?? [], ...(name?.out ?? [])],
graph: graph,
environment: value?.environment ?? data.environment,
entryPoint: entryPoint ?? argument.info.id,
exitPoints: value?.exitPoints ?? name?.exitPoints ?? [{ nodeId: argument.info.id, type: 0 /* ExitPointType.Default */, controlDependencies: data.controlDependencies }]
};
}
//# sourceMappingURL=process-argument.js.map