@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
64 lines • 3.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.processPipe = processPipe;
const known_call_handling_1 = require("../known-call-handling");
const assert_1 = require("../../../../../../util/assert");
const unpack_argument_1 = require("../argument/unpack-argument");
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 processPipe(name, args, rootId, data) {
const { information, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data });
if (args.length !== 2) {
logger_1.dataflowLogger.warn(`Pipe ${name.content} has something else than 2 arguments, skipping`);
return information;
}
const [lhs, rhs] = args.map(e => (0, unpack_argument_1.unpackArgument)(e));
(0, assert_1.guard)(lhs !== undefined && rhs !== undefined, () => `lhs and rhs must be present, but ${JSON.stringify(lhs)} and ${JSON.stringify(rhs)} were found instead.`);
if (rhs.type !== type_1.RType.FunctionCall) {
logger_1.dataflowLogger.warn(`Expected rhs of pipe to be a function call, but got ${rhs.type} instead.`);
}
else {
const functionCallNode = information.graph.getVertex(rhs.info.id, true);
(0, assert_1.guard)(functionCallNode?.tag === vertex_1.VertexType.FunctionCall, () => `Expected function call node with id ${rhs.info.id} to be a function call node, but got ${functionCallNode?.tag} instead.`);
// make the lhs an argument node:
const argId = lhs.info.id;
logger_1.dataflowLogger.trace(`Linking pipe arg ${argId} as first argument of ${rhs.info.id}`);
functionCallNode.args.unshift({
name: undefined,
nodeId: argId,
controlDependencies: data.controlDependencies,
type: identifier_1.ReferenceType.Function
});
information.graph.addEdge(functionCallNode.id, argId, edge_1.EdgeType.Argument | edge_1.EdgeType.Reads);
}
const firstArgument = processedArguments[0];
const uniqueIn = [...information.in];
for (const ing of (firstArgument?.in ?? [])) {
if (!uniqueIn.find(e => e.nodeId === ing.nodeId)) {
uniqueIn.push(ing);
}
}
const uniqueOut = [...information.out];
for (const outg of (firstArgument?.out ?? [])) {
if (!uniqueOut.find(e => e.nodeId === outg.nodeId)) {
uniqueOut.push(outg);
}
}
const uniqueUnknownReferences = [...information.unknownReferences];
for (const unknown of (firstArgument?.unknownReferences ?? [])) {
if (!uniqueUnknownReferences.find(e => e.nodeId === unknown.nodeId)) {
uniqueUnknownReferences.push(unknown);
}
}
return {
...information,
in: uniqueIn,
out: uniqueOut,
unknownReferences: uniqueUnknownReferences,
entryPoint: rootId
};
}
//# sourceMappingURL=built-in-pipe.js.map