@eagleoutice/flowr 2.0.16 → 2.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/cli/repl/commands/commands.js +3 -1
- package/cli/repl/commands/lineage.d.ts +15 -0
- package/cli/repl/commands/lineage.js +66 -0
- package/cli/repl/server/connection.d.ts +1 -0
- package/cli/repl/server/connection.js +36 -2
- package/cli/repl/server/messages/lineage.d.ts +16 -0
- package/cli/repl/server/messages/lineage.js +17 -0
- package/cli/repl/server/messages/messages.d.ts +2 -1
- package/cli/slicer-app.js +2 -2
- package/dataflow/environments/built-in.js +29 -9
- package/dataflow/environments/environment.js +4 -3
- package/dataflow/environments/resolve-by-name.d.ts +1 -1
- package/dataflow/environments/resolve-by-name.js +4 -4
- package/dataflow/graph/diff.js +1 -0
- package/dataflow/graph/graph.d.ts +24 -20
- package/dataflow/graph/graph.js +51 -24
- package/dataflow/graph/vertex.d.ts +6 -1
- package/dataflow/graph/vertex.js +21 -0
- package/dataflow/info.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +2 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +29 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +14 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +65 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +19 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +40 -24
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +10 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +4 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-library.js +7 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.d.ts +3 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +3 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +2 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +18 -7
- package/dataflow/internal/process/functions/call/built-in/{built-in-logical-bin-op.d.ts → built-in-special-bin-op.d.ts} +2 -1
- package/dataflow/internal/process/functions/call/built-in/{built-in-logical-bin-op.js → built-in-special-bin-op.js} +3 -3
- package/dataflow/internal/process/functions/call/common.d.ts +6 -2
- package/dataflow/internal/process/functions/call/common.js +36 -1
- package/dataflow/internal/process/functions/call/known-call-handling.d.ts +8 -3
- package/dataflow/internal/process/functions/call/known-call-handling.js +10 -7
- package/dataflow/internal/process/functions/call/named-call-handling.js +3 -1
- package/dataflow/internal/process/functions/call/unnamed-call-handling.js +1 -0
- package/dataflow/internal/process/functions/process-argument.js +0 -28
- package/package.json +3 -2
- package/r-bridge/data/data.d.ts +10 -0
- package/r-bridge/data/data.js +12 -0
- package/r-bridge/lang-4.x/ast/model/operators.js +1 -1
- package/reconstruct/auto-select/auto-select-defaults.d.ts +1 -6
- package/reconstruct/auto-select/auto-select-defaults.js +1 -13
- package/reconstruct/reconstruct.js +1 -1
- package/slicing/criterion/parse.d.ts +3 -4
- package/slicing/criterion/parse.js +3 -3
- package/slicing/static/static-slicer.d.ts +1 -1
- package/slicing/static/static-slicer.js +10 -4
- package/statistics/statistics.js +1 -1
- package/util/json.d.ts +1 -1
- package/util/json.js +3 -3
- package/util/logic.d.ts +5 -1
- package/util/version.js +1 -1
- package/abstract-interpretation/domain.d.ts +0 -57
- package/abstract-interpretation/domain.js +0 -176
- package/abstract-interpretation/handler/binop/binop.d.ts +0 -15
- package/abstract-interpretation/handler/binop/binop.js +0 -42
- package/abstract-interpretation/handler/binop/operators.d.ts +0 -2
- package/abstract-interpretation/handler/binop/operators.js +0 -28
- package/abstract-interpretation/handler/handler.d.ts +0 -6
- package/abstract-interpretation/handler/handler.js +0 -3
- package/abstract-interpretation/processor.d.ts +0 -11
- package/abstract-interpretation/processor.js +0 -84
package/dataflow/graph/graph.js
CHANGED
|
@@ -5,6 +5,7 @@ const assert_1 = require("../../util/assert");
|
|
|
5
5
|
const diff_1 = require("./diff");
|
|
6
6
|
const arrays_1 = require("../../util/arrays");
|
|
7
7
|
const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
8
|
+
const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
|
|
8
9
|
const environment_1 = require("../environments/environment");
|
|
9
10
|
const clone_1 = require("../environments/clone");
|
|
10
11
|
const built_in_1 = require("../environments/built-in");
|
|
@@ -42,8 +43,8 @@ function extractEdgeIds(from, to) {
|
|
|
42
43
|
class DataflowGraph {
|
|
43
44
|
static DEFAULT_ENVIRONMENT = undefined;
|
|
44
45
|
_idMap;
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
/* Set of vertices which have sideEffects that we do not know anything about */
|
|
47
|
+
_unknownSideEffects = new Set();
|
|
47
48
|
constructor(idMap) {
|
|
48
49
|
DataflowGraph.DEFAULT_ENVIRONMENT ??= (0, environment_1.initializeCleanEnvironments)();
|
|
49
50
|
this._idMap = idMap;
|
|
@@ -96,16 +97,22 @@ class DataflowGraph {
|
|
|
96
97
|
get idMap() {
|
|
97
98
|
return this._idMap;
|
|
98
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Retrieves the set of vertices which have side effects that we do not know anything about.
|
|
102
|
+
*/
|
|
103
|
+
get unknownSideEffects() {
|
|
104
|
+
return this._unknownSideEffects;
|
|
105
|
+
}
|
|
99
106
|
/** Allows setting the id-map explicitly (which should only be used when, e.g., you plan to compare two dataflow graphs on the same AST-basis) */
|
|
100
107
|
setIdMap(idMap) {
|
|
101
108
|
this._idMap = idMap;
|
|
102
109
|
}
|
|
103
110
|
/**
|
|
104
|
-
|
|
105
|
-
|
|
111
|
+
* @param includeDefinedFunctions - If true this will iterate over function definitions as well and not just the toplevel
|
|
112
|
+
* @returns the ids of all toplevel vertices in the graph together with their vertex information
|
|
106
113
|
*
|
|
107
114
|
* @see #edges
|
|
108
|
-
|
|
115
|
+
*/
|
|
109
116
|
*vertices(includeDefinedFunctions) {
|
|
110
117
|
if (includeDefinedFunctions) {
|
|
111
118
|
yield* this.vertexInformation.entries();
|
|
@@ -143,15 +150,15 @@ class DataflowGraph {
|
|
|
143
150
|
return this.rootVertices;
|
|
144
151
|
}
|
|
145
152
|
/**
|
|
146
|
-
|
|
147
|
-
|
|
153
|
+
* Adds a new vertex to the graph, for ease of use, some arguments are optional and filled automatically.
|
|
154
|
+
*
|
|
148
155
|
* @param vertex - The vertex to add
|
|
149
156
|
* @param asRoot - If false, this will only add the vertex but do not add it to the {@link rootIds|root vertices} of the graph.
|
|
150
157
|
* This is probably only of use, when you construct dataflow graphs for tests.
|
|
151
158
|
*
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
159
|
+
* @see DataflowGraphVertexInfo
|
|
160
|
+
* @see DataflowGraphVertexArgument
|
|
161
|
+
*/
|
|
155
162
|
addVertex(vertex, asRoot = true) {
|
|
156
163
|
const oldVertex = this.vertexInformation.get(vertex.id);
|
|
157
164
|
if (oldVertex !== undefined) {
|
|
@@ -170,11 +177,11 @@ class DataflowGraph {
|
|
|
170
177
|
return this;
|
|
171
178
|
}
|
|
172
179
|
/**
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
180
|
+
* Will insert a new edge into the graph,
|
|
181
|
+
* if the direction of the edge is of no importance (`same-read-read` or `same-def-def`), source
|
|
182
|
+
* and target will be sorted so that `from` has the lower, and `to` the higher id (default ordering).
|
|
183
|
+
* Please note that this will never make edges to {@link BuiltIn} as they are not part of the graph.
|
|
184
|
+
*/
|
|
178
185
|
addEdge(from, to, edgeInfo) {
|
|
179
186
|
const { fromId, toId } = extractEdgeIds(from, to);
|
|
180
187
|
const { type, ...rest } = edgeInfo;
|
|
@@ -232,6 +239,9 @@ class DataflowGraph {
|
|
|
232
239
|
this.rootVertices.add(root);
|
|
233
240
|
}
|
|
234
241
|
}
|
|
242
|
+
for (const unknown of otherGraph.unknownSideEffects) {
|
|
243
|
+
this._unknownSideEffects.add(unknown);
|
|
244
|
+
}
|
|
235
245
|
for (const [id, info] of otherGraph.vertexInformation) {
|
|
236
246
|
const currentInfo = this.vertexInformation.get(id);
|
|
237
247
|
this.vertexInformation.set(id, currentInfo === undefined ? info : mergeNodeInfos(currentInfo, info));
|
|
@@ -258,15 +268,6 @@ class DataflowGraph {
|
|
|
258
268
|
}
|
|
259
269
|
}
|
|
260
270
|
}
|
|
261
|
-
equals(other, diff = false, names = { left: 'left', right: 'right' }) {
|
|
262
|
-
const report = (0, diff_1.diffOfDataflowGraphs)({ name: names.left, graph: this }, { name: names.right, graph: other });
|
|
263
|
-
if (diff) {
|
|
264
|
-
return report;
|
|
265
|
-
}
|
|
266
|
-
else {
|
|
267
|
-
return report.isEqual();
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
271
|
/**
|
|
271
272
|
* Marks a vertex in the graph to be a definition
|
|
272
273
|
* @param reference - The reference to the vertex to mark as definition
|
|
@@ -281,6 +282,32 @@ class DataflowGraph {
|
|
|
281
282
|
this.vertexInformation.set(reference.nodeId, { ...vertex, tag: 'variable-definition' });
|
|
282
283
|
}
|
|
283
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Marks a vertex in the graph to be a function call with the new information
|
|
287
|
+
* @param info - The information about the new function call node
|
|
288
|
+
*/
|
|
289
|
+
updateToFunctionCall(info) {
|
|
290
|
+
const vertex = this.getVertex(info.id, true);
|
|
291
|
+
(0, assert_1.guard)(vertex !== undefined, () => `node must be defined for ${JSON.stringify(info.id)} to update it to a function call`);
|
|
292
|
+
(0, assert_1.guard)(vertex.tag === "use" /* VertexType.Use */, () => `node must be a use node for ${JSON.stringify(info.id)} to update it to a function call`);
|
|
293
|
+
this.vertexInformation.set(info.id, { ...vertex, ...info, tag: "function-call" /* VertexType.FunctionCall */ });
|
|
294
|
+
}
|
|
295
|
+
/** If you do not pass the `to` node, this will just mark the node as maybe */
|
|
296
|
+
addControlDependency(from, to, when) {
|
|
297
|
+
to = to ? (0, node_id_1.normalizeIdToNumberIfPossible)(to) : undefined;
|
|
298
|
+
const vertex = this.getVertex(from, true);
|
|
299
|
+
(0, assert_1.guard)(vertex !== undefined, () => `node must be defined for ${from} to add control dependency`);
|
|
300
|
+
vertex.controlDependencies ??= [];
|
|
301
|
+
if (to && vertex.controlDependencies.every(({ id, when: cond }) => id !== to && when !== cond)) {
|
|
302
|
+
vertex.controlDependencies.push({ id: to, when });
|
|
303
|
+
}
|
|
304
|
+
return this;
|
|
305
|
+
}
|
|
306
|
+
/** Marks the given node as having unknown side effects */
|
|
307
|
+
markIdForUnknownSideEffects(id) {
|
|
308
|
+
this._unknownSideEffects.add((0, node_id_1.normalizeIdToNumberIfPossible)(id));
|
|
309
|
+
return this;
|
|
310
|
+
}
|
|
284
311
|
}
|
|
285
312
|
exports.DataflowGraph = DataflowGraph;
|
|
286
313
|
function mergeNodeInfos(current, next) {
|
|
@@ -79,7 +79,7 @@ export interface DataflowGraphVertexFunctionDefinition extends DataflowGraphVert
|
|
|
79
79
|
*/
|
|
80
80
|
subflow: DataflowFunctionFlowInformation;
|
|
81
81
|
/**
|
|
82
|
-
* All
|
|
82
|
+
* All exit points of the function definitions.
|
|
83
83
|
* In other words: last expressions/return calls
|
|
84
84
|
*/
|
|
85
85
|
exitPoints: readonly NodeId[];
|
|
@@ -87,4 +87,9 @@ export interface DataflowGraphVertexFunctionDefinition extends DataflowGraphVert
|
|
|
87
87
|
}
|
|
88
88
|
export type DataflowGraphVertexArgument = DataflowGraphVertexUse | DataflowGraphVertexVariableDefinition | DataflowGraphVertexFunctionDefinition | DataflowGraphVertexFunctionCall | DataflowGraphValue;
|
|
89
89
|
export type DataflowGraphVertexInfo = Required<DataflowGraphVertexArgument>;
|
|
90
|
+
export declare function isValueVertex(vertex: DataflowGraphVertexBase): vertex is DataflowGraphValue;
|
|
91
|
+
export declare function isUseVertex(vertex: DataflowGraphVertexBase): vertex is DataflowGraphVertexUse;
|
|
92
|
+
export declare function isFunctionCallVertex(vertex: DataflowGraphVertexBase): vertex is DataflowGraphVertexFunctionCall;
|
|
93
|
+
export declare function isVariableDefinitionVertex(vertex: DataflowGraphVertexBase): vertex is DataflowGraphVertexVariableDefinition;
|
|
94
|
+
export declare function isFunctionDefinitionVertex(vertex: DataflowGraphVertexBase): vertex is DataflowGraphVertexFunctionDefinition;
|
|
90
95
|
export {};
|
package/dataflow/graph/vertex.js
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isFunctionDefinitionVertex = exports.isVariableDefinitionVertex = exports.isFunctionCallVertex = exports.isUseVertex = exports.isValueVertex = void 0;
|
|
4
|
+
function isValueVertex(vertex) {
|
|
5
|
+
return vertex.tag === "value" /* VertexType.Value */;
|
|
6
|
+
}
|
|
7
|
+
exports.isValueVertex = isValueVertex;
|
|
8
|
+
function isUseVertex(vertex) {
|
|
9
|
+
return vertex.tag === "use" /* VertexType.Use */;
|
|
10
|
+
}
|
|
11
|
+
exports.isUseVertex = isUseVertex;
|
|
12
|
+
function isFunctionCallVertex(vertex) {
|
|
13
|
+
return vertex.tag === "function-call" /* VertexType.FunctionCall */;
|
|
14
|
+
}
|
|
15
|
+
exports.isFunctionCallVertex = isFunctionCallVertex;
|
|
16
|
+
function isVariableDefinitionVertex(vertex) {
|
|
17
|
+
return vertex.tag === "variable-definition" /* VertexType.VariableDefinition */;
|
|
18
|
+
}
|
|
19
|
+
exports.isVariableDefinitionVertex = isVariableDefinitionVertex;
|
|
20
|
+
function isFunctionDefinitionVertex(vertex) {
|
|
21
|
+
return vertex.tag === "function-definition" /* VertexType.FunctionDefinition */;
|
|
22
|
+
}
|
|
23
|
+
exports.isFunctionDefinitionVertex = isFunctionDefinitionVertex;
|
|
3
24
|
//# sourceMappingURL=vertex.js.map
|
package/dataflow/info.d.ts
CHANGED
|
@@ -57,7 +57,7 @@ export interface DataflowInformation extends DataflowCfgInformation {
|
|
|
57
57
|
graph: DataflowGraph;
|
|
58
58
|
}
|
|
59
59
|
export declare function initializeCleanDataflowInformation<T>(entryPoint: NodeId, data: Pick<DataflowProcessorInformation<T>, 'environment' | 'completeAst'>): DataflowInformation;
|
|
60
|
-
export declare function happensInEveryBranch(controlDependencies: ControlDependency[] | undefined): boolean;
|
|
60
|
+
export declare function happensInEveryBranch(controlDependencies: readonly ControlDependency[] | undefined): boolean;
|
|
61
61
|
export declare function alwaysExits(data: DataflowInformation): boolean;
|
|
62
62
|
export declare function filterOutLoopExitPoints(exitPoints: readonly ExitPoint[]): readonly ExitPoint[];
|
|
63
63
|
export declare function diffControlDependency<Report extends WriteableDifferenceReport>(a: ControlDependency | undefined, b: ControlDependency | undefined, info: GenericDifferenceInformation<Report>): void;
|
|
@@ -4,6 +4,7 @@ import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/
|
|
|
4
4
|
import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
5
5
|
import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
6
6
|
import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
7
|
+
import type { ForceArguments } from '../common';
|
|
7
8
|
export declare function processAccess<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: {
|
|
8
9
|
treatIndicesAsString: boolean;
|
|
9
|
-
}): DataflowInformation;
|
|
10
|
+
} & ForceArguments): DataflowInformation;
|
|
@@ -6,16 +6,41 @@ const known_call_handling_1 = require("../known-call-handling");
|
|
|
6
6
|
const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
7
7
|
const logger_1 = require("../../../../../logger");
|
|
8
8
|
const environment_1 = require("../../../../../environments/environment");
|
|
9
|
+
const built_in_1 = require("../../../../../environments/built-in");
|
|
10
|
+
const built_in_assignment_1 = require("./built-in-assignment");
|
|
11
|
+
function tableAssignmentProcessor(name, args, rootId, data, outInfo) {
|
|
12
|
+
outInfo.definitionRootNodes.push(rootId);
|
|
13
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
14
|
+
}
|
|
9
15
|
function processAccess(name, args, rootId, data, config) {
|
|
10
16
|
if (args.length < 2) {
|
|
11
17
|
logger_1.dataflowLogger.warn(`Access ${name.content} has less than 2 arguments, skipping`);
|
|
12
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
18
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs }).information;
|
|
13
19
|
}
|
|
14
20
|
const head = args[0];
|
|
15
21
|
(0, assert_1.guard)(head !== r_function_call_1.EmptyArgument, () => `Access ${name.content} has no source, impossible!`);
|
|
16
22
|
let fnCall;
|
|
17
23
|
if (!config.treatIndicesAsString) {
|
|
18
|
-
|
|
24
|
+
/* within an access operation which treats its fields, we redefine the table assignment ':=' as a trigger if this is to be treated as a definition */
|
|
25
|
+
// do we have a local definition that needs to be recovered?
|
|
26
|
+
const existing = data.environment.current.memory.get(':=');
|
|
27
|
+
const outInfo = { definitionRootNodes: [] };
|
|
28
|
+
data.environment.current.memory.set(':=', [{
|
|
29
|
+
kind: 'built-in-function',
|
|
30
|
+
definedAt: built_in_1.BuiltIn,
|
|
31
|
+
controlDependencies: undefined,
|
|
32
|
+
processor: (name, args, rootId, data) => tableAssignmentProcessor(name, args, rootId, data, outInfo),
|
|
33
|
+
name: ':=',
|
|
34
|
+
nodeId: built_in_1.BuiltIn
|
|
35
|
+
}]);
|
|
36
|
+
fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs });
|
|
37
|
+
/* recover the environment */
|
|
38
|
+
if (existing !== undefined) {
|
|
39
|
+
data.environment.current.memory.set(':=', existing);
|
|
40
|
+
}
|
|
41
|
+
if (head.value && outInfo.definitionRootNodes.length > 0) {
|
|
42
|
+
(0, built_in_assignment_1.markAsAssignment)(fnCall.information, { kind: 'variable', name: head.value.lexeme ?? '', nodeId: head.value.info.id, definedAt: rootId, controlDependencies: [] }, outInfo.definitionRootNodes, rootId);
|
|
43
|
+
}
|
|
19
44
|
}
|
|
20
45
|
else {
|
|
21
46
|
const newArgs = [...args];
|
|
@@ -38,7 +63,7 @@ function processAccess(name, args, rootId, data, config) {
|
|
|
38
63
|
};
|
|
39
64
|
}
|
|
40
65
|
}
|
|
41
|
-
fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args: newArgs, rootId, data });
|
|
66
|
+
fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args: newArgs, rootId, data, forceArgs: config.forceArgs });
|
|
42
67
|
}
|
|
43
68
|
const info = fnCall.information;
|
|
44
69
|
info.graph.addEdge(name.info.id, fnCall.processedArguments[0]?.entryPoint ?? head.info.id, { type: 8 /* EdgeType.Returns */ });
|
|
@@ -47,10 +72,7 @@ function processAccess(name, args, rootId, data, config) {
|
|
|
47
72
|
if (arg !== undefined) {
|
|
48
73
|
info.graph.addEdge(name.info.id, arg.entryPoint, { type: 1 /* EdgeType.Reads */ });
|
|
49
74
|
}
|
|
50
|
-
if
|
|
51
|
-
// everything but the first is disabled here
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
75
|
+
/* we include the read edges to the constant arguments as well so that they are included if necessary */
|
|
54
76
|
}
|
|
55
77
|
return {
|
|
56
78
|
...info,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DataflowProcessorInformation } from '../../../../../processor';
|
|
2
|
+
import type { DataflowInformation } from '../../../../../info';
|
|
3
|
+
import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
4
|
+
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
5
|
+
import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
6
|
+
import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
7
|
+
import type { MergeableRecord } from '../../../../../../util/objects';
|
|
8
|
+
export interface BuiltInApplyConfiguration extends MergeableRecord {
|
|
9
|
+
/** the 0-based index of the argument which is the actual function passed, defaults to 1 */
|
|
10
|
+
readonly indexOfFunction?: number;
|
|
11
|
+
/** does the argument have a name that it can be given by as well? */
|
|
12
|
+
readonly nameOfFunctionArgument?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function processApply<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, { indexOfFunction, nameOfFunctionArgument }: BuiltInApplyConfiguration): DataflowInformation;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processApply = void 0;
|
|
4
|
+
const known_call_handling_1 = require("../known-call-handling");
|
|
5
|
+
const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
6
|
+
const logger_1 = require("../../../../../logger");
|
|
7
|
+
function processApply(name, args, rootId, data, { indexOfFunction = 1, nameOfFunctionArgument }) {
|
|
8
|
+
/* as the length is one-based and the argument filter mapping is zero-based, we do not have to subtract 1 */
|
|
9
|
+
const forceArgsMask = new Array(indexOfFunction).fill(false);
|
|
10
|
+
forceArgsMask.push(true);
|
|
11
|
+
const { information, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({
|
|
12
|
+
name, args, rootId, data, forceArgs: forceArgsMask
|
|
13
|
+
});
|
|
14
|
+
let index = indexOfFunction;
|
|
15
|
+
/* search, if one of the arguments actually contains the argument name if given in the config */
|
|
16
|
+
if (nameOfFunctionArgument !== undefined) {
|
|
17
|
+
const mayFn = args.findIndex(arg => arg !== r_function_call_1.EmptyArgument && arg.name && arg.name.content === nameOfFunctionArgument);
|
|
18
|
+
if (mayFn >= 0) {
|
|
19
|
+
index = mayFn;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/* validate, that we indeed have so many arguments to fill this one :D */
|
|
23
|
+
if (index >= args.length) {
|
|
24
|
+
logger_1.dataflowLogger.warn(`Function argument at index ${index} not found, skipping`);
|
|
25
|
+
return information;
|
|
26
|
+
}
|
|
27
|
+
const arg = args[index];
|
|
28
|
+
if (arg === r_function_call_1.EmptyArgument || arg?.value?.type !== "RSymbol" /* RType.Symbol */) {
|
|
29
|
+
logger_1.dataflowLogger.warn(`Expected symbol as argument at index ${index}, but got ${JSON.stringify(arg)} instead.`);
|
|
30
|
+
return information;
|
|
31
|
+
}
|
|
32
|
+
const functionSymbol = arg.value;
|
|
33
|
+
const allOtherArguments = processedArguments.filter((_, i) => i !== index).map((arg, i) => {
|
|
34
|
+
const counterpart = args[i];
|
|
35
|
+
if (arg && counterpart !== r_function_call_1.EmptyArgument && counterpart.name) {
|
|
36
|
+
return {
|
|
37
|
+
name: counterpart.name.content,
|
|
38
|
+
controlDependencies: data.controlDependencies,
|
|
39
|
+
nodeId: arg.entryPoint
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return r_function_call_1.EmptyArgument;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const applyCallId = functionSymbol.info.id;
|
|
47
|
+
/* identify it as a full-blown function call :) */
|
|
48
|
+
information.graph.updateToFunctionCall({
|
|
49
|
+
tag: "function-call" /* VertexType.FunctionCall */,
|
|
50
|
+
id: applyCallId,
|
|
51
|
+
name: functionSymbol.content,
|
|
52
|
+
args: allOtherArguments,
|
|
53
|
+
environment: data.environment,
|
|
54
|
+
onlyBuiltin: false,
|
|
55
|
+
controlDependencies: data.controlDependencies
|
|
56
|
+
});
|
|
57
|
+
for (const arg of processedArguments) {
|
|
58
|
+
if (arg) {
|
|
59
|
+
information.graph.addEdge(applyCallId, arg.entryPoint, { type: 64 /* EdgeType.Argument */ });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return information;
|
|
63
|
+
}
|
|
64
|
+
exports.processApply = processApply;
|
|
65
|
+
//# sourceMappingURL=built-in-apply.js.map
|
|
@@ -5,7 +5,11 @@ import type { RNode } from '../../../../../../r-bridge/lang-4.x/ast/model/model'
|
|
|
5
5
|
import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
6
6
|
import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
7
7
|
import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
8
|
-
|
|
8
|
+
import type { IdentifierDefinition } from '../../../../../environments/identifier';
|
|
9
|
+
import type { ForceArguments } from '../common';
|
|
10
|
+
import type { REnvironmentInformation } from '../../../../../environments/environment';
|
|
11
|
+
import type { DataflowGraph } from '../../../../../graph/graph';
|
|
12
|
+
export interface AssignmentConfiguration extends ForceArguments {
|
|
9
13
|
readonly superAssignment?: boolean;
|
|
10
14
|
readonly swapSourceAndTarget?: boolean;
|
|
11
15
|
readonly makeMaybe?: boolean;
|
|
@@ -19,7 +23,7 @@ export interface AssignmentConfiguration {
|
|
|
19
23
|
*/
|
|
20
24
|
export declare function processAssignment<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: AssignmentConfiguration): DataflowInformation;
|
|
21
25
|
export interface AssignmentToSymbolParameters<OtherInfo> extends AssignmentConfiguration {
|
|
22
|
-
readonly
|
|
26
|
+
readonly nameOfAssignmentFunction: string;
|
|
23
27
|
readonly source: RNode<OtherInfo & ParentInformation>;
|
|
24
28
|
readonly args: [DataflowInformation, DataflowInformation];
|
|
25
29
|
readonly target: RSymbol<OtherInfo & ParentInformation>;
|
|
@@ -27,3 +31,16 @@ export interface AssignmentToSymbolParameters<OtherInfo> extends AssignmentConfi
|
|
|
27
31
|
readonly data: DataflowProcessorInformation<OtherInfo>;
|
|
28
32
|
readonly information: DataflowInformation;
|
|
29
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Consider a call like `x <- v`
|
|
36
|
+
* @param information - the information to define the assignment within
|
|
37
|
+
* @param nodeToDefine - `x`
|
|
38
|
+
* @param sourceIds - `v`
|
|
39
|
+
* @param rootIdOfAssignment - `<-`
|
|
40
|
+
* @param quoteSource - whether to quote the source (i.e., define `x` without a direct reference to `v`)
|
|
41
|
+
* @param superAssignment - whether this is a super assignment (i.e., `<<-`)
|
|
42
|
+
*/
|
|
43
|
+
export declare function markAsAssignment(information: {
|
|
44
|
+
environment: REnvironmentInformation;
|
|
45
|
+
graph: DataflowGraph;
|
|
46
|
+
}, nodeToDefine: IdentifierDefinition, sourceIds: readonly NodeId[], rootIdOfAssignment: NodeId, quoteSource?: boolean, superAssignment?: boolean): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.processAssignment = void 0;
|
|
3
|
+
exports.markAsAssignment = exports.processAssignment = void 0;
|
|
4
4
|
const known_call_handling_1 = require("../known-call-handling");
|
|
5
5
|
const assert_1 = require("../../../../../../util/assert");
|
|
6
6
|
const log_1 = require("../../../../../../util/log");
|
|
@@ -15,7 +15,7 @@ function toReplacementSymbol(target, prefix, superAssignment) {
|
|
|
15
15
|
return {
|
|
16
16
|
type: "RSymbol" /* RType.Symbol */,
|
|
17
17
|
info: target.info,
|
|
18
|
-
/* they are all mapped to
|
|
18
|
+
/* they are all mapped to `<-` in R, but we mark super as well */
|
|
19
19
|
content: `${prefix}${superAssignment ? '<<-' : '<-'}`,
|
|
20
20
|
lexeme: target.lexeme,
|
|
21
21
|
location: target.location,
|
|
@@ -35,16 +35,16 @@ function processAssignment(name,
|
|
|
35
35
|
args, rootId, data, config) {
|
|
36
36
|
if (args.length != 2) {
|
|
37
37
|
logger_1.dataflowLogger.warn(`Assignment ${name.content} has something else than 2 arguments, skipping`);
|
|
38
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
38
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs }).information;
|
|
39
39
|
}
|
|
40
40
|
const effectiveArgs = getEffectiveOrder(config, args);
|
|
41
41
|
const { target, source } = extractSourceAndTarget(effectiveArgs, name);
|
|
42
42
|
const { type, named } = target;
|
|
43
43
|
if (type === "RSymbol" /* RType.Symbol */) {
|
|
44
|
-
const res = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, reverseOrder: !config.swapSourceAndTarget });
|
|
44
|
+
const res = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, reverseOrder: !config.swapSourceAndTarget, forceArgs: config.forceArgs });
|
|
45
45
|
return processAssignmentToSymbol({
|
|
46
46
|
...config,
|
|
47
|
-
name,
|
|
47
|
+
nameOfAssignmentFunction: name.content,
|
|
48
48
|
source,
|
|
49
49
|
target,
|
|
50
50
|
args: getEffectiveOrder(config, res.processedArguments),
|
|
@@ -68,7 +68,7 @@ args, rootId, data, config) {
|
|
|
68
68
|
return processAssignmentToString(target, args, name, rootId, data, config, source);
|
|
69
69
|
}
|
|
70
70
|
logger_1.dataflowLogger.warn(`Assignment ${name.content} has an unknown target type ${target.type}, skipping`);
|
|
71
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args: effectiveArgs, rootId, data }).information;
|
|
71
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args: effectiveArgs, rootId, data, forceArgs: config.forceArgs }).information;
|
|
72
72
|
}
|
|
73
73
|
exports.processAssignment = processAssignment;
|
|
74
74
|
function extractSourceAndTarget(args, name) {
|
|
@@ -105,11 +105,12 @@ function processAssignmentToString(target, args, name, rootId, data, config, sou
|
|
|
105
105
|
args: mappedArgs,
|
|
106
106
|
rootId,
|
|
107
107
|
data,
|
|
108
|
-
reverseOrder: !config.swapSourceAndTarget
|
|
108
|
+
reverseOrder: !config.swapSourceAndTarget,
|
|
109
|
+
forceArgs: config.forceArgs
|
|
109
110
|
});
|
|
110
111
|
return processAssignmentToSymbol({
|
|
111
112
|
...config,
|
|
112
|
-
name,
|
|
113
|
+
nameOfAssignmentFunction: name.content,
|
|
113
114
|
source,
|
|
114
115
|
target: symbol,
|
|
115
116
|
args: getEffectiveOrder(config, res.processedArguments),
|
|
@@ -121,10 +122,38 @@ function processAssignmentToString(target, args, name, rootId, data, config, sou
|
|
|
121
122
|
function checkFunctionDef(source, sourceInfo) {
|
|
122
123
|
return sourceInfo.graph.getVertex(source.info.id)?.tag === "function-definition" /* VertexType.FunctionDefinition */;
|
|
123
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Consider a call like `x <- v`
|
|
127
|
+
* @param information - the information to define the assignment within
|
|
128
|
+
* @param nodeToDefine - `x`
|
|
129
|
+
* @param sourceIds - `v`
|
|
130
|
+
* @param rootIdOfAssignment - `<-`
|
|
131
|
+
* @param quoteSource - whether to quote the source (i.e., define `x` without a direct reference to `v`)
|
|
132
|
+
* @param superAssignment - whether this is a super assignment (i.e., `<<-`)
|
|
133
|
+
*/
|
|
134
|
+
function markAsAssignment(information, nodeToDefine, sourceIds, rootIdOfAssignment, quoteSource, superAssignment) {
|
|
135
|
+
information.environment = (0, define_1.define)(nodeToDefine, superAssignment, information.environment);
|
|
136
|
+
information.graph.setDefinitionOfVertex(nodeToDefine);
|
|
137
|
+
if (!quoteSource) {
|
|
138
|
+
for (const sourceId of sourceIds) {
|
|
139
|
+
information.graph.addEdge(nodeToDefine, sourceId, { type: 2 /* EdgeType.DefinedBy */ });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
information.graph.addEdge(nodeToDefine, rootIdOfAssignment, { type: 2 /* EdgeType.DefinedBy */ });
|
|
143
|
+
// kinda dirty, but we have to remove existing read edges for the symbol, added by the child
|
|
144
|
+
const out = information.graph.outgoingEdges(nodeToDefine.nodeId);
|
|
145
|
+
for (const [id, edge] of (out ?? [])) {
|
|
146
|
+
edge.types &= ~1 /* EdgeType.Reads */;
|
|
147
|
+
if (edge.types == 0) {
|
|
148
|
+
out?.delete(id);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
exports.markAsAssignment = markAsAssignment;
|
|
124
153
|
/**
|
|
125
154
|
* Helper function whenever it is known that the _target_ of an assignment is a (single) symbol (i.e. `x <- ...`, but not `names(x) <- ...`).
|
|
126
155
|
*/
|
|
127
|
-
function processAssignmentToSymbol({
|
|
156
|
+
function processAssignmentToSymbol({ nameOfAssignmentFunction, source, args: [targetArg, sourceArg], target, rootId, data, information, superAssignment, makeMaybe, quoteSource }) {
|
|
128
157
|
const isFunctionDef = checkFunctionDef(source, sourceArg);
|
|
129
158
|
const writeNodes = produceWrittenNodes(rootId, targetArg, isFunctionDef, data, makeMaybe ?? false);
|
|
130
159
|
if (writeNodes.length !== 1 && log_1.log.settings.minLevel <= 4 /* LogLevel.Warn */) {
|
|
@@ -132,25 +161,12 @@ function processAssignmentToSymbol({ name, source, args: [targetArg, sourceArg],
|
|
|
132
161
|
}
|
|
133
162
|
// we drop the first arg which we use to pass along arguments :D
|
|
134
163
|
const readFromSourceWritten = sourceArg.out.slice(1);
|
|
135
|
-
const readTargets = [{ nodeId: rootId, name:
|
|
164
|
+
const readTargets = [{ nodeId: rootId, name: nameOfAssignmentFunction, controlDependencies: data.controlDependencies }, ...sourceArg.unknownReferences, ...sourceArg.in, ...targetArg.in.filter(i => i.nodeId !== target.info.id), ...readFromSourceWritten];
|
|
136
165
|
const writeTargets = [...writeNodes, ...writeNodes, ...readFromSourceWritten];
|
|
137
166
|
information.environment = (0, overwrite_1.overwriteEnvironment)(targetArg.environment, sourceArg.environment);
|
|
138
167
|
// install assigned variables in environment
|
|
139
168
|
for (const write of writeNodes) {
|
|
140
|
-
information
|
|
141
|
-
information.graph.setDefinitionOfVertex(write);
|
|
142
|
-
if (!quoteSource) {
|
|
143
|
-
information.graph.addEdge(write, source.info.id, { type: 2 /* EdgeType.DefinedBy */ });
|
|
144
|
-
}
|
|
145
|
-
information.graph.addEdge(write, rootId, { type: 2 /* EdgeType.DefinedBy */ });
|
|
146
|
-
// kinda dirty, but we have to remove existing read edges for the symbol, added by the child
|
|
147
|
-
const out = information.graph.outgoingEdges(write.nodeId);
|
|
148
|
-
for (const [id, edge] of (out ?? [])) {
|
|
149
|
-
edge.types &= ~1 /* EdgeType.Reads */;
|
|
150
|
-
if (edge.types == 0) {
|
|
151
|
-
out?.delete(id);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
169
|
+
markAsAssignment(information, write, [source.info.id], rootId, quoteSource, superAssignment);
|
|
154
170
|
}
|
|
155
171
|
information.graph.addEdge(rootId, targetArg.entryPoint, { type: 8 /* EdgeType.Returns */ });
|
|
156
172
|
if (quoteSource) {
|
|
@@ -63,7 +63,7 @@ function processForLoop(name, args, rootId, data) {
|
|
|
63
63
|
for (const readId of readIdsToLink) {
|
|
64
64
|
nextGraph.addEdge(readId.nodeId, write.nodeId, { type: 1 /* EdgeType.Reads */ });
|
|
65
65
|
}
|
|
66
|
-
// now, we remove the name from the id shares as they are no longer
|
|
66
|
+
// now, we remove the name from the id shares as they are no longer necessary
|
|
67
67
|
nameIdShares.delete(name);
|
|
68
68
|
nextGraph.setDefinitionOfVertex(write);
|
|
69
69
|
}
|
|
@@ -45,8 +45,17 @@ function processFunctionDefinition(name, args, rootId, data) {
|
|
|
45
45
|
const readInBody = [...body.in, ...body.unknownReferences];
|
|
46
46
|
// there is no uncertainty regarding the arguments, as if a function header is executed, so is its body
|
|
47
47
|
const remainingRead = (0, linker_1.linkInputs)(readInBody, paramsEnvironments, readInParameters.slice(), body.graph, true /* functions do not have to be called */);
|
|
48
|
+
// functions can be called multiple times,
|
|
49
|
+
// so if they have a global effect, we have to link them as if they would be executed a loop
|
|
50
|
+
/* theoretically, we should just check if there is a global effect-write somewhere within */
|
|
51
|
+
if (remainingRead.length > 0) {
|
|
52
|
+
const nameIdShares = (0, linker_1.produceNameSharedIdMap)(remainingRead);
|
|
53
|
+
const definedInLocalEnvironment = new Set([...bodyEnvironment.current.memory.values()].flat().map(d => d.nodeId));
|
|
54
|
+
// Everything that is in body.out but not within the local environment populated for the function scope is a potential escape ~> global definition
|
|
55
|
+
const globalBodyOut = body.out.filter(d => !definedInLocalEnvironment.has(d.nodeId));
|
|
56
|
+
(0, linker_1.linkCircularRedefinitionsWithinALoop)(body.graph, nameIdShares, globalBodyOut);
|
|
57
|
+
}
|
|
48
58
|
subgraph.mergeWith(body.graph);
|
|
49
|
-
logger_1.dataflowLogger.trace(`Function definition with id ${name.info.id} has ${remainingRead.length} remaining reads`);
|
|
50
59
|
const outEnvironment = (0, overwrite_1.overwriteEnvironment)(paramsEnvironments, bodyEnvironment);
|
|
51
60
|
for (const read of remainingRead) {
|
|
52
61
|
if (read.name) {
|
|
@@ -33,23 +33,23 @@ function processIfThenElse(name, args, rootId, data) {
|
|
|
33
33
|
// we should defer this to the abstract interpretation
|
|
34
34
|
const conditionIsFalse = (0, resolve_by_name_1.resolvesToBuiltInConstant)(condArg?.lexeme, data.environment, false);
|
|
35
35
|
const conditionIsTrue = (0, resolve_by_name_1.resolvesToBuiltInConstant)(condArg?.lexeme, data.environment, true);
|
|
36
|
-
if (conditionIsFalse !==
|
|
36
|
+
if (conditionIsFalse !== 0 /* Ternary.Always */) {
|
|
37
37
|
then = (0, processor_1.processDataflowFor)(thenArg, data);
|
|
38
38
|
if (then.entryPoint) {
|
|
39
39
|
then.graph.addEdge(name.info.id, then.entryPoint, { type: 8 /* EdgeType.Returns */ });
|
|
40
40
|
}
|
|
41
|
-
if (conditionIsTrue !==
|
|
41
|
+
if (conditionIsTrue !== 0 /* Ternary.Always */) {
|
|
42
42
|
makeThenMaybe = true;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
let otherwise;
|
|
46
46
|
let makeOtherwiseMaybe = false;
|
|
47
|
-
if (otherwiseArg !== undefined && conditionIsTrue !==
|
|
47
|
+
if (otherwiseArg !== undefined && conditionIsTrue !== 0 /* Ternary.Always */) {
|
|
48
48
|
otherwise = (0, processor_1.processDataflowFor)(otherwiseArg, data);
|
|
49
49
|
if (otherwise.entryPoint) {
|
|
50
50
|
otherwise.graph.addEdge(name.info.id, otherwise.entryPoint, { type: 8 /* EdgeType.Returns */ });
|
|
51
51
|
}
|
|
52
|
-
if (conditionIsFalse !==
|
|
52
|
+
if (conditionIsFalse !== 0 /* Ternary.Always */) {
|
|
53
53
|
makeOtherwiseMaybe = true;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -6,14 +6,15 @@ const logger_1 = require("../../../../../logger");
|
|
|
6
6
|
const unpack_argument_1 = require("../argument/unpack-argument");
|
|
7
7
|
const make_argument_1 = require("../argument/make-argument");
|
|
8
8
|
function processLibrary(name, args, rootId, data) {
|
|
9
|
+
/* we do not really know what loading the library does and what side effects it causes, hence we mark it as an unknown side effect */
|
|
9
10
|
if (args.length !== 1) {
|
|
10
11
|
logger_1.dataflowLogger.warn(`Currently only one-arg library-likes are allows (for ${name.content}), skipping`);
|
|
11
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
12
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, hasUnknownSideEffect: true }).information;
|
|
12
13
|
}
|
|
13
14
|
const nameToLoad = (0, unpack_argument_1.unpackArgument)(args[0]);
|
|
14
15
|
if (nameToLoad === undefined || nameToLoad.type !== "RSymbol" /* RType.Symbol */) {
|
|
15
16
|
logger_1.dataflowLogger.warn('No library name provided, skipping');
|
|
16
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
17
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, hasUnknownSideEffect: true }).information;
|
|
17
18
|
}
|
|
18
19
|
// treat as a function call but convert the first argument to a string
|
|
19
20
|
const newArg = {
|
|
@@ -26,7 +27,10 @@ function processLibrary(name, args, rootId, data) {
|
|
|
26
27
|
str: nameToLoad.content
|
|
27
28
|
}
|
|
28
29
|
};
|
|
29
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({
|
|
30
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({
|
|
31
|
+
name, args: (0, make_argument_1.wrapArgumentsUnnamed)([newArg], data.completeAst.idMap), rootId, data,
|
|
32
|
+
hasUnknownSideEffect: true
|
|
33
|
+
}).information;
|
|
30
34
|
}
|
|
31
35
|
exports.processLibrary = processLibrary;
|
|
32
36
|
//# sourceMappingURL=built-in-library.js.map
|
|
@@ -4,6 +4,7 @@ import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/
|
|
|
4
4
|
import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
5
5
|
import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
6
6
|
import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
7
|
-
|
|
7
|
+
import type { ForceArguments } from '../common';
|
|
8
|
+
export declare function processQuote<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: {
|
|
8
9
|
quoteArgumentsWithIndex?: number;
|
|
9
|
-
}): DataflowInformation;
|
|
10
|
+
} & ForceArguments): DataflowInformation;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.processQuote = void 0;
|
|
4
4
|
const known_call_handling_1 = require("../known-call-handling");
|
|
5
5
|
function processQuote(name, args, rootId, data, config) {
|
|
6
|
-
const { information, processedArguments, fnRef } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data });
|
|
6
|
+
const { information, processedArguments, fnRef } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs });
|
|
7
7
|
const inRefs = [fnRef];
|
|
8
8
|
const outRefs = [];
|
|
9
9
|
const unknownRefs = [];
|