@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
69 lines • 3.21 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.markAsOnlyBuiltIn = markAsOnlyBuiltIn;
exports.processNamedCall = processNamedCall;
const info_1 = require("../../../../info");
const known_call_handling_1 = require("./known-call-handling");
const append_1 = require("../../../../environments/append");
const resolve_by_name_1 = require("../../../../environments/resolve-by-name");
const vertex_1 = require("../../../../graph/vertex");
const identifier_1 = require("../../../../environments/identifier");
function mergeInformation(info, newInfo) {
if (info === undefined) {
return newInfo;
}
return {
unknownReferences: info.unknownReferences.concat(newInfo.unknownReferences),
in: info.in.concat(newInfo.in),
out: info.out.concat(newInfo.out),
graph: info.graph.mergeWith(newInfo.graph),
environment: (0, append_1.appendEnvironment)(info.environment, newInfo.environment),
entryPoint: newInfo.entryPoint,
exitPoints: info.exitPoints.concat(newInfo.exitPoints),
hooks: info.hooks.concat(newInfo.hooks)
};
}
function processDefaultFunctionProcessor(information, name, args, rootId, data) {
const resolve = (0, resolve_by_name_1.resolveByName)(name.content, data.environment, identifier_1.ReferenceType.Function);
/* if we do not know where we land, we force! */
const call = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: (resolve?.length ?? 0) > 0 ? undefined : 'all', origin: 'default' });
return mergeInformation(information, call.information);
}
/**
* Marks the given function call node as only calling built-in functions.
*/
function markAsOnlyBuiltIn(graph, rootId) {
const v = graph.getVertex(rootId);
if (v?.tag === vertex_1.VertexType.FunctionCall) {
v.onlyBuiltin = true;
v.environment = undefined;
}
}
/**
* Processes a named function call within the dataflow analysis.
* For example, `myFunction(arg1, arg2)`, resolves against the environment.
*/
function processNamedCall(name, args, rootId, data) {
const resolved = (0, resolve_by_name_1.resolveByName)(name.content, data.environment, identifier_1.ReferenceType.Function) ?? [];
let defaultProcessor = resolved.length === 0;
let information = undefined;
let builtIn = false;
for (const resolvedFunction of resolved) {
if (resolvedFunction.type === identifier_1.ReferenceType.BuiltInFunction && typeof resolvedFunction.processor === 'function') {
builtIn ||= resolvedFunction.config?.libFn !== true;
information = mergeInformation(information, resolvedFunction.processor(name, args, rootId, data));
}
else {
defaultProcessor = true;
}
}
if (defaultProcessor) {
information = processDefaultFunctionProcessor(information, name, args, rootId, data);
}
else if (information && builtIn) {
// mark the function call as built in only
markAsOnlyBuiltIn(information.graph, rootId);
}
return information ?? info_1.DataflowInformation.initialize(rootId, data);
}
//# sourceMappingURL=named-call-handling.js.map