@eagleoutice/flowr 1.3.11 → 1.3.13

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.
Files changed (125) hide show
  1. package/cli/common/scripts-info.d.ts +1 -1
  2. package/package.json +3 -4
  3. package/benchmark/benchmark-slicer.js +0 -223
  4. package/core/pipeline-executor.js +0 -221
  5. package/core/stepping-slicer.js +0 -160
  6. package/core/steps/all/00-parse.js +0 -19
  7. package/core/steps/all/10-normalize.js +0 -21
  8. package/core/steps/all/20-dataflow.js +0 -21
  9. package/core/steps/all/30-slice.js +0 -16
  10. package/core/steps/all/40-reconstruct.js +0 -16
  11. package/core/steps/all/core/00-parse.js +0 -24
  12. package/core/steps/all/core/10-normalize.js +0 -46
  13. package/core/steps/all/core/20-dataflow.js +0 -39
  14. package/core/steps/all/static-slicing/00-slice.js +0 -21
  15. package/core/steps/all/static-slicing/10-reconstruct.js +0 -21
  16. package/core/steps/index.js +0 -21
  17. package/core/steps/input.js +0 -3
  18. package/core/steps/output.js +0 -3
  19. package/core/steps/pipeline/create.js +0 -130
  20. package/core/steps/pipeline/default.js +0 -15
  21. package/core/steps/pipeline/dependency-checker.js +0 -76
  22. package/core/steps/pipeline/index.js +0 -20
  23. package/core/steps/pipeline/invalid-pipeline-error.js +0 -14
  24. package/core/steps/pipeline/pipeline.js +0 -28
  25. package/core/steps/step.js +0 -8
  26. package/core/steps/steps-provider.js +0 -3
  27. package/core/steps/steps.js +0 -35
  28. package/dataflow/common/environments/append.js +0 -48
  29. package/dataflow/common/environments/environment.js +0 -165
  30. package/dataflow/common/environments/index.js +0 -23
  31. package/dataflow/common/environments/overwrite.js +0 -82
  32. package/dataflow/common/environments/register.js +0 -49
  33. package/dataflow/common/environments/resolve-by-name.js +0 -35
  34. package/dataflow/common/environments/scopes.js +0 -6
  35. package/dataflow/common/environments/scoping.js +0 -27
  36. package/dataflow/graph/equal.js +0 -127
  37. package/dataflow/v1/extractor.js +0 -60
  38. package/dataflow/v1/graph/diff.js +0 -206
  39. package/dataflow/v1/graph/edge.js +0 -32
  40. package/dataflow/v1/graph/graph.js +0 -298
  41. package/dataflow/v1/graph/index.js +0 -21
  42. package/dataflow/v1/graph/quads.js +0 -27
  43. package/dataflow/v1/graph/vertex.js +0 -3
  44. package/dataflow/v1/index.js +0 -24
  45. package/dataflow/v1/internal/info.js +0 -16
  46. package/dataflow/v1/internal/linker.js +0 -255
  47. package/dataflow/v1/internal/process/access.js +0 -54
  48. package/dataflow/v1/internal/process/expression-list.js +0 -154
  49. package/dataflow/v1/internal/process/functions/argument.js +0 -46
  50. package/dataflow/v1/internal/process/functions/exit-points.js +0 -125
  51. package/dataflow/v1/internal/process/functions/function-call.js +0 -99
  52. package/dataflow/v1/internal/process/functions/function-definition.js +0 -176
  53. package/dataflow/v1/internal/process/functions/parameter.js +0 -47
  54. package/dataflow/v1/internal/process/if-then-else.js +0 -57
  55. package/dataflow/v1/internal/process/loops/for-loop.js +0 -54
  56. package/dataflow/v1/internal/process/loops/repeat-loop.js +0 -21
  57. package/dataflow/v1/internal/process/loops/while-loop.js +0 -31
  58. package/dataflow/v1/internal/process/operators/assignment.js +0 -129
  59. package/dataflow/v1/internal/process/operators/non-assignment-binary-op.js +0 -25
  60. package/dataflow/v1/internal/process/operators/pipe.js +0 -46
  61. package/dataflow/v1/internal/process/operators/unary-op.js +0 -10
  62. package/dataflow/v1/internal/process/symbol.js +0 -21
  63. package/dataflow/v1/internal/process/uninteresting-leaf.js +0 -9
  64. package/dataflow/v1/processor.js +0 -20
  65. package/dataflow/v2/entry.js +0 -11
  66. package/flowr-1.3.7.tgz +0 -0
  67. package/r-bridge/lang-4.x/ast/parser/xml/common/config.js +0 -16
  68. package/r-bridge/lang-4.x/ast/parser/xml/common/input-format.js +0 -42
  69. package/r-bridge/lang-4.x/ast/parser/xml/common/meta.js +0 -118
  70. package/r-bridge/lang-4.x/ast/parser/xml/common/xml-to-json.js +0 -58
  71. package/r-bridge/lang-4.x/ast/parser/xml/v1/data.js +0 -3
  72. package/r-bridge/lang-4.x/ast/parser/xml/v1/hooks.js +0 -136
  73. package/r-bridge/lang-4.x/ast/parser/xml/v1/index.js +0 -22
  74. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/access.js +0 -107
  75. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/control/if-then-else.js +0 -32
  76. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/control/if-then.js +0 -46
  77. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/control/index.js +0 -19
  78. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/expression/expression.js +0 -65
  79. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/expression/index.js +0 -18
  80. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/functions/argument.js +0 -74
  81. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/functions/call.js +0 -149
  82. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/functions/definition.js +0 -60
  83. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/functions/index.js +0 -20
  84. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/functions/parameter.js +0 -64
  85. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/index.js +0 -27
  86. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/loops/break.js +0 -24
  87. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/loops/for.js +0 -72
  88. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/loops/index.js +0 -22
  89. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/loops/next.js +0 -24
  90. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/loops/repeat.js +0 -42
  91. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/loops/while.js +0 -45
  92. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/operators/binary.js +0 -162
  93. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/operators/index.js +0 -20
  94. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/operators/special.js +0 -24
  95. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/operators/unary.js +0 -59
  96. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/other/comment.js +0 -34
  97. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/other/index.js +0 -18
  98. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/other/line-directive.js +0 -55
  99. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/structure/elements.js +0 -159
  100. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/structure/index.js +0 -20
  101. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/structure/root.js +0 -34
  102. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/structure/single-element.js +0 -64
  103. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/values/index.js +0 -20
  104. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/values/number.js +0 -56
  105. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/values/string.js +0 -41
  106. package/r-bridge/lang-4.x/ast/parser/xml/v1/internal/values/symbol.js +0 -56
  107. package/r-bridge/lang-4.x/ast/parser/xml/v1/normalize.js +0 -30
  108. package/r-bridge/lang-4.x/ast/parser/xml/v2/data.js +0 -3
  109. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/access.js +0 -95
  110. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/expression.js +0 -99
  111. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/functions/argument.js +0 -71
  112. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/operators/binary.js +0 -30
  113. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/operators/index.js +0 -19
  114. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/operators/unary.js +0 -35
  115. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/other/comment.js +0 -25
  116. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/other/index.js +0 -18
  117. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/other/line-directive.js +0 -38
  118. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/root.js +0 -26
  119. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/single-element.js +0 -63
  120. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/values/index.js +0 -18
  121. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/values/number.js +0 -46
  122. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/values/string.js +0 -33
  123. package/r-bridge/lang-4.x/ast/parser/xml/v2/internal/values/symbol.js +0 -63
  124. package/r-bridge/lang-4.x/ast/parser/xml/v2/normalize.js +0 -25
  125. package/util/summarizer/benchmark/benchmark-summarizer.js +0 -208
@@ -1,255 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.linkCircularRedefinitionsWithinALoop = exports.linkInputs = exports.getAllLinkedFunctionDefinitions = exports.linkFunctionCalls = exports.linkArgumentsOnCall = exports.linkReadVariablesInSameScopeWithNames = exports.produceNameSharedIdMap = exports.linkIngoingVariablesInSameScope = void 0;
4
- const environments_1 = require("../../common/environments");
5
- const defaultmap_1 = require("../../../util/defaultmap");
6
- const assert_1 = require("../../../util/assert");
7
- const log_1 = require("../../../util/log");
8
- const slicing_1 = require("../../../slicing");
9
- const index_1 = require("../index");
10
- const scopes_1 = require("../../common/environments/scopes");
11
- function linkIngoingVariablesInSameScope(graph, references) {
12
- const nameIdShares = produceNameSharedIdMap(references);
13
- linkReadVariablesInSameScopeWithNames(graph, nameIdShares);
14
- }
15
- exports.linkIngoingVariablesInSameScope = linkIngoingVariablesInSameScope;
16
- function produceNameSharedIdMap(references) {
17
- const nameIdShares = new defaultmap_1.DefaultMap(() => []);
18
- for (const reference of references) {
19
- nameIdShares.get(reference.name).push(reference);
20
- }
21
- return nameIdShares;
22
- }
23
- exports.produceNameSharedIdMap = produceNameSharedIdMap;
24
- function linkReadVariablesInSameScopeWithNames(graph, nameIdShares) {
25
- for (const ids of nameIdShares.values()) {
26
- if (ids.length <= 1) {
27
- continue;
28
- }
29
- const base = ids[0];
30
- for (let i = 1; i < ids.length; i++) {
31
- graph.addEdge(base.nodeId, ids[i].nodeId, index_1.EdgeType.SameReadRead, 'always', true);
32
- }
33
- }
34
- }
35
- exports.linkReadVariablesInSameScopeWithNames = linkReadVariablesInSameScopeWithNames;
36
- function specialReturnFunction(info, graph, id) {
37
- if (info.args.length > 1) {
38
- index_1.dataflowLogger.error(`expected up to one argument for return, but got ${info.args.length}`);
39
- }
40
- for (const arg of info.args) {
41
- if (Array.isArray(arg)) {
42
- if (arg[1] !== '<value>') {
43
- graph.addEdge(id, arg[1], index_1.EdgeType.Returns, 'always');
44
- }
45
- }
46
- else if (arg !== '<value>') {
47
- graph.addEdge(id, arg, index_1.EdgeType.Returns, 'always');
48
- }
49
- }
50
- }
51
- function linkArgumentsOnCall(args, params, graph) {
52
- const nameArgMap = new Map(args.filter(Array.isArray));
53
- const nameParamMap = new Map(params.map(p => [p.name.content, p]));
54
- const specialDotParameter = params.find(p => p.special);
55
- // all parameters matched by name
56
- const matchedParameters = new Set();
57
- // first map names
58
- for (const [name, arg] of nameArgMap) {
59
- if (arg === '<value>') {
60
- index_1.dataflowLogger.trace(`skipping value argument for ${name}`);
61
- continue;
62
- }
63
- const param = nameParamMap.get(name);
64
- if (param !== undefined) {
65
- index_1.dataflowLogger.trace(`mapping named argument "${name}" to parameter "${param.name.content}"`);
66
- graph.addEdge(arg.nodeId, param.name.info.id, index_1.EdgeType.DefinesOnCall, 'always');
67
- matchedParameters.add(name);
68
- }
69
- else if (specialDotParameter !== undefined) {
70
- index_1.dataflowLogger.trace(`mapping named argument "${name}" to dot-dot-dot parameter`);
71
- graph.addEdge(arg.nodeId, specialDotParameter.name.info.id, index_1.EdgeType.DefinesOnCall, 'always');
72
- }
73
- }
74
- const remainingParameter = params.filter(p => !matchedParameters.has(p.name.content));
75
- const remainingArguments = args.filter(a => !Array.isArray(a));
76
- for (let i = 0; i < remainingArguments.length; i++) {
77
- const arg = remainingArguments[i];
78
- if (arg === '<value>' || arg === 'empty') {
79
- index_1.dataflowLogger.trace(`skipping value argument for ${i}`);
80
- continue;
81
- }
82
- if (remainingParameter.length <= i) {
83
- if (specialDotParameter !== undefined) {
84
- index_1.dataflowLogger.trace(`mapping unnamed argument ${i} (id: ${arg.nodeId}) to dot-dot-dot parameter`);
85
- graph.addEdge(arg.nodeId, specialDotParameter.name.info.id, index_1.EdgeType.DefinesOnCall, 'always');
86
- }
87
- else {
88
- index_1.dataflowLogger.error(`skipping argument ${i} as there is no corresponding parameter - R should block that`);
89
- }
90
- continue;
91
- }
92
- const param = remainingParameter[i];
93
- index_1.dataflowLogger.trace(`mapping unnamed argument ${i} (id: ${arg.nodeId}) to parameter "${param.name.content}"`);
94
- graph.addEdge(arg.nodeId, param.name.info.id, index_1.EdgeType.DefinesOnCall, 'always');
95
- }
96
- }
97
- exports.linkArgumentsOnCall = linkArgumentsOnCall;
98
- function linkFunctionCallArguments(targetId, idMap, functionCallName, functionRootId, callArgs, finalGraph) {
99
- // we get them by just choosing the rhs of the definition
100
- const linkedFunction = idMap.get(targetId);
101
- if (linkedFunction === undefined) {
102
- index_1.dataflowLogger.trace(`no function definition found for ${functionCallName} (${functionRootId})`);
103
- return;
104
- }
105
- if (linkedFunction.type !== "RFunctionDefinition" /* RType.FunctionDefinition */) {
106
- index_1.dataflowLogger.trace(`function call definition base ${functionCallName} does not lead to a function definition (${functionRootId}) but got ${linkedFunction.type}`);
107
- return;
108
- }
109
- index_1.dataflowLogger.trace(`linking arguments for ${functionCallName} (${functionRootId}) to ${JSON.stringify(linkedFunction.location)}`);
110
- linkArgumentsOnCall(callArgs, linkedFunction.parameters, finalGraph);
111
- }
112
- function linkFunctionCall(graph, id, info, idMap, thisGraph, calledFunctionDefinitions) {
113
- const edges = graph.get(id, true);
114
- (0, assert_1.guard)(edges !== undefined, () => `id ${id} must be present in graph`);
115
- const functionDefinitionReadIds = [...edges[1]].filter(([_, e]) => e.types.has(index_1.EdgeType.Reads) || e.types.has(index_1.EdgeType.Calls) || e.types.has(index_1.EdgeType.Relates)).map(([target, _]) => target);
116
- const functionDefs = getAllLinkedFunctionDefinitions(new Set(functionDefinitionReadIds), graph);
117
- for (const def of functionDefs.values()) {
118
- (0, assert_1.guard)(def.tag === 'function-definition', () => `expected function definition, but got ${def.tag}`);
119
- if (info.environment !== undefined) {
120
- // for each open ingoing reference, try to resolve it here, and if so add a read edge from the call to signal that it reads it
121
- for (const ingoing of def.subflow.in) {
122
- const defs = (0, environments_1.resolveByName)(ingoing.name, scopes_1.LocalScope, info.environment);
123
- if (defs === undefined) {
124
- continue;
125
- }
126
- for (const def of defs) {
127
- graph.addEdge(id, def, index_1.EdgeType.Reads, 'always');
128
- }
129
- }
130
- }
131
- const exitPoints = def.exitPoints;
132
- for (const exitPoint of exitPoints) {
133
- graph.addEdge(id, exitPoint, index_1.EdgeType.Returns, 'always');
134
- }
135
- index_1.dataflowLogger.trace(`recording expression-list-level call from ${info.name} to ${def.name}`);
136
- graph.addEdge(id, def.id, index_1.EdgeType.Calls, 'always');
137
- linkFunctionCallArguments(def.id, idMap, def.name, id, info.args, graph);
138
- }
139
- if (thisGraph.isRoot(id)) {
140
- calledFunctionDefinitions.push({ functionCall: id, called: [...functionDefs.values()] });
141
- }
142
- }
143
- /**
144
- * Returns the called functions within the current graph, which can be used to merge the environments with the call.
145
- * Furthermore, it links the corresponding arguments.
146
- */
147
- function linkFunctionCalls(graph, idMap, functionCalls, thisGraph) {
148
- const calledFunctionDefinitions = [];
149
- for (const [id, info] of functionCalls) {
150
- (0, assert_1.guard)(info.tag === 'function-call', () => `encountered non-function call in function call linkage ${JSON.stringify(info)}`);
151
- if (info.name === 'return') {
152
- specialReturnFunction(info, graph, id);
153
- graph.addEdge(id, environments_1.BuiltIn, index_1.EdgeType.Calls, 'always');
154
- continue;
155
- }
156
- linkFunctionCall(graph, id, info, idMap, thisGraph, calledFunctionDefinitions);
157
- }
158
- return calledFunctionDefinitions;
159
- }
160
- exports.linkFunctionCalls = linkFunctionCalls;
161
- function getAllLinkedFunctionDefinitions(functionDefinitionReadIds, dataflowGraph) {
162
- const potential = [...functionDefinitionReadIds];
163
- const visited = new Set();
164
- const result = new Map();
165
- while (potential.length > 0) {
166
- const currentId = potential.pop();
167
- if (currentId === environments_1.BuiltIn) {
168
- // do not traverse builtins
169
- slicing_1.slicerLogger.trace('skipping builtin function definition during collection');
170
- continue;
171
- }
172
- const currentInfo = dataflowGraph.get(currentId, true);
173
- if (currentInfo === undefined) {
174
- slicing_1.slicerLogger.trace('skipping unknown link');
175
- continue;
176
- }
177
- visited.add(currentId);
178
- const outgoingEdges = [...currentInfo[1]];
179
- const returnEdges = outgoingEdges.filter(([_, e]) => e.types.has(index_1.EdgeType.Returns));
180
- if (returnEdges.length > 0) {
181
- // only traverse return edges and do not follow calls etc. as this indicates that we have a function call which returns a result, and not the function call itself
182
- potential.push(...returnEdges.map(([target]) => target).filter(id => !visited.has(id)));
183
- continue;
184
- }
185
- const followEdges = outgoingEdges.filter(([_, e]) => e.types.has(index_1.EdgeType.Reads) || e.types.has(index_1.EdgeType.DefinedBy) || e.types.has(index_1.EdgeType.DefinedByOnCall) || e.types.has(index_1.EdgeType.Relates));
186
- if (currentInfo[0].subflow !== undefined) {
187
- result.set(currentId, currentInfo[0]);
188
- }
189
- // trace all joined reads
190
- potential.push(...followEdges.map(([target]) => target).filter(id => !visited.has(id)));
191
- }
192
- return result;
193
- }
194
- exports.getAllLinkedFunctionDefinitions = getAllLinkedFunctionDefinitions;
195
- /**
196
- * This method links a set of read variables to definitions in an environment.
197
- *
198
- * @param referencesToLinkAgainstEnvironment - The set of references to link against the environment
199
- * @param scope - The scope in which the linking shall happen (probably the active scope of {@link DataflowProcessorInformation})
200
- * @param environmentInformation - The environment information to link against
201
- * @param givenInputs - The existing list of inputs that might be extended
202
- * @param graph - The graph to enter the found links
203
- * @param maybeForRemaining - Each input that can not be linked, will be added to `givenInputs`. If this flag is `true`, it will be marked as `maybe`.
204
- *
205
- * @returns the given inputs, possibly extended with the remaining inputs (those of `referencesToLinkAgainstEnvironment` that could not be linked against the environment)
206
- */
207
- function linkInputs(referencesToLinkAgainstEnvironment, scope, environmentInformation, givenInputs, graph, maybeForRemaining) {
208
- for (const bodyInput of referencesToLinkAgainstEnvironment) {
209
- const probableTarget = (0, environments_1.resolveByName)(bodyInput.name, scope, environmentInformation);
210
- if (probableTarget === undefined) {
211
- log_1.log.trace(`found no target for ${bodyInput.name} in ${scope}`);
212
- if (maybeForRemaining) {
213
- bodyInput.used = 'maybe';
214
- }
215
- givenInputs.push(bodyInput);
216
- }
217
- else {
218
- for (const target of probableTarget) {
219
- // we can stick with maybe even if readId.attribute is always
220
- graph.addEdge(bodyInput, target, index_1.EdgeType.Reads, undefined, true);
221
- }
222
- }
223
- }
224
- // data.graph.get(node.id).definedAtPosition = false
225
- return givenInputs;
226
- }
227
- exports.linkInputs = linkInputs;
228
- /** all loops variables which are open read (not already bound by a redefinition within the loop) get a maybe read marker to their last definition within the loop
229
- * e.g. with:
230
- * ```R
231
- * for(i in 1:10) {
232
- * x_1 <- x_2 + 1
233
- * }
234
- * ```
235
- * `x_2` must get a read marker to `x_1` as `x_1` is the active redefinition in the second loop iteration.
236
- */
237
- function linkCircularRedefinitionsWithinALoop(graph, openIns, outgoing) {
238
- // first we preprocess out so that only the last definition of a given identifier survives
239
- // this implicitly assumes that the outgoing references are ordered
240
- const lastOutgoing = new Map();
241
- for (const out of outgoing) {
242
- lastOutgoing.set(out.name, out);
243
- }
244
- for (const [name, targets] of openIns.entries()) {
245
- for (const out of lastOutgoing.values()) {
246
- if (out.name === name) {
247
- for (const target of targets) {
248
- graph.addEdge(target.nodeId, out.nodeId, index_1.EdgeType.Reads, 'maybe');
249
- }
250
- }
251
- }
252
- }
253
- }
254
- exports.linkCircularRedefinitionsWithinALoop = linkCircularRedefinitionsWithinALoop;
255
- //# sourceMappingURL=linker.js.map
@@ -1,54 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.processAccess = void 0;
4
- const processor_1 = require("../../processor");
5
- const environments_1 = require("../../../common/environments");
6
- const graph_1 = require("../../graph");
7
- function processAccess(node, data) {
8
- const processedAccessed = (0, processor_1.processDataflowFor)(node.accessed, data);
9
- const nextGraph = processedAccessed.graph;
10
- const outgoing = processedAccessed.out;
11
- const ingoing = processedAccessed.in;
12
- let environments = processedAccessed.environments;
13
- const accessedNodes = processedAccessed.unknownReferences;
14
- if (node.operator === '[' || node.operator === '[[') {
15
- for (const access of node.access) {
16
- if (access === null || access.value === undefined) {
17
- continue;
18
- }
19
- data = { ...data, environments };
20
- const processedAccess = (0, processor_1.processDataflowFor)(access, data);
21
- nextGraph.mergeWith(processedAccess.graph);
22
- // outgoing.push()
23
- // we link to *out* instead of *in*, as access uses arguments for parsing and the arguments are defined
24
- for (const newIn of [...processedAccess.out, ...processedAccess.unknownReferences]) {
25
- for (const accessedNode of accessedNodes) {
26
- nextGraph.addEdge(accessedNode, newIn, graph_1.EdgeType.Reads, 'always');
27
- }
28
- }
29
- ingoing.push(...processedAccess.in, ...processedAccess.unknownReferences);
30
- environments = processedAccess.environments;
31
- }
32
- }
33
- return {
34
- /*
35
- * keep active nodes in case of assignments etc.
36
- * We make them maybe as a kind of hack.
37
- * This way when using
38
- * ```ts
39
- * a[[1]] <- 3
40
- * a[[2]] <- 4
41
- * a
42
- * ```
43
- * the read for a will use both accesses as potential definitions and not just the last one!
44
- */
45
- unknownReferences: (0, environments_1.makeAllMaybe)(processedAccessed.unknownReferences, nextGraph, environments),
46
- in: ingoing,
47
- out: outgoing,
48
- environments: environments,
49
- scope: data.activeScope,
50
- graph: nextGraph
51
- };
52
- }
53
- exports.processAccess = processAccess;
54
- //# sourceMappingURL=access.js.map
@@ -1,154 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.processExpressionList = void 0;
4
- /**
5
- * Processes a list of expressions joining their dataflow graphs accordingly.
6
- * @module
7
- */
8
- const info_1 = require("../info");
9
- const r_bridge_1 = require("../../../../r-bridge");
10
- const processor_1 = require("../../processor");
11
- const environments_1 = require("../../../common/environments");
12
- const linker_1 = require("../linker");
13
- const defaultmap_1 = require("../../../../util/defaultmap");
14
- const graph_1 = require("../../graph");
15
- const index_1 = require("../../index");
16
- const assert_1 = require("../../../../util/assert");
17
- const dotDotDotAccess = /\.\.\d+/;
18
- function linkReadNameToWriteIfPossible(read, data, environments, listEnvironments, remainingRead, nextGraph) {
19
- const readName = dotDotDotAccess.test(read.name) ? '...' : read.name;
20
- const probableTarget = (0, environments_1.resolveByName)(readName, data.activeScope, environments);
21
- // record if at least one has not been defined
22
- if (probableTarget === undefined || probableTarget.some(t => !listEnvironments.has(t.nodeId))) {
23
- if (remainingRead.has(readName)) {
24
- remainingRead.get(readName)?.push(read);
25
- }
26
- else {
27
- remainingRead.set(readName, [read]);
28
- }
29
- }
30
- // keep it, for we have no target, as read-ids are unique within same fold, this should work for same links
31
- // we keep them if they are defined outside the current parent and maybe throw them away later
32
- if (probableTarget === undefined) {
33
- return;
34
- }
35
- for (const target of probableTarget) {
36
- // we can stick with maybe even if readId.attribute is always
37
- nextGraph.addEdge(read, target, index_1.EdgeType.Reads, undefined, true);
38
- }
39
- }
40
- function processNextExpression(currentElement, data, environments, listEnvironments, remainingRead, nextGraph) {
41
- // all inputs that have not been written until know, are read!
42
- for (const read of [...currentElement.in, ...currentElement.unknownReferences]) {
43
- linkReadNameToWriteIfPossible(read, data, environments, listEnvironments, remainingRead, nextGraph);
44
- }
45
- // add same variable reads for deferred if they are read previously but not dependent
46
- for (const writeTarget of currentElement.out) {
47
- const writeName = writeTarget.name;
48
- const resolved = (0, environments_1.resolveByName)(writeName, data.activeScope, environments);
49
- if (resolved !== undefined) {
50
- // write-write
51
- for (const target of resolved) {
52
- nextGraph.addEdge(target, writeTarget, index_1.EdgeType.SameDefDef, undefined, true);
53
- }
54
- }
55
- }
56
- }
57
- function updateSideEffectsForCalledFunctions(calledEnvs, environments, nextGraph) {
58
- for (const { functionCall, called } of calledEnvs) {
59
- for (const calledFn of called) {
60
- (0, assert_1.guard)(calledFn.tag === 'function-definition', 'called function must call a function definition');
61
- // only merge the environments they have in common
62
- let environment = calledFn.environment;
63
- while (environment.level > environments.level) {
64
- environment = (0, environments_1.popLocalEnvironment)(environment);
65
- }
66
- // update alle definitions to be defined at this function call
67
- let current = environment.current;
68
- while (current !== undefined) {
69
- for (const definitions of current.memory.values()) {
70
- for (const def of definitions) {
71
- if (def.kind !== 'built-in-function') {
72
- nextGraph.addEdge(def.nodeId, functionCall, index_1.EdgeType.SideEffectOnCall, def.used);
73
- }
74
- }
75
- }
76
- current = current.parent;
77
- }
78
- // we update all definitions to be linked with the corresponding function call
79
- environments = (0, environments_1.overwriteEnvironments)(environments, environment);
80
- }
81
- }
82
- return environments;
83
- }
84
- function processExpressionList(exprList, data) {
85
- const expressions = exprList.children;
86
- index_1.dataflowLogger.trace(`processing expression list with ${expressions.length} expressions`);
87
- if (expressions.length === 0) {
88
- return (0, info_1.initializeCleanDataflowInformation)(data);
89
- }
90
- let environments = data.environments;
91
- // used to detect if a "write" happens within the same expression list
92
- const listEnvironments = new Set();
93
- const remainingRead = new Map();
94
- const nextGraph = new graph_1.DataflowGraph();
95
- const out = [];
96
- let expressionCounter = 0;
97
- let foundNextOrBreak = false;
98
- for (const expression of expressions) {
99
- index_1.dataflowLogger.trace(`processing expression ${++expressionCounter} of ${expressions.length}`);
100
- // use the current environments for processing
101
- data = { ...data, environments };
102
- const processed = (0, processor_1.processDataflowFor)(expression, data);
103
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- seems to be a bug in eslint
104
- if (!foundNextOrBreak) {
105
- (0, r_bridge_1.visitAst)(expression, n => {
106
- // we should track returns more consistently
107
- if (n.type === "RNext" /* RType.Next */ || n.type === "RBreak" /* RType.Break */) {
108
- foundNextOrBreak = true;
109
- }
110
- return n.type === "RForLoop" /* RType.ForLoop */ || n.type === "RWhileLoop" /* RType.WhileLoop */ || n.type === "RRepeatLoop" /* RType.RepeatLoop */ || n.type === "RFunctionDefinition" /* RType.FunctionDefinition */;
111
- });
112
- }
113
- // if the expression contained next or break anywhere before the next loop, the overwrite should be an append because we do not know if the rest is executed
114
- // update the environments for the next iteration with the previous writes
115
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- seems to be a bug in eslint
116
- if (foundNextOrBreak) {
117
- processed.out = (0, environments_1.makeAllMaybe)(processed.out, nextGraph, processed.environments);
118
- processed.in = (0, environments_1.makeAllMaybe)(processed.in, nextGraph, processed.environments);
119
- processed.unknownReferences = (0, environments_1.makeAllMaybe)(processed.unknownReferences, nextGraph, processed.environments);
120
- }
121
- nextGraph.mergeWith(processed.graph);
122
- out.push(...processed.out);
123
- index_1.dataflowLogger.trace(`expression ${expressionCounter} of ${expressions.length} has ${processed.unknownReferences.length} unknown nodes`);
124
- processNextExpression(processed, data, environments, listEnvironments, remainingRead, nextGraph);
125
- const functionCallIds = [...processed.graph.vertices(true)]
126
- .filter(([_, info]) => info.tag === 'function-call');
127
- const calledEnvs = (0, linker_1.linkFunctionCalls)(nextGraph, data.completeAst.idMap, functionCallIds, processed.graph);
128
- if (foundNextOrBreak) {
129
- environments = (0, environments_1.overwriteEnvironments)(environments, processed.environments);
130
- }
131
- else {
132
- environments = processed.environments;
133
- }
134
- // if the called function has global redefinitions, we have to keep them within our environment
135
- environments = updateSideEffectsForCalledFunctions(calledEnvs, environments, nextGraph);
136
- for (const { nodeId } of processed.out) {
137
- listEnvironments.add(nodeId);
138
- }
139
- }
140
- // now, we have to link same reads
141
- (0, linker_1.linkReadVariablesInSameScopeWithNames)(nextGraph, new defaultmap_1.DefaultMap(() => [], remainingRead));
142
- index_1.dataflowLogger.trace(`expression list exits with ${remainingRead.size} remaining read names`);
143
- return {
144
- /* no active nodes remain, they are consumed within the remaining read collection */
145
- unknownReferences: [],
146
- in: [...remainingRead.values()].flat(),
147
- out,
148
- environments,
149
- scope: data.activeScope,
150
- graph: nextGraph
151
- };
152
- }
153
- exports.processExpressionList = processExpressionList;
154
- //# sourceMappingURL=expression-list.js.map
@@ -1,46 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.processFunctionArgument = exports.linkReadsForArgument = exports.UnnamedArgumentPrefix = void 0;
4
- const processor_1 = require("../../../processor");
5
- const r_bridge_1 = require("../../../../../r-bridge");
6
- const graph_1 = require("../../../graph");
7
- const scopes_1 = require("../../../../common/environments/scopes");
8
- exports.UnnamedArgumentPrefix = 'unnamed-argument-';
9
- function linkReadsForArgument(root, ingoingRefs, graph) {
10
- const allIdsBeforeArguments = new Set((0, r_bridge_1.collectAllIds)(root, n => n.type === "RArgument" /* RType.Argument */ && n.info.id !== root.info.id));
11
- const ingoingBeforeArgs = ingoingRefs.filter(r => allIdsBeforeArguments.has(r.nodeId));
12
- for (const ref of ingoingBeforeArgs) {
13
- // link against the root reference currently I do not know how to deal with nested function calls otherwise
14
- graph.addEdge(root.info.id, ref, graph_1.EdgeType.Reads, 'always');
15
- }
16
- }
17
- exports.linkReadsForArgument = linkReadsForArgument;
18
- function processFunctionArgument(argument, data) {
19
- const name = argument.name === undefined ? undefined : (0, processor_1.processDataflowFor)(argument.name, data);
20
- const value = argument.value === undefined ? undefined : (0, processor_1.processDataflowFor)(argument.value, data);
21
- // we do not keep the graph of the name, as this is no node that should ever exist
22
- const graph = value?.graph ?? new graph_1.DataflowGraph();
23
- const argContent = argument.name?.content;
24
- const argumentName = argContent ?? `${exports.UnnamedArgumentPrefix}${argument.info.id}`;
25
- graph.addVertex({ tag: 'use', id: argument.info.id, name: argumentName, environment: data.environments, when: 'always' });
26
- const ingoingRefs = [...value?.unknownReferences ?? [], ...value?.in ?? [], ...(name === undefined ? [] : [...name.in])];
27
- if (argument.value?.type === "RFunctionDefinition" /* RType.FunctionDefinition */) {
28
- graph.addEdge(argument.info.id, argument.value.info.id, graph_1.EdgeType.Reads, 'always');
29
- }
30
- else {
31
- // we only need to link against those which are not already bound to another function call argument
32
- linkReadsForArgument(argument, [...ingoingRefs, ...value?.out ?? [] /* value may perform definitions */], graph);
33
- }
34
- return {
35
- unknownReferences: [],
36
- // active nodes of the name will be lost as they are only used to reference the corresponding parameter
37
- in: ingoingRefs,
38
- // , ...value.out, ...(name?.out ?? [])
39
- out: [{ name: argumentName, scope: scopes_1.LocalScope, nodeId: argument.info.id, used: 'always' }],
40
- graph: graph,
41
- environments: value?.environments ?? data.environments,
42
- scope: data.activeScope
43
- };
44
- }
45
- exports.processFunctionArgument = processFunctionArgument;
46
- //# sourceMappingURL=argument.js.map
@@ -1,125 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.retrieveExitPointsOfFunctionDefinition = void 0;
4
- const assert_1 = require("../../../../../util/assert");
5
- // TODO: wir wollen exit points für alle expression lists nicht nur für function definitions -> wir schlagen alle mit einer klappe :3
6
- function retrieveExitPointsOfFunctionDefinition(functionDefinition) {
7
- const exitPoints = visitExitPoints(functionDefinition.body);
8
- return exitPoints.knownIds.concat(exitPoints.potentialIds);
9
- }
10
- exports.retrieveExitPointsOfFunctionDefinition = retrieveExitPointsOfFunctionDefinition;
11
- // TODO: fold
12
- function visitExitPoints(node) {
13
- const type = node.type;
14
- switch (type) {
15
- case "RExpressionList" /* RType.ExpressionList */:
16
- return visitExpressionList(node);
17
- case "RFunctionCall" /* RType.FunctionCall */:
18
- // TODO: what if return is overwritten
19
- if (node.flavor === 'named' && node.functionName.content === 'return') {
20
- return {
21
- knownIds: [node.info.id],
22
- potentialIds: []
23
- };
24
- }
25
- break;
26
- case "RFunctionDefinition" /* RType.FunctionDefinition */:
27
- // do not further investigate
28
- break;
29
- case "RForLoop" /* RType.ForLoop */:
30
- case "RWhileLoop" /* RType.WhileLoop */:
31
- case "RRepeatLoop" /* RType.RepeatLoop */:
32
- // loops return invisible null, as we do not trace values, but they may contain return statements
33
- return visitLoops(node);
34
- case "RIfThenElse" /* RType.IfThenElse */:
35
- return visitIf(node);
36
- case "RPipe" /* RType.Pipe */:
37
- case "RBinaryOp" /* RType.BinaryOp */:
38
- // assignments return invisible rhs
39
- return knownIdsOfChildren(node.info.id, node.lhs, node.rhs);
40
- case "RUnaryOp" /* RType.UnaryOp */:
41
- return knownIdsOfChildren(node.info.id, node.operand);
42
- case "RParameter" /* RType.Parameter */:
43
- return node.defaultValue ? knownIdsOfChildren(node.info.id, node.defaultValue) : { knownIds: [], potentialIds: [] };
44
- case "RArgument" /* RType.Argument */:
45
- return node.value ? knownIdsOfChildren(node.info.id, node.value) : { knownIds: [], potentialIds: [] };
46
- case "RSymbol" /* RType.Symbol */:
47
- case "RLogical" /* RType.Logical */:
48
- case "RNumber" /* RType.Number */:
49
- case "RString" /* RType.String */:
50
- case "RAccess" /* RType.Access */:
51
- // just use this node
52
- break;
53
- // contain noting to return/return `invisible(null)`
54
- case "RComment" /* RType.Comment */:
55
- case "RLineDirective" /* RType.LineDirective */:
56
- case "RBreak" /* RType.Break */:
57
- case "RNext" /* RType.Next */:
58
- // TODO: wrong for loops
59
- return { knownIds: [], potentialIds: [] };
60
- default:
61
- (0, assert_1.assertUnreachable)(type);
62
- }
63
- return {
64
- knownIds: [],
65
- potentialIds: [node.info.id]
66
- };
67
- }
68
- // we use keepSelfAsPotential in order to track nodes like 2 + 3, which keep themselves as potential exit points if there are no knownIds
69
- function knownIdsOfChildren(keepSelfAsPotential, ...children) {
70
- const knownIds = children.flatMap(child => visitExitPoints(child).knownIds);
71
- return {
72
- knownIds,
73
- potentialIds: knownIds.length === 0 ? [keepSelfAsPotential] : []
74
- };
75
- }
76
- function visitLoops(loop) {
77
- const result = visitExitPoints(loop.body);
78
- // conditions may contain return statements which we have to keep
79
- let otherKnownIds = [];
80
- if (loop.type === "RForLoop" /* RType.ForLoop */) {
81
- otherKnownIds = visitExitPoints(loop.variable).knownIds;
82
- otherKnownIds.push(...visitExitPoints(loop.vector).knownIds);
83
- }
84
- else if (loop.type === "RWhileLoop" /* RType.WhileLoop */) {
85
- otherKnownIds = visitExitPoints(loop.condition).knownIds;
86
- }
87
- return {
88
- knownIds: [...result.knownIds, ...otherKnownIds],
89
- potentialIds: []
90
- };
91
- }
92
- function visitExpressionList(node) {
93
- const known = [];
94
- let lastPotentialIds = [];
95
- // we only keep the potential ids of the last expression, which is no comment
96
- for (const child of node.children) {
97
- const { knownIds, potentialIds } = visitExitPoints(child);
98
- known.push(...knownIds);
99
- if (child.type !== "RComment" /* RType.Comment */) {
100
- lastPotentialIds = potentialIds;
101
- }
102
- }
103
- return {
104
- knownIds: known,
105
- potentialIds: lastPotentialIds
106
- };
107
- }
108
- function visitIf(node) {
109
- // conditions can contain return statements
110
- const known = visitExitPoints(node.condition).knownIds;
111
- const potential = [];
112
- const thenCase = visitExitPoints(node.then);
113
- known.push(...thenCase.knownIds);
114
- potential.push(...thenCase.potentialIds);
115
- if (node.otherwise !== undefined) {
116
- const otherwiseCase = visitExitPoints(node.otherwise);
117
- known.push(...otherwiseCase.knownIds);
118
- potential.push(...otherwiseCase.potentialIds);
119
- }
120
- return {
121
- knownIds: known,
122
- potentialIds: potential
123
- };
124
- }
125
- //# sourceMappingURL=exit-points.js.map