UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

53 lines 3.04 kB
"use strict"; 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