@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
61 lines • 3.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.processGet = processGet;
const known_call_handling_1 = require("../known-call-handling");
const unpack_argument_1 = require("../argument/unpack-argument");
const make_argument_1 = require("../argument/make-argument");
const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
const logger_1 = require("../../../../../logger");
const retriever_1 = require("../../../../../../r-bridge/retriever");
const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
const edge_1 = require("../../../../../graph/edge");
const identifier_1 = require("../../../../../environments/identifier");
const built_in_proc_name_1 = require("../../../../../environments/built-in-proc-name");
const built_in_envir_utils_1 = require("./built-in-envir-utils");
/**
* Processes a built-in 'get' function call.
*
* When an `envir` argument is present and resolves to a variable with a tracked environment
* state (set up by `new.env()` + `assign(..., envir=...)`), the lookup is performed inside
* that environment so that the correct definition is found and the returned {@link DataflowInformation}
* contains the right read edges.
*/
function processGet(name, args, rootId, data) {
/* use the custom environment for resolution when envir points to a tracked env */
const resolution = (0, built_in_envir_utils_1.resolveEnvirArg)(args, data);
/* the first arg must be a string naming the variable to retrieve */
const firstArg = args.length >= 1 ? args[0] : undefined;
const retrieve = firstArg !== undefined && firstArg !== r_function_call_1.EmptyArgument
? (0, unpack_argument_1.unpackNonameArg)(firstArg)
: undefined;
if (retrieve === undefined || retrieve.type !== type_1.RType.String) {
logger_1.dataflowLogger.warn(`symbol access with ${identifier_1.Identifier.toString(name.content)} has not 1 string argument, skipping`);
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
}
const treatTargetAsSymbol = {
type: type_1.RType.Symbol,
info: retrieve.info,
content: (0, retriever_1.removeRQuotes)(retrieve.lexeme),
lexeme: retrieve.lexeme,
location: retrieve.location
};
/* resolve in the custom environment if one was found, else the global one.
* Pass remaining original args (e.g. envir=e) so they appear as Use vertices in the graph. */
const { information, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({
name,
args: [...(0, make_argument_1.wrapArgumentsUnnamed)([treatTargetAsSymbol], data.completeAst.idMap), ...args.slice(1)],
rootId,
data: resolution ? resolution.envirData : data,
origin: built_in_proc_name_1.BuiltInProcName.Get
});
const firstProcessed = processedArguments[0];
if (firstProcessed) {
information.graph.addEdge(rootId, firstProcessed.entryPoint, edge_1.EdgeType.Returns | edge_1.EdgeType.Reads);
}
if (resolution) {
information.graph.addEdge(rootId, resolution.envirNodeId, edge_1.EdgeType.Reads);
}
/* restore the caller's (global) environment so we don't leak envState upward */
return { ...information, environment: data.environment };
}
//# sourceMappingURL=built-in-get.js.map