@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
152 lines • 8.22 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EmptyBuiltInMemory = exports.BuiltInMemory = exports.BuiltInEvalHandlerMapper = exports.BuiltInProcessorMapper = void 0;
exports.builtInId = builtInId;
exports.isBuiltIn = isBuiltIn;
exports.registerBuiltInFunctions = registerBuiltInFunctions;
const known_call_handling_1 = require("../internal/process/functions/call/known-call-handling");
const built_in_access_1 = require("../internal/process/functions/call/built-in/built-in-access");
const built_in_if_then_else_1 = require("../internal/process/functions/call/built-in/built-in-if-then-else");
const built_in_assignment_1 = require("../internal/process/functions/call/built-in/built-in-assignment");
const built_in_special_bin_op_1 = require("../internal/process/functions/call/built-in/built-in-special-bin-op");
const built_in_pipe_1 = require("../internal/process/functions/call/built-in/built-in-pipe");
const built_in_for_loop_1 = require("../internal/process/functions/call/built-in/built-in-for-loop");
const built_in_repeat_loop_1 = require("../internal/process/functions/call/built-in/built-in-repeat-loop");
const built_in_while_loop_1 = require("../internal/process/functions/call/built-in/built-in-while-loop");
const identifier_1 = require("./identifier");
const assert_1 = require("../../util/assert");
const built_in_replacement_1 = require("../internal/process/functions/call/built-in/built-in-replacement");
const built_in_quote_1 = require("../internal/process/functions/call/built-in/built-in-quote");
const built_in_function_definition_1 = require("../internal/process/functions/call/built-in/built-in-function-definition");
const built_in_expression_list_1 = require("../internal/process/functions/call/built-in/built-in-expression-list");
const built_in_get_1 = require("../internal/process/functions/call/built-in/built-in-get");
const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
const edge_1 = require("../graph/edge");
const built_in_library_1 = require("../internal/process/functions/call/built-in/built-in-library");
const built_in_source_1 = require("../internal/process/functions/call/built-in/built-in-source");
const built_in_apply_1 = require("../internal/process/functions/call/built-in/built-in-apply");
const built_in_config_1 = require("./built-in-config");
const default_builtin_config_1 = require("./default-builtin-config");
const built_in_list_1 = require("../internal/process/functions/call/built-in/built-in-list");
const built_in_vector_1 = require("../internal/process/functions/call/built-in/built-in-vector");
const built_in_rm_1 = require("../internal/process/functions/call/built-in/built-in-rm");
const built_in_eval_1 = require("../internal/process/functions/call/built-in/built-in-eval");
const vertex_1 = require("../graph/vertex");
const type_1 = require("../../r-bridge/lang-4.x/ast/model/type");
const unknown_side_effect_1 = require("../graph/unknown-side-effect");
const resolve_1 = require("../eval/resolve/resolve");
function builtInId(name) {
return `built-in:${name}`;
}
function isBuiltIn(name) {
return String(name).startsWith('built-in:');
}
function defaultBuiltInProcessor(name, args, rootId, data, config) {
const { information: res, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs, origin: 'builtin:default' });
if (config.returnsNthArgument !== undefined) {
const arg = config.returnsNthArgument === 'last' ? processedArguments[args.length - 1] : processedArguments[config.returnsNthArgument];
if (arg !== undefined) {
res.graph.addEdge(rootId, arg.entryPoint, edge_1.EdgeType.Returns);
}
}
if (config.readAllArguments) {
for (const arg of processedArguments) {
if (arg) {
res.graph.addEdge(rootId, arg.entryPoint, edge_1.EdgeType.Reads);
}
}
}
if (config.hasUnknownSideEffects) {
if (typeof config.hasUnknownSideEffects !== 'boolean') {
(0, unknown_side_effect_1.handleUnknownSideEffect)(res.graph, res.environment, rootId, config.hasUnknownSideEffects);
}
else {
(0, unknown_side_effect_1.handleUnknownSideEffect)(res.graph, res.environment, rootId);
}
}
const fnCallNames = config.treatAsFnCall?.[name.content];
if (fnCallNames) {
for (const arg of args) {
if (arg !== r_function_call_1.EmptyArgument && arg.value && fnCallNames.includes(arg.name?.content)) {
const rhs = arg.value;
let fnName;
let fnId;
if (rhs.type === type_1.RType.String) {
fnName = rhs.content.str;
fnId = rhs.info.id;
}
else if (rhs.type === type_1.RType.Symbol) {
fnName = rhs.content;
fnId = rhs.info.id;
}
else {
continue;
}
res.graph.updateToFunctionCall({
tag: vertex_1.VertexType.FunctionCall,
id: fnId,
name: fnName,
args: [],
environment: data.environment,
onlyBuiltin: false,
cds: data.controlDependencies,
origin: ['builtin:default']
});
}
}
}
if (config.cfg !== undefined) {
res.exitPoints = [...res.exitPoints, { type: config.cfg, nodeId: rootId, controlDependencies: data.controlDependencies }];
}
return res;
}
function registerBuiltInFunctions(both, names, processor, config) {
for (const name of names) {
(0, assert_1.guard)(processor !== undefined, `Processor for ${name} is undefined, maybe you have an import loop? You may run 'npm run detect-circular-deps' - although by far not all are bad`);
const id = builtInId(name);
const d = [{
type: identifier_1.ReferenceType.BuiltInFunction,
definedAt: id,
controlDependencies: undefined,
processor: (name, args, rootId, data) => processor(name, args, rootId, data, config),
config,
name,
nodeId: id
}];
exports.BuiltInMemory.set(name, d);
if (both) {
exports.EmptyBuiltInMemory.set(name, d);
}
}
}
exports.BuiltInProcessorMapper = {
'builtin:default': defaultBuiltInProcessor,
'builtin:eval': built_in_eval_1.processEvalCall,
'builtin:apply': built_in_apply_1.processApply,
'builtin:expression-list': built_in_expression_list_1.processExpressionList,
'builtin:source': built_in_source_1.processSourceCall,
'builtin:access': built_in_access_1.processAccess,
'builtin:if-then-else': built_in_if_then_else_1.processIfThenElse,
'builtin:get': built_in_get_1.processGet,
'builtin:rm': built_in_rm_1.processRm,
'builtin:library': built_in_library_1.processLibrary,
'builtin:assignment': built_in_assignment_1.processAssignment,
'builtin:special-bin-op': built_in_special_bin_op_1.processSpecialBinOp,
'builtin:pipe': built_in_pipe_1.processPipe,
'builtin:function-definition': built_in_function_definition_1.processFunctionDefinition,
'builtin:quote': built_in_quote_1.processQuote,
'builtin:for-loop': built_in_for_loop_1.processForLoop,
'builtin:repeat-loop': built_in_repeat_loop_1.processRepeatLoop,
'builtin:while-loop': built_in_while_loop_1.processWhileLoop,
'builtin:replacement': built_in_replacement_1.processReplacementFunction,
'builtin:list': built_in_list_1.processList,
'builtin:vector': built_in_vector_1.processVector,
};
exports.BuiltInEvalHandlerMapper = {
'built-in:c': resolve_1.resolveAsVector,
'builtin:vector': resolve_1.resolveAsVector
};
exports.BuiltInMemory = new Map();
exports.EmptyBuiltInMemory = new Map();
(0, built_in_config_1.registerBuiltInDefinitions)(default_builtin_config_1.DefaultBuiltinConfig);
//# sourceMappingURL=built-in.js.map