UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

53 lines 2.08 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"); /** * Find all clusters in the given dataflow graph. */ 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).toArray().reverse()); while (notReached.size > 0) { const [startNode] = notReached; notReached.delete(startNode); clusters.push({ startNode: startNode, members: Array.from(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 { nodeId } of info.exitPoints) { if (notReached.delete(nodeId)) { for (const m of makeCluster(graph, nodeId, notReached)) { nodes.add(m); } } } } // cluster adjacent edges for (const edges of [graph.outgoingEdges(from), graph.ingoingEdges(from)]) { for (const [dest, e] of edges ?? []) { // don't cluster for function content if it isn't returned if (edge_1.DfEdge.doesNotIncludeType(e, 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