UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

65 lines 2.64 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calculateExceptionsOfFunction = calculateExceptionsOfFunction; const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id"); const vertex_1 = require("../graph/vertex"); const built_in_proc_name_1 = require("../environments/built-in-proc-name"); const CatchHandlers = new Set([built_in_proc_name_1.BuiltInProcName.Try]); /** * Collect exception sources of a function in the call graph. * This returns the `NodeId`s of functions that may throw exceptions when called by the given function. * Please be aware, that these are restricted to functions known by flowR. * With `knownThrower` you can provide additional functions that are known to throw exceptions. * @returns A record mapping all `NodeId`s of functions that may throw exceptions to their exception points. */ function calculateExceptionsOfFunction(id, graph, knownThrower = {}) { const collectedExceptions = {}; const mine = []; const visited = new Set(); const toVisit = [id]; while (toVisit.length > 0) { const currentId = toVisit.pop(); if (visited.has(currentId)) { continue; } visited.add(currentId); const kt = knownThrower[currentId]; if (kt) { for (const e of kt) { if (!mine.includes(e)) { mine.push(e); } } continue; } const vtx = graph.getVertex(currentId); if (!vtx) { continue; } if (node_id_1.NodeId.isBuiltIn(currentId)) { continue; } if (vtx.tag === vertex_1.VertexType.FunctionDefinition) { const es = vtx.exitPoints.filter(e => e.type === 4 /* ExitPointType.Error */).map(e => ({ id: e.nodeId, cds: e.cds })); for (const e of es) { if (!mine.includes(e)) { mine.push(e); } } collectedExceptions[vtx.id] = es; } else if (vtx.tag === vertex_1.VertexType.FunctionCall && vtx.origin !== 'unnamed' && vtx.origin.some(c => CatchHandlers.has(c))) { // skip the try-catch handlers as they catch all exceptions within their body continue; } const outEdges = graph.outgoingEdges(currentId) ?? []; for (const [out] of outEdges) { if (!visited.has(out)) { toVisit.push(out); } } } collectedExceptions[id] = mine; return collectedExceptions; } //# sourceMappingURL=exceptions-of-function.js.map