UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

46 lines 1.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.findAllClusters = findAllClusters; const edge_1 = require("./graph/edge"); const vertex_1 = require("./graph/vertex"); const assert_1 = require("../util/assert"); function findAllClusters(graph) { const clusters = []; // we reverse the vertices since dependencies usually point "backwards" from later nodes const notReached = new Set([...graph.vertices(true)].map(([id]) => id).reverse()); while (notReached.size > 0) { const [startNode] = notReached; notReached.delete(startNode); clusters.push({ startNode: startNode, members: [...makeCluster(graph, startNode, notReached)], hasUnknownSideEffects: graph.unknownSideEffects.has(startNode) }); } return clusters; } function makeCluster(graph, from, notReached) { const info = graph.getVertex(from); (0, assert_1.guard)(info !== undefined, () => `Vertex ${from} not found in graph`); const nodes = new Set([from]); // cluster function def exit points if (info.tag === vertex_1.VertexType.FunctionDefinition) { for (const sub of info.exitPoints) { if (notReached.delete(sub)) { makeCluster(graph, sub, notReached).forEach(n => nodes.add(n)); } } } // cluster adjacent edges for (const [dest, { types }] of [...graph.outgoingEdges(from) ?? [], ...graph.ingoingEdges(from) ?? []]) { // don't cluster for function content if it isn't returned if ((0, edge_1.edgeDoesNotIncludeType)(types, edge_1.EdgeType.Returns) && info.onlyBuiltin && info.name == '{') { continue; } if (notReached.delete(dest)) { makeCluster(graph, dest, notReached).forEach(n => nodes.add(n)); } } return nodes; } //# sourceMappingURL=cluster.js.map