UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

66 lines 2.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.lineageCommand = void 0; exports.getLineage = getLineage; const default_pipelines_1 = require("../../../core/steps/pipeline/default-pipelines"); const retriever_1 = require("../../../r-bridge/retriever"); const parse_1 = require("../../../slicing/criterion/parse"); const edge_1 = require("../../../dataflow/graph/edge"); const assert_1 = require("../../../util/assert"); function splitAt(str, idx) { return [str.slice(0, idx), str.slice(idx)]; } async function getDfg(parser, remainingLine) { return await (0, default_pipelines_1.createDataflowPipeline)(parser, { request: (0, retriever_1.requestFromInput)(remainingLine.trim()) }).allRemainingSteps(); } function filterRelevantEdges(edge) { return (0, edge_1.edgeIncludesType)(edge_1.EdgeType.DefinedBy | edge_1.EdgeType.DefinedByOnCall | edge_1.EdgeType.Returns | edge_1.EdgeType.Reads, edge.types); } function pushRelevantEdges(queue, outgoingEdges) { queue.push(...[...outgoingEdges].filter(([_, edge]) => filterRelevantEdges(edge))); } /** * Get the lineage of a node in the dataflow graph * * @param criterion - The criterion to get the lineage of * @param graph - The dataflow graph to search in * @param idMap - The ID map to use for resolving the criterion (will default to that shipped with the dfgraph) * @returns The lineage of the node represented as a set of node ids */ function getLineage(criterion, graph, idMap) { idMap ??= graph.idMap; (0, assert_1.guard)(idMap !== undefined, 'The ID map is required to get the lineage of a node'); const src = graph.get((0, parse_1.slicingCriterionToId)(criterion, idMap)); (0, assert_1.guard)(src !== undefined, 'The ID pointed to by the criterion does not exist in the dataflow graph'); const [vertex, outgoingEdges] = src; const result = new Set([vertex.id]); const edgeQueue = []; pushRelevantEdges(edgeQueue, outgoingEdges); while (edgeQueue.length > 0) { const [target] = edgeQueue.shift(); if (result.has(target)) { continue; } result.add(target); const outgoingEdges = graph.outgoingEdges(target); if (outgoingEdges !== undefined) { pushRelevantEdges(edgeQueue, outgoingEdges); } } return result; } exports.lineageCommand = { description: 'Get the lineage of an R object', usageExample: ':lineage', aliases: ['lin'], script: false, fn: async (output, shell, remainingLine) => { const [criterion, rest] = splitAt(remainingLine, remainingLine.indexOf(' ')); const { dataflow: dfg } = await getDfg(shell, rest); const lineageIds = getLineage(criterion, dfg.graph); output.stdout([...lineageIds].join('\n')); } }; //# sourceMappingURL=repl-lineage.js.map