@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
60 lines • 2.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.processRecall = processRecall;
const known_call_handling_1 = require("../known-call-handling");
const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
const unknown_side_effect_1 = require("../../../../../graph/unknown-side-effect");
const log_1 = require("../../../../../../util/log");
const edge_1 = require("../../../../../graph/edge");
const vertex_1 = require("../../../../../graph/vertex");
const unnamed_call_handling_1 = require("../unnamed-call-handling");
const identifier_1 = require("../../../../../environments/identifier");
const built_in_proc_name_1 = require("../../../../../environments/built-in-proc-name");
/**
* Processes a built-in 'Recall' function call, linking
* the recall to the enveloping function closure.
*/
function processRecall(name, args, rootId, data, config) {
const { information } = (0, known_call_handling_1.processKnownFunctionCall)({
name,
args,
rootId,
data,
origin: built_in_proc_name_1.BuiltInProcName.Recall
});
// If requested, treat Recall as an unknown side effect when a single argument is provided and it is not the numeric literal 0.
if (config?.unknownOnNonZeroArg) {
if (args.length === 1 && args[0] !== r_function_call_1.EmptyArgument && args[0].value) {
const v = args[0].value;
// only allow the normal recall handling if the single arg is the literal 0
if (!(v.type === type_1.RType.Number && v.content.num === 0)) {
(0, unknown_side_effect_1.handleUnknownSideEffect)(information.graph, information.environment, rootId);
return information;
}
}
}
let cur = data.environment.current;
let closure;
while (cur) {
if (cur.closure) {
closure = cur.closure;
break;
}
cur = cur.parent;
}
if (closure) {
information.graph.addEdge(rootId, closure, edge_1.EdgeType.Calls);
// also kill the name of the recall function
const r = information.graph.getVertex(rootId);
if ((0, vertex_1.isFunctionCallVertex)(r)) {
r.name = unnamed_call_handling_1.UnnamedFunctionCallPrefix + rootId + '-' + identifier_1.Identifier.toString(r.name);
r.environment = information.environment;
}
}
else {
log_1.log.warn('No enclosing function closure found for recall at node', rootId);
}
return information;
}
//# sourceMappingURL=built-in-recall.js.map