UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

82 lines 3.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.processApply = processApply; 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 logger_1 = require("../../../../../logger"); const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type"); const vertex_1 = require("../../../../../graph/vertex"); const edge_1 = require("../../../../../graph/edge"); const identifier_1 = require("../../../../../environments/identifier"); function processApply(name, args, rootId, data, { indexOfFunction = 1, nameOfFunctionArgument, unquoteFunction }) { /* as the length is one-based and the argument filter mapping is zero-based, we do not have to subtract 1 */ const forceArgsMask = new Array(indexOfFunction).fill(false); forceArgsMask.push(true); const { information, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: forceArgsMask }); let index = indexOfFunction; /* search, if one of the arguments actually contains the argument name if given in the config */ if (nameOfFunctionArgument !== undefined) { const mayFn = args.findIndex(arg => arg !== r_function_call_1.EmptyArgument && arg.name && arg.name.content === nameOfFunctionArgument); if (mayFn >= 0) { index = mayFn; } } /* validate, that we indeed have so many arguments to fill this one :D */ if (index >= args.length) { logger_1.dataflowLogger.warn(`Function argument at index ${index} not found, skipping`); return information; } const arg = args[index]; if (arg === r_function_call_1.EmptyArgument || !arg.value || (!unquoteFunction && arg.value.type !== type_1.RType.Symbol)) { logger_1.dataflowLogger.warn(`Expected symbol as argument at index ${index}, but got ${JSON.stringify(arg)} instead.`); return information; } let functionId; let functionName; const val = arg.value; if (unquoteFunction && val.type === type_1.RType.String) { functionId = val.info.id; functionName = val.content.str; } else if (val.type === type_1.RType.Symbol) { functionId = val.info.id; functionName = val.content; } else { logger_1.dataflowLogger.warn(`Expected symbol or string as function argument at index ${index}, but got ${JSON.stringify(val)} instead.`); return information; } const allOtherArguments = processedArguments.filter((_, i) => i !== index).map((arg, i) => { const counterpart = args[i]; if (arg && counterpart !== r_function_call_1.EmptyArgument && counterpart.name) { return { name: counterpart.name.content, controlDependencies: data.controlDependencies, type: identifier_1.ReferenceType.Argument, nodeId: arg.entryPoint }; } else { return r_function_call_1.EmptyArgument; } }); /* identify it as a full-blown function call :) */ information.graph.updateToFunctionCall({ tag: vertex_1.VertexType.FunctionCall, id: functionId, name: functionName, args: allOtherArguments, environment: data.environment, onlyBuiltin: false, controlDependencies: data.controlDependencies }); for (const arg of processedArguments) { if (arg) { information.graph.addEdge(functionId, arg.entryPoint, edge_1.EdgeType.Argument); } } return information; } //# sourceMappingURL=built-in-apply.js.map