@eagleoutice/flowr 2.9.9 → 2.9.11
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 +57 -54
- package/abstract-interpretation/absint-visitor.d.ts +16 -14
- package/abstract-interpretation/absint-visitor.js +93 -47
- package/abstract-interpretation/data-frame/mappers/arguments.d.ts +1 -1
- package/abstract-interpretation/data-frame/mappers/arguments.js +2 -2
- package/abstract-interpretation/data-frame/shape-inference.d.ts +2 -5
- package/abstract-interpretation/data-frame/shape-inference.js +4 -5
- package/abstract-interpretation/domains/abstract-domain.d.ts +4 -4
- package/abstract-interpretation/domains/abstract-domain.js +8 -8
- package/abstract-interpretation/domains/mapped-abstract-domain.d.ts +12 -5
- package/abstract-interpretation/domains/mapped-abstract-domain.js +47 -23
- package/abstract-interpretation/domains/set-range-domain.js +1 -1
- package/abstract-interpretation/domains/state-abstract-domain.d.ts +30 -1
- package/abstract-interpretation/domains/state-abstract-domain.js +130 -4
- package/abstract-interpretation/normalized-ast-fold.d.ts +2 -2
- package/abstract-interpretation/normalized-ast-fold.js +4 -3
- package/benchmark/slicer.js +5 -5
- package/benchmark/summarizer/first-phase/process.js +4 -4
- package/cli/repl/commands/repl-normalize.js +2 -2
- package/cli/repl/core.js +2 -2
- package/config.js +1 -1
- package/control-flow/cfg-simplification.d.ts +1 -0
- package/control-flow/cfg-simplification.js +1 -0
- package/control-flow/control-flow-graph.d.ts +1 -1
- package/control-flow/control-flow-graph.js +1 -2
- package/control-flow/extract-cfg.js +34 -15
- package/control-flow/semantic-cfg-guided-visitor.js +1 -0
- package/dataflow/cluster.js +1 -1
- package/dataflow/environments/built-in.d.ts +6 -15
- package/dataflow/environments/built-in.js +25 -33
- package/dataflow/environments/default-builtin-config.d.ts +4 -8
- package/dataflow/environments/default-builtin-config.js +8 -5
- package/dataflow/environments/reference-to-maybe.d.ts +8 -0
- package/dataflow/environments/reference-to-maybe.js +46 -3
- package/dataflow/eval/resolve/alias-tracking.d.ts +2 -2
- package/dataflow/eval/resolve/alias-tracking.js +6 -6
- package/dataflow/eval/resolve/resolve.js +12 -10
- package/dataflow/fn/exceptions-of-function.d.ts +1 -1
- package/dataflow/fn/exceptions-of-function.js +2 -1
- package/dataflow/graph/call-graph.d.ts +1 -1
- package/dataflow/graph/call-graph.js +4 -3
- package/dataflow/graph/dataflowgraph-builder.d.ts +1 -1
- package/dataflow/graph/dataflowgraph-builder.js +21 -21
- package/dataflow/graph/graph.d.ts +5 -5
- package/dataflow/graph/graph.js +36 -32
- package/dataflow/graph/unknown-side-effect.js +3 -1
- package/dataflow/info.d.ts +4 -0
- package/dataflow/info.js +2 -2
- package/dataflow/internal/linker.d.ts +4 -4
- package/dataflow/internal/linker.js +59 -33
- package/dataflow/internal/process/functions/call/argument/make-argument.d.ts +2 -1
- package/dataflow/internal/process/functions/call/argument/make-argument.js +3 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +2 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +3 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +6 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +15 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +3 -2
- 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-local.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +2 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.js +7 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +22 -11
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +22 -19
- package/dataflow/internal/process/functions/call/common.d.ts +1 -1
- package/dataflow/internal/process/functions/call/common.js +43 -35
- package/dataflow/internal/process/functions/call/known-call-handling.js +0 -2
- package/dataflow/internal/process/functions/process-argument.d.ts +1 -1
- package/dataflow/internal/process/functions/process-argument.js +3 -3
- package/dataflow/internal/process/functions/process-parameter.js +2 -2
- package/dataflow/origin/dfg-get-origin.d.ts +1 -1
- package/dataflow/origin/dfg-get-origin.js +2 -2
- package/documentation/doc-util/doc-types.js +1 -1
- package/documentation/wiki-absint.js +7 -8
- package/documentation/wiki-cfg.js +3 -3
- package/documentation/wiki-mk/doc-context.d.ts +8 -0
- package/documentation/wiki-mk/doc-context.js +4 -0
- package/documentation/wiki-normalized-ast.d.ts +1 -1
- package/documentation/wiki-normalized-ast.js +9 -6
- package/linter/linter-format.d.ts +10 -0
- package/linter/linter-format.js +15 -0
- package/linter/rules/absolute-path.js +3 -3
- package/linter/rules/dead-code.js +1 -1
- package/linter/rules/file-path-validity.js +1 -1
- package/linter/rules/seeded-randomness.js +1 -1
- package/linter/rules/unused-definition.js +1 -1
- package/package.json +7 -7
- package/project/plugins/file-plugins/files/flowr-description-file.d.ts +9 -0
- package/project/plugins/file-plugins/files/flowr-description-file.js +12 -0
- package/queries/catalog/call-context-query/call-context-query-executor.js +1 -1
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +1 -1
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +4 -5
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +2 -1
- package/queries/catalog/dependencies-query/dependencies-query-format.js +6 -5
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +1 -1
- package/queries/catalog/df-shape-query/df-shape-query-format.js +3 -3
- package/queries/catalog/does-call-query/does-call-query-executor.js +3 -3
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +1 -1
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.js +2 -2
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +1 -1
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.js +1 -1
- package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +1 -1
- package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.js +1 -1
- package/queries/query-print.d.ts +1 -1
- package/queries/query-print.js +4 -3
- package/r-bridge/lang-4.x/ast/model/model.d.ts +151 -4
- package/r-bridge/lang-4.x/ast/model/model.js +249 -0
- package/r-bridge/lang-4.x/ast/model/nodes/info/r-delimiter.d.ts +11 -1
- package/r-bridge/lang-4.x/ast/model/nodes/info/r-delimiter.js +13 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +19 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.js +26 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +36 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +48 -13
- package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.js +21 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +11 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.js +14 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +8 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +11 -5
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +23 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.js +32 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +11 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.js +14 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +19 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.js +26 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +11 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +14 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +11 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.js +14 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +12 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.js +14 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +20 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.js +26 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +12 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.js +14 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +8 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +11 -5
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +17 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.js +22 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +22 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-project.d.ts +45 -8
- package/r-bridge/lang-4.x/ast/model/nodes/r-project.js +57 -16
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +12 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.js +14 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +15 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +21 -6
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +21 -6
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.js +22 -5
- package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.js +21 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +11 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.js +14 -0
- package/r-bridge/lang-4.x/ast/model/processing/decorate.js +23 -17
- package/r-bridge/lang-4.x/ast/model/processing/node-id.d.ts +39 -2
- package/r-bridge/lang-4.x/ast/model/processing/node-id.js +52 -9
- package/r-bridge/lang-4.x/ast/model/processing/role.d.ts +18 -17
- package/r-bridge/lang-4.x/ast/model/processing/visitor.d.ts +8 -7
- package/r-bridge/lang-4.x/ast/model/processing/visitor.js +6 -13
- package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/parser/json/parser.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/expression/normalize-expression.js +4 -2
- package/r-bridge/lang-4.x/ast/parser/main/internal/values/normalize-number.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/values/normalize-string.js +2 -2
- package/r-bridge/lang-4.x/convert-values.d.ts +14 -5
- package/r-bridge/lang-4.x/convert-values.js +76 -72
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +33 -15
- package/r-bridge/roxygen2/roxygen-parse.js +1 -1
- package/r-bridge/shell-executor.js +1 -1
- package/reconstruct/auto-select/magic-comments.js +4 -4
- package/reconstruct/reconstruct.js +2 -1
- package/search/search-executor/search-generators.js +2 -2
- package/slicing/criterion/filters/all-variables.js +1 -1
- package/slicing/criterion/parse.d.ts +1 -1
- package/slicing/criterion/parse.js +5 -3
- package/slicing/static/slice-call.d.ts +1 -1
- package/slicing/static/slice-call.js +2 -2
- package/statistics/features/supported/assignments/assignments.js +2 -2
- package/statistics/features/supported/control-flow/control-flow.js +2 -2
- package/statistics/features/supported/data-access/data-access.js +6 -5
- package/statistics/features/supported/defined-functions/defined-functions.js +9 -8
- package/statistics/features/supported/expression-list/statistics-expression-list.js +2 -2
- package/statistics/features/supported/loops/loops.js +6 -5
- package/statistics/features/supported/used-functions/used-functions.js +2 -2
- package/statistics/features/supported/variables/variables.js +8 -8
- package/util/mermaid/ast.js +3 -3
- package/util/mermaid/cfg.js +3 -4
- package/util/mermaid/dfg.d.ts +1 -1
- package/util/mermaid/dfg.js +13 -12
- package/util/simple-df/dfg-ascii.js +1 -1
- package/util/version.js +1 -1
- package/r-bridge/lang-4.x/ast/model/collect.d.ts +0 -10
- package/r-bridge/lang-4.x/ast/model/collect.js +0 -25
package/dataflow/graph/graph.js
CHANGED
|
@@ -61,7 +61,7 @@ exports.FunctionArgument = {
|
|
|
61
61
|
},
|
|
62
62
|
/**
|
|
63
63
|
* Checks whether the given argument is not an empty argument.
|
|
64
|
-
* @see {@link isEmpty}
|
|
64
|
+
* @see {@link FunctionArgument.isEmpty}
|
|
65
65
|
*/
|
|
66
66
|
isNotEmpty(arg) {
|
|
67
67
|
return arg !== r_function_call_1.EmptyArgument;
|
|
@@ -267,25 +267,24 @@ class DataflowGraph {
|
|
|
267
267
|
* @see DataflowGraphVertexArgument
|
|
268
268
|
*/
|
|
269
269
|
addVertex(vertex, fallbackEnv, asRoot = true, overwrite = false) {
|
|
270
|
-
const
|
|
270
|
+
const vid = vertex.id;
|
|
271
|
+
const oldVertex = this.vertexInformation.get(vid);
|
|
271
272
|
if (oldVertex !== undefined && !overwrite) {
|
|
272
273
|
return this;
|
|
273
274
|
}
|
|
274
|
-
const
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
environment: vertex.environment ? (0, clone_1.cloneEnvironmentInformation)(vertex.environment) : fallback
|
|
279
|
-
});
|
|
275
|
+
const vtag = vertex.tag;
|
|
276
|
+
// keep a clone of the original environment
|
|
277
|
+
vertex.environment = vertex.environment ? (0, clone_1.cloneEnvironmentInformation)(vertex.environment) : (vtag === vertex_1.VertexType.FunctionDefinition || (vtag === vertex_1.VertexType.FunctionCall && !vertex.onlyBuiltin) ? fallbackEnv : undefined);
|
|
278
|
+
this.vertexInformation.set(vid, vertex);
|
|
280
279
|
const has = this.types.get(vertex.tag);
|
|
281
280
|
if (has) {
|
|
282
|
-
has.push(
|
|
281
|
+
has.push(vid);
|
|
283
282
|
}
|
|
284
283
|
else {
|
|
285
|
-
this.types.set(vertex.tag, [
|
|
284
|
+
this.types.set(vertex.tag, [vid]);
|
|
286
285
|
}
|
|
287
286
|
if (asRoot) {
|
|
288
|
-
this.rootVertices.add(
|
|
287
|
+
this.rootVertices.add(vid);
|
|
289
288
|
}
|
|
290
289
|
return this;
|
|
291
290
|
}
|
|
@@ -293,11 +292,10 @@ class DataflowGraph {
|
|
|
293
292
|
if (fromId === toId) {
|
|
294
293
|
return this;
|
|
295
294
|
}
|
|
296
|
-
/* we now that we pass all required arguments */
|
|
297
|
-
const edge = { types: type };
|
|
298
295
|
const existingFrom = this.edgeInformation.get(fromId);
|
|
299
296
|
const edgeInFrom = existingFrom?.get(toId);
|
|
300
297
|
if (edgeInFrom === undefined) {
|
|
298
|
+
const edge = { types: type };
|
|
301
299
|
if (existingFrom === undefined) {
|
|
302
300
|
this.edgeInformation.set(fromId, new Map([[toId, edge]]));
|
|
303
301
|
}
|
|
@@ -374,8 +372,9 @@ class DataflowGraph {
|
|
|
374
372
|
vertex.cds = reference.cds;
|
|
375
373
|
}
|
|
376
374
|
else {
|
|
377
|
-
|
|
378
|
-
|
|
375
|
+
const oldTag = vertex.tag;
|
|
376
|
+
vertex.tag = vertex_1.VertexType.VariableDefinition;
|
|
377
|
+
this.types.set(oldTag, (this.types.get(oldTag) ?? []).filter(id => id !== reference.nodeId));
|
|
379
378
|
this.types.set(vertex_1.VertexType.VariableDefinition, (this.types.get(vertex_1.VertexType.VariableDefinition) ?? []).concat([reference.nodeId]));
|
|
380
379
|
}
|
|
381
380
|
}
|
|
@@ -384,43 +383,48 @@ class DataflowGraph {
|
|
|
384
383
|
* @param info - The information about the new function call node
|
|
385
384
|
*/
|
|
386
385
|
updateToFunctionCall(info) {
|
|
387
|
-
const
|
|
386
|
+
const infoId = info.id;
|
|
387
|
+
const vertex = this.getVertex(infoId);
|
|
388
388
|
(0, assert_1.guard)(vertex !== undefined && (vertex.tag === vertex_1.VertexType.Use || vertex.tag === vertex_1.VertexType.Value), () => `node must be a use or value node for ${JSON.stringify(info.id)} to update it to a function call but is ${vertex?.tag}`);
|
|
389
389
|
const previousTag = vertex.tag;
|
|
390
|
-
this.vertexInformation.set(
|
|
391
|
-
this.types.set(previousTag, (this.types.get(previousTag) ?? []).filter(id => id !==
|
|
392
|
-
|
|
390
|
+
this.vertexInformation.set(infoId, { ...vertex, ...info, tag: vertex_1.VertexType.FunctionCall });
|
|
391
|
+
this.types.set(previousTag, (this.types.get(previousTag) ?? []).filter(id => id !== infoId));
|
|
392
|
+
const g = this.types.get(vertex_1.VertexType.FunctionCall);
|
|
393
|
+
if (g) {
|
|
394
|
+
g.push(infoId);
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
this.types.set(vertex_1.VertexType.FunctionCall, [infoId]);
|
|
398
|
+
}
|
|
393
399
|
}
|
|
394
400
|
/** If you do not pass the `to` node, this will just mark the node as maybe */
|
|
395
401
|
addControlDependency(from, to, when) {
|
|
396
|
-
to =
|
|
402
|
+
to = node_id_1.NodeId.normalize(to);
|
|
397
403
|
const vertex = this.getVertex(from);
|
|
398
404
|
(0, assert_1.guard)(vertex !== undefined, () => `node must be defined for ${from} to add control dependency`);
|
|
399
405
|
vertex.cds ??= [];
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
break;
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
if (!hasControlDependency) {
|
|
409
|
-
vertex.cds.push({ id: to, when });
|
|
406
|
+
let hasControlDependency = false;
|
|
407
|
+
for (const { id, when: cond } of vertex.cds) {
|
|
408
|
+
if (id === to && when !== cond) {
|
|
409
|
+
hasControlDependency = true;
|
|
410
|
+
break;
|
|
410
411
|
}
|
|
411
412
|
}
|
|
413
|
+
if (!hasControlDependency) {
|
|
414
|
+
vertex.cds.push({ id: to, when });
|
|
415
|
+
}
|
|
412
416
|
return this;
|
|
413
417
|
}
|
|
414
418
|
/** Marks the given node as having unknown side effects */
|
|
415
419
|
markIdForUnknownSideEffects(id, target) {
|
|
416
420
|
if (target) {
|
|
417
421
|
this._unknownSideEffects.add({
|
|
418
|
-
id:
|
|
422
|
+
id: node_id_1.NodeId.normalize(id),
|
|
419
423
|
linkTo: typeof target.callName === 'string' ? { ...target, callName: new RegExp(target.callName) } : target
|
|
420
424
|
});
|
|
421
425
|
return this;
|
|
422
426
|
}
|
|
423
|
-
this._unknownSideEffects.add(
|
|
427
|
+
this._unknownSideEffects.add(node_id_1.NodeId.normalize(id));
|
|
424
428
|
return this;
|
|
425
429
|
}
|
|
426
430
|
/**
|
|
@@ -16,6 +16,8 @@ function onUnknownSideEffect(handler) {
|
|
|
16
16
|
*/
|
|
17
17
|
function handleUnknownSideEffect(graph, env, id, target) {
|
|
18
18
|
graph.markIdForUnknownSideEffects(id, target);
|
|
19
|
-
|
|
19
|
+
for (const handler of handlers) {
|
|
20
|
+
handler(graph, env, id, target);
|
|
21
|
+
}
|
|
20
22
|
}
|
|
21
23
|
//# sourceMappingURL=unknown-side-effect.js.map
|
package/dataflow/info.d.ts
CHANGED
|
@@ -19,6 +19,10 @@ export interface ControlDependency {
|
|
|
19
19
|
readonly when?: boolean;
|
|
20
20
|
/** whether this control dependency was created due to iteration (e.g., a loop) */
|
|
21
21
|
readonly byIteration?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* any file-exist assumptions made
|
|
24
|
+
*/
|
|
25
|
+
readonly file?: string;
|
|
22
26
|
}
|
|
23
27
|
/**
|
|
24
28
|
* Negates the given control dependency (i.e., flips the `when` flag).
|
package/dataflow/info.js
CHANGED
|
@@ -66,7 +66,7 @@ function initializeCleanDataflowInformation(entryPoint, data) {
|
|
|
66
66
|
in: [],
|
|
67
67
|
out: [],
|
|
68
68
|
environment: data.environment,
|
|
69
|
-
graph: new graph_1.DataflowGraph(
|
|
69
|
+
graph: new graph_1.DataflowGraph(undefined),
|
|
70
70
|
entryPoint,
|
|
71
71
|
exitPoints: [{ nodeId: entryPoint, type: 0 /* ExitPointType.Default */ }],
|
|
72
72
|
hooks: []
|
|
@@ -138,7 +138,7 @@ function diffControlDependency(a, b, info) {
|
|
|
138
138
|
info.report.addComment(`${info.position}Different control dependency ids. ${info.leftname}: ${JSON.stringify(a.id)} vs. ${info.rightname}: ${JSON.stringify(b.id)}`);
|
|
139
139
|
}
|
|
140
140
|
if (a.when !== b.when) {
|
|
141
|
-
info.report.addComment(`${info.position}Different control dependency when. ${info.leftname}: ${a.when} vs. ${info.rightname}: ${b.when}`);
|
|
141
|
+
info.report.addComment(`${info.position}Different control dependency when (id: ${JSON.stringify(a.id)}). ${info.leftname}: ${a.when} vs. ${info.rightname}: ${b.when}`);
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
/**
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { DefaultMap } from '../../util/collections/defaultmap';
|
|
2
|
-
import {
|
|
2
|
+
import type { BuiltIn } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
3
|
+
import { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
3
4
|
import { Identifier, type IdentifierReference } from '../environments/identifier';
|
|
4
5
|
import { type DataflowGraph, FunctionArgument } from '../graph/graph';
|
|
5
6
|
import type { RParameter } from '../../r-bridge/lang-4.x/ast/model/nodes/r-parameter';
|
|
6
7
|
import type { AstIdMap, ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
7
8
|
import { type DataflowGraphVertexFunctionCall, type DataflowGraphVertexFunctionDefinition, type DataflowGraphVertexInfo } from '../graph/vertex';
|
|
8
|
-
import { type BuiltIn } from '../environments/built-in';
|
|
9
9
|
import type { REnvironmentInformation } from '../environments/environment';
|
|
10
10
|
import type { ExitPoint } from '../info';
|
|
11
11
|
export type NameIdMap = DefaultMap<Identifier, IdentifierReference[]>;
|
|
12
12
|
/**
|
|
13
13
|
* Find all reads within the graph that do not reference a local definition in the graph.
|
|
14
14
|
*/
|
|
15
|
-
export declare function findNonLocalReads(graph: DataflowGraph,
|
|
15
|
+
export declare function findNonLocalReads(graph: DataflowGraph, ignores?: ReadonlySet<NodeId>): IdentifierReference[];
|
|
16
16
|
/**
|
|
17
17
|
* Produces a map from names to all identifier references sharing that name.
|
|
18
18
|
*/
|
|
@@ -101,4 +101,4 @@ export declare function linkCircularRedefinitionsWithinALoop(graph: DataflowGrap
|
|
|
101
101
|
/**
|
|
102
102
|
* Reapplies the loop exit points' control dependencies to the given identifier references.
|
|
103
103
|
*/
|
|
104
|
-
export declare function reapplyLoopExitPoints(exits: readonly ExitPoint[], references: readonly IdentifierReference[]): void;
|
|
104
|
+
export declare function reapplyLoopExitPoints(exits: readonly ExitPoint[], references: readonly IdentifierReference[], graph: DataflowGraph): void;
|
|
@@ -32,27 +32,29 @@ const unnamed_call_handling_1 = require("./process/functions/call/unnamed-call-h
|
|
|
32
32
|
/**
|
|
33
33
|
* Find all reads within the graph that do not reference a local definition in the graph.
|
|
34
34
|
*/
|
|
35
|
-
function findNonLocalReads(graph,
|
|
36
|
-
const
|
|
37
|
-
const ids = new Set(graph.vertexIdsOfType(vertex_1.VertexType.Use).concat(graph.vertexIdsOfType(vertex_1.VertexType.FunctionCall)));
|
|
35
|
+
function findNonLocalReads(graph, ignores = new Set()) {
|
|
36
|
+
const defs = new Set(graph.vertexIdsOfType(vertex_1.VertexType.VariableDefinition).concat(graph.vertexIdsOfType(vertex_1.VertexType.FunctionDefinition)));
|
|
38
37
|
/* find all variable use ids which do not link to a given id */
|
|
39
38
|
const nonLocalReads = [];
|
|
40
|
-
for (const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
39
|
+
for (const ids of [graph.vertexIdsOfType(vertex_1.VertexType.Use), graph.vertexIdsOfType(vertex_1.VertexType.FunctionCall)]) {
|
|
40
|
+
for (const nodeId of ids) {
|
|
41
|
+
if (ignores.has(nodeId)) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const outgoing = graph.outgoingEdges(nodeId);
|
|
45
|
+
const origin = graph.getVertex(nodeId);
|
|
46
|
+
const name = (0, node_id_1.recoverName)(nodeId, graph.idMap);
|
|
47
|
+
const type = origin?.tag === vertex_1.VertexType.FunctionCall ? identifier_1.ReferenceType.Function : identifier_1.ReferenceType.Variable;
|
|
48
|
+
const identifierRef = { nodeId, name, type };
|
|
49
|
+
if (outgoing === undefined) {
|
|
50
|
+
nonLocalReads.push(identifierRef);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
for (const [target, e] of outgoing) {
|
|
54
|
+
if (edge_1.DfEdge.includesType(e, edge_1.EdgeType.Reads) && !defs.has(target)) {
|
|
55
|
+
nonLocalReads.push(identifierRef);
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
56
58
|
}
|
|
57
59
|
}
|
|
58
60
|
}
|
|
@@ -64,8 +66,9 @@ function findNonLocalReads(graph, ignore) {
|
|
|
64
66
|
function produceNameSharedIdMap(references) {
|
|
65
67
|
const nameIdShares = new defaultmap_1.DefaultMap(() => []);
|
|
66
68
|
for (const reference of references) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
const rn = reference.name;
|
|
70
|
+
if (rn) {
|
|
71
|
+
nameIdShares.get(rn).push(reference);
|
|
69
72
|
}
|
|
70
73
|
}
|
|
71
74
|
return nameIdShares;
|
|
@@ -232,7 +235,7 @@ function linkFunctionCallWithSingleTarget(graph, { subflow: fnSubflow, exitPoint
|
|
|
232
235
|
continue;
|
|
233
236
|
}
|
|
234
237
|
for (const { nodeId, type, value } of defs) {
|
|
235
|
-
if (!
|
|
238
|
+
if (!node_id_1.NodeId.isBuiltIn(nodeId)) {
|
|
236
239
|
graph.addEdge(ingoing.nodeId, nodeId, edge_1.EdgeType.DefinedByOnCall);
|
|
237
240
|
graph.addEdge(id, nodeId, edge_1.EdgeType.DefinesOnCall);
|
|
238
241
|
if (type === identifier_1.ReferenceType.Function && ingoing.type === identifier_1.ReferenceType.S7MethodPrefix && Array.isArray(value)) {
|
|
@@ -288,7 +291,7 @@ function linkFunctionCall(graph, id, info, idMap, thisGraph, calledFunctionDefin
|
|
|
288
291
|
}
|
|
289
292
|
const functionDefinitionReadIds = new Set();
|
|
290
293
|
for (const [t, e] of edges.entries()) {
|
|
291
|
-
if (!
|
|
294
|
+
if (!node_id_1.NodeId.isBuiltIn(t) && edge_1.DfEdge.doesNotIncludeType(e, edge_1.EdgeType.Argument) && edge_1.DfEdge.includesType(e, FCallLinkReadBits)) {
|
|
292
295
|
functionDefinitionReadIds.add(t);
|
|
293
296
|
}
|
|
294
297
|
}
|
|
@@ -388,7 +391,7 @@ function getAllLinkedFunctionDefinitions(functionDefinitionReadIds, dataflowGrap
|
|
|
388
391
|
while (potential.length !== 0) {
|
|
389
392
|
const cid = potential.pop();
|
|
390
393
|
visited.add(cid);
|
|
391
|
-
if (
|
|
394
|
+
if (node_id_1.NodeId.isBuiltIn(cid)) {
|
|
392
395
|
builtIns.add(cid);
|
|
393
396
|
continue;
|
|
394
397
|
}
|
|
@@ -435,7 +438,6 @@ function linkInputs(referencesToLinkAgainstEnvironment, environmentInformation,
|
|
|
435
438
|
for (const bodyInput of referencesToLinkAgainstEnvironment) {
|
|
436
439
|
const probableTarget = bodyInput.name ? (0, resolve_by_name_1.resolveByName)(bodyInput.name, environmentInformation, bodyInput.type) : undefined;
|
|
437
440
|
if (probableTarget === undefined) {
|
|
438
|
-
log_1.log.trace(`found no target for ${bodyInput.name ? identifier_1.Identifier.toString(bodyInput.name) : '<no-name>'}`);
|
|
439
441
|
if (maybeForRemaining) {
|
|
440
442
|
bodyInput.cds ??= [];
|
|
441
443
|
}
|
|
@@ -473,8 +475,9 @@ function linkCircularRedefinitionsWithinALoop(graph, openIns, outgoing) {
|
|
|
473
475
|
// this implicitly assumes that the outgoing references are ordered
|
|
474
476
|
const lastOutgoing = new Map();
|
|
475
477
|
for (const out of outgoing) {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
+
const on = out.name;
|
|
479
|
+
if (on) {
|
|
480
|
+
lastOutgoing.set(on, out);
|
|
478
481
|
}
|
|
479
482
|
}
|
|
480
483
|
for (const [name, targets] of openIns.entries()) {
|
|
@@ -490,19 +493,42 @@ function linkCircularRedefinitionsWithinALoop(graph, openIns, outgoing) {
|
|
|
490
493
|
/**
|
|
491
494
|
* Reapplies the loop exit points' control dependencies to the given identifier references.
|
|
492
495
|
*/
|
|
493
|
-
function reapplyLoopExitPoints(exits, references) {
|
|
496
|
+
function reapplyLoopExitPoints(exits, references, graph) {
|
|
494
497
|
// just apply the cds of all exit points not already present
|
|
495
|
-
const exitCds =
|
|
498
|
+
const exitCds = exits.flatMap(e => e.cds?.map(info_1.negateControlDependency))
|
|
499
|
+
.filter(assert_1.isNotUndefined)
|
|
500
|
+
.map(cd => ({ ...cd, byIteration: true }));
|
|
501
|
+
const seenRefs = new Set();
|
|
496
502
|
for (const ref of references) {
|
|
503
|
+
if (seenRefs.has(ref.nodeId)) {
|
|
504
|
+
continue;
|
|
505
|
+
}
|
|
506
|
+
seenRefs.add(ref.nodeId);
|
|
497
507
|
for (const cd of exitCds) {
|
|
498
|
-
const { id: cId
|
|
508
|
+
const { id: cId } = cd;
|
|
509
|
+
let setVertex = false;
|
|
499
510
|
if (ref.cds) {
|
|
500
|
-
if (!ref.cds?.find(c => c.id === cId
|
|
501
|
-
ref.cds.push(
|
|
511
|
+
if (!ref.cds?.find(c => c.id === cId)) {
|
|
512
|
+
ref.cds.push(cd);
|
|
513
|
+
setVertex = true;
|
|
502
514
|
}
|
|
503
515
|
}
|
|
504
516
|
else {
|
|
505
|
-
ref.cds = [
|
|
517
|
+
ref.cds = [cd];
|
|
518
|
+
setVertex = true;
|
|
519
|
+
}
|
|
520
|
+
if (setVertex) {
|
|
521
|
+
const vertex = graph.getVertex(ref.nodeId);
|
|
522
|
+
if (vertex) {
|
|
523
|
+
if (vertex.cds) {
|
|
524
|
+
if (!vertex.cds?.find(c => c.id === cId)) {
|
|
525
|
+
vertex.cds.push(cd);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
vertex.cds = [cd];
|
|
530
|
+
}
|
|
531
|
+
}
|
|
506
532
|
}
|
|
507
533
|
}
|
|
508
534
|
}
|
|
@@ -2,6 +2,7 @@ import type { RNode } from '../../../../../../r-bridge/lang-4.x/ast/model/model'
|
|
|
2
2
|
import type { AstIdMap, ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
3
3
|
import { EmptyArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
4
4
|
import type { RUnnamedArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument';
|
|
5
|
+
import { RArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument';
|
|
5
6
|
/**
|
|
6
7
|
* Converts a normalized node into an unnamed argument (wraps it with an argument node).
|
|
7
8
|
*/
|
|
@@ -9,4 +10,4 @@ export declare function toUnnamedArgument<OtherInfo>(node: RNode<OtherInfo & Par
|
|
|
9
10
|
/**
|
|
10
11
|
* Wraps the given nodes as unnamed arguments where necessary.
|
|
11
12
|
*/
|
|
12
|
-
export declare function wrapArgumentsUnnamed<OtherInfo>(nodes: readonly (RNode<OtherInfo & ParentInformation> | typeof EmptyArgument | undefined)[], idMap: AstIdMap<OtherInfo>): ("<>" |
|
|
13
|
+
export declare function wrapArgumentsUnnamed<OtherInfo>(nodes: readonly (RNode<OtherInfo & ParentInformation> | typeof EmptyArgument | undefined)[], idMap: AstIdMap<OtherInfo>): ("<>" | RArgument<OtherInfo & ParentInformation>)[];
|
|
@@ -4,7 +4,9 @@ exports.toUnnamedArgument = toUnnamedArgument;
|
|
|
4
4
|
exports.wrapArgumentsUnnamed = wrapArgumentsUnnamed;
|
|
5
5
|
const range_1 = require("../../../../../../util/range");
|
|
6
6
|
const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
7
|
+
const r_argument_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument");
|
|
7
8
|
const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
|
|
9
|
+
const graph_1 = require("../../../../../graph/graph");
|
|
8
10
|
/**
|
|
9
11
|
* Converts a normalized node into an unnamed argument (wraps it with an argument node).
|
|
10
12
|
*/
|
|
@@ -30,6 +32,6 @@ function toUnnamedArgument(node, idMap) {
|
|
|
30
32
|
* Wraps the given nodes as unnamed arguments where necessary.
|
|
31
33
|
*/
|
|
32
34
|
function wrapArgumentsUnnamed(nodes, idMap) {
|
|
33
|
-
return nodes.map(n => n
|
|
35
|
+
return nodes.map(n => graph_1.FunctionArgument.isEmpty(n) || r_argument_1.RArgument.is(n) ? n : toUnnamedArgument(n, idMap));
|
|
34
36
|
}
|
|
35
37
|
//# sourceMappingURL=make-argument.js.map
|
|
@@ -3,7 +3,7 @@ import type { DataflowInformation } from '../../../../../info';
|
|
|
3
3
|
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
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
|
-
import
|
|
6
|
+
import { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
7
7
|
import type { ForceArguments } from '../common';
|
|
8
8
|
/**
|
|
9
9
|
* Processes different types of access operations.
|
|
@@ -4,6 +4,7 @@ exports.processAccess = processAccess;
|
|
|
4
4
|
exports.symbolArgumentsToStrings = symbolArgumentsToStrings;
|
|
5
5
|
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
|
+
const node_id_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id");
|
|
7
8
|
const logger_1 = require("../../../../../logger");
|
|
8
9
|
const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
|
|
9
10
|
const edge_1 = require("../../../../../graph/edge");
|
|
@@ -94,7 +95,7 @@ function processAccess(name, args, rootId, data, config) {
|
|
|
94
95
|
function processNumberBasedAccess(data, name, args, rootId, config, head) {
|
|
95
96
|
const existing = data.environment.current.memory.get(':=');
|
|
96
97
|
const outInfo = { definitionRootNodes: [] };
|
|
97
|
-
const tableAssignId =
|
|
98
|
+
const tableAssignId = node_id_1.NodeId.toBuiltIn(':=-table');
|
|
98
99
|
data.environment.current.memory.set(':=', [{
|
|
99
100
|
type: identifier_1.ReferenceType.BuiltInFunction,
|
|
100
101
|
definedAt: tableAssignId,
|
|
@@ -15,6 +15,7 @@ const r_value_1 = require("../../../../../eval/values/r-value");
|
|
|
15
15
|
const log_1 = require("../../../../../../util/log");
|
|
16
16
|
const alias_tracking_1 = require("../../../../../eval/resolve/alias-tracking");
|
|
17
17
|
const built_in_1 = require("../../../../../environments/built-in");
|
|
18
|
+
const r_string_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-string");
|
|
18
19
|
/**
|
|
19
20
|
* Process an apply call like `vapply` or `mapply`.
|
|
20
21
|
*/
|
|
@@ -65,13 +66,10 @@ function processApply(name, args, rootId, data, config) {
|
|
|
65
66
|
let functionName = undefined;
|
|
66
67
|
let anonymous = false;
|
|
67
68
|
const val = arg.value;
|
|
68
|
-
if (unquoteFunction &&
|
|
69
|
+
if (unquoteFunction && r_string_1.RString.is(val)) {
|
|
69
70
|
functionId = val.info.id;
|
|
70
71
|
functionName = val.content.str;
|
|
71
|
-
information = {
|
|
72
|
-
...information,
|
|
73
|
-
in: [...information.in, { type: identifier_1.ReferenceType.Function, name: functionName, cds: data.cds, nodeId: functionId }]
|
|
74
|
-
};
|
|
72
|
+
information.in = [...information.in, { type: identifier_1.ReferenceType.Function, name: functionName, cds: data.cds, nodeId: functionId }];
|
|
75
73
|
}
|
|
76
74
|
else if (val.type === type_1.RType.Symbol) {
|
|
77
75
|
functionId = val.info.id;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { DataflowInformation } from '../../../../../info';
|
|
6
6
|
import { type DataflowProcessorInformation } from '../../../../../processor';
|
|
7
|
-
import
|
|
7
|
+
import { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
8
8
|
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
9
9
|
import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
10
10
|
import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
@@ -7,6 +7,7 @@ const linker_1 = require("../../../../linker");
|
|
|
7
7
|
const assert_1 = require("../../../../../../util/assert");
|
|
8
8
|
const unpack_argument_1 = require("../argument/unpack-argument");
|
|
9
9
|
const common_1 = require("../common");
|
|
10
|
+
const node_id_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id");
|
|
10
11
|
const graph_1 = require("../../../../../graph/graph");
|
|
11
12
|
const identifier_1 = require("../../../../../environments/identifier");
|
|
12
13
|
const resolve_by_name_1 = require("../../../../../environments/resolve-by-name");
|
|
@@ -20,13 +21,13 @@ const log_1 = require("../../../../../../util/log");
|
|
|
20
21
|
const reference_to_maybe_1 = require("../../../../../environments/reference-to-maybe");
|
|
21
22
|
function linkReadNameToWriteIfPossible(read, environments, listEnvironments, remainingRead, nextGraph) {
|
|
22
23
|
const readName = read.name && identifier_1.Identifier.isDotDotDotAccess(read.name) ? identifier_1.Identifier.dotdotdot() : read.name;
|
|
23
|
-
const readId = readName ? identifier_1.Identifier.getName(readName) : undefined;
|
|
24
24
|
const probableTarget = readName ? (0, resolve_by_name_1.resolveByName)(readName, environments, read.type) : undefined;
|
|
25
25
|
// record if at least one has not been defined
|
|
26
26
|
if (probableTarget === undefined || probableTarget.some(t => !listEnvironments.has(t.nodeId) || !(0, info_1.happensInEveryBranch)(t.cds))) {
|
|
27
|
+
const readId = readName ? identifier_1.Identifier.getName(readName) : undefined;
|
|
27
28
|
const has = remainingRead.get(readId);
|
|
28
29
|
if (has) {
|
|
29
|
-
if (!has
|
|
30
|
+
if (!has.some(h => h.nodeId === read.nodeId && h.name === read.name && h.cds === read.cds)) {
|
|
30
31
|
has.push(read);
|
|
31
32
|
}
|
|
32
33
|
}
|
|
@@ -42,7 +43,7 @@ function linkReadNameToWriteIfPossible(read, environments, listEnvironments, rem
|
|
|
42
43
|
const rid = read.nodeId;
|
|
43
44
|
for (const target of probableTarget) {
|
|
44
45
|
const tid = target.nodeId;
|
|
45
|
-
if ((read.type === identifier_1.ReferenceType.Function || read.type === identifier_1.ReferenceType.BuiltInFunction)
|
|
46
|
+
if (node_id_1.NodeId.isBuiltIn(target.definedAt) && (read.type === identifier_1.ReferenceType.Function || read.type === identifier_1.ReferenceType.BuiltInFunction)) {
|
|
46
47
|
nextGraph.addEdge(rid, tid, edge_1.EdgeType.Reads | edge_1.EdgeType.Calls);
|
|
47
48
|
}
|
|
48
49
|
else {
|
|
@@ -66,7 +67,7 @@ function updateSideEffectsForCalledFunctions(calledEnvs, inputEnvironment, nextG
|
|
|
66
67
|
while (!current?.builtInEnv) {
|
|
67
68
|
for (const definitions of current.memory.values()) {
|
|
68
69
|
for (const def of definitions) {
|
|
69
|
-
if (!
|
|
70
|
+
if (!node_id_1.NodeId.isBuiltIn(def.definedAt)) {
|
|
70
71
|
hasUpdate = true;
|
|
71
72
|
nextGraph.addEdge(def.nodeId, functionCall, edge_1.EdgeType.SideEffectOnCall);
|
|
72
73
|
}
|
|
@@ -179,7 +180,7 @@ function processExpressionList(name, args, rootId, data) {
|
|
|
179
180
|
argumentProcessResult: processedExpressions,
|
|
180
181
|
origin: built_in_1.BuiltInProcName.ExpressionList
|
|
181
182
|
});
|
|
182
|
-
nextGraph.addEdge(rootId,
|
|
183
|
+
nextGraph.addEdge(rootId, node_id_1.NodeId.toBuiltIn('{'), edge_1.EdgeType.Reads | edge_1.EdgeType.Calls);
|
|
183
184
|
// process all exit points as potential returns:
|
|
184
185
|
for (const exit of exitPoints) {
|
|
185
186
|
if (exit.type === 1 /* ExitPointType.Return */ || exit.type === 0 /* ExitPointType.Default */) {
|
|
@@ -29,6 +29,8 @@ function processForLoop(name, args, rootId, data) {
|
|
|
29
29
|
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
30
30
|
}
|
|
31
31
|
const [variableArg, vectorArg, bodyArg] = args.map(e => (0, unpack_argument_1.unpackNonameArg)(e));
|
|
32
|
+
// we store the original environment here, as we merge it back lter in case the for-loop never executes
|
|
33
|
+
const origEnv = data.environment;
|
|
32
34
|
(0, assert_1.guard)(variableArg !== undefined && vectorArg !== undefined && bodyArg !== undefined, () => `For-Loop ${JSON.stringify(args)} has missing arguments! Bad!`);
|
|
33
35
|
const vector = (0, processor_1.processDataflowFor)(vectorArg, data);
|
|
34
36
|
if ((0, info_1.alwaysExits)(vector)) {
|
|
@@ -41,23 +43,29 @@ function processForLoop(name, args, rootId, data) {
|
|
|
41
43
|
let headEnvironments = (0, overwrite_1.overwriteEnvironment)(vector.environment, variable.environment);
|
|
42
44
|
const headGraph = variable.graph.mergeWith(vector.graph);
|
|
43
45
|
const writtenVariable = variable.unknownReferences.concat(variable.in);
|
|
46
|
+
const writtenIds = new Set();
|
|
44
47
|
for (const write of writtenVariable) {
|
|
48
|
+
writtenIds.add(write.nodeId);
|
|
45
49
|
headEnvironments = (0, define_1.define)({ ...write, definedAt: name.info.id, type: identifier_1.ReferenceType.Variable }, false, headEnvironments);
|
|
46
50
|
}
|
|
47
|
-
data =
|
|
51
|
+
data.environment = headEnvironments;
|
|
48
52
|
const body = (0, processor_1.processDataflowFor)(bodyArg, data);
|
|
49
|
-
const nextGraph = headGraph.mergeWith(body.graph);
|
|
50
53
|
const outEnvironment = (0, append_1.appendEnvironment)(headEnvironments, body.environment);
|
|
54
|
+
const cd = [{ id: name.info.id, when: true }];
|
|
55
|
+
const bodyRefs = body.in.concat(body.unknownReferences);
|
|
56
|
+
(0, reference_to_maybe_1.applyCdsToAllInGraphButConstants)(body.graph, bodyRefs, cd);
|
|
57
|
+
const nextGraph = headGraph.mergeWith(body.graph);
|
|
51
58
|
// now we have to identify all reads that may be effected by a circular redefinition
|
|
52
59
|
// for this, we search for all reads with a non-local read resolve!
|
|
53
|
-
const nameIdShares = (0, linker_1.produceNameSharedIdMap)((0, linker_1.findNonLocalReads)(nextGraph,
|
|
60
|
+
const nameIdShares = (0, linker_1.produceNameSharedIdMap)((0, linker_1.findNonLocalReads)(nextGraph, writtenIds));
|
|
54
61
|
for (const write of writtenVariable) {
|
|
55
62
|
nextGraph.addEdge(write.nodeId, vector.entryPoint, edge_1.EdgeType.DefinedBy);
|
|
56
63
|
nextGraph.setDefinitionOfVertex(write);
|
|
57
64
|
}
|
|
58
|
-
|
|
65
|
+
(0, reference_to_maybe_1.applyCdToReferences)(body.out, cd);
|
|
66
|
+
const outgoing = variable.out.concat(writtenVariable, body.out);
|
|
59
67
|
(0, linker_1.linkCircularRedefinitionsWithinALoop)(nextGraph, nameIdShares, body.out);
|
|
60
|
-
(0, linker_1.reapplyLoopExitPoints)(body.exitPoints, body.in.concat(body.out, body.unknownReferences));
|
|
68
|
+
(0, linker_1.reapplyLoopExitPoints)(body.exitPoints, body.in.concat(body.out, body.unknownReferences), nextGraph);
|
|
61
69
|
(0, common_1.patchFunctionCall)({
|
|
62
70
|
nextGraph,
|
|
63
71
|
rootId,
|
|
@@ -78,7 +86,8 @@ function processForLoop(name, args, rootId, data) {
|
|
|
78
86
|
graph: nextGraph,
|
|
79
87
|
entryPoint: name.info.id,
|
|
80
88
|
exitPoints: (0, info_1.filterOutLoopExitPoints)(body.exitPoints),
|
|
81
|
-
environment
|
|
89
|
+
// if we can not be sure that the for-loop runs once, we have to merge back the original environment, as the body may never execute
|
|
90
|
+
environment: (0, append_1.appendEnvironment)(origEnv, outEnvironment),
|
|
82
91
|
hooks: variable.hooks.concat(vector.hooks, body.hooks),
|
|
83
92
|
};
|
|
84
93
|
}
|
|
@@ -3,7 +3,7 @@ import { type DataflowInformation } from '../../../../../info';
|
|
|
3
3
|
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
4
4
|
import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
5
5
|
import { type RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
6
|
-
import
|
|
6
|
+
import { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
7
7
|
import { DataflowGraph } from '../../../../../graph/graph';
|
|
8
8
|
import { type REnvironmentInformation } from '../../../../../environments/environment';
|
|
9
9
|
import type { ReadOnlyFlowrAnalyzerContext } from '../../../../../../project/context/flowr-analyzer-context';
|
|
@@ -11,6 +11,7 @@ const unpack_argument_1 = require("../argument/unpack-argument");
|
|
|
11
11
|
const assert_1 = require("../../../../../../util/assert");
|
|
12
12
|
const logger_1 = require("../../../../../logger");
|
|
13
13
|
const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
14
|
+
const node_id_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id");
|
|
14
15
|
const graph_1 = require("../../../../../graph/graph");
|
|
15
16
|
const identifier_1 = require("../../../../../environments/identifier");
|
|
16
17
|
const overwrite_1 = require("../../../../../environments/overwrite");
|
|
@@ -248,7 +249,7 @@ function updateNestedFunctionCalls(graph, outEnvironment) {
|
|
|
248
249
|
const collectedNextMethods = new Set();
|
|
249
250
|
const treatAsS3 = origin.includes(built_in_1.BuiltInProcName.S3Dispatch);
|
|
250
251
|
for (const target of targets) {
|
|
251
|
-
if (
|
|
252
|
+
if (node_id_1.NodeId.isBuiltIn(target)) {
|
|
252
253
|
graph.addEdge(id, target, edge_1.EdgeType.Calls);
|
|
253
254
|
continue;
|
|
254
255
|
}
|
|
@@ -289,7 +290,7 @@ function updateNestedFunctionCalls(graph, outEnvironment) {
|
|
|
289
290
|
const inId = ingoing.nodeId;
|
|
290
291
|
(0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Found ${resolved.length} references to open ref ${id} in closure of function definition ${id}`);
|
|
291
292
|
for (const { nodeId } of resolved) {
|
|
292
|
-
if (!
|
|
293
|
+
if (!node_id_1.NodeId.isBuiltIn(nodeId)) {
|
|
293
294
|
graph.addEdge(inId, nodeId, edge_1.EdgeType.DefinedByOnCall);
|
|
294
295
|
graph.addEdge(id, nodeId, edge_1.EdgeType.DefinesOnCall);
|
|
295
296
|
}
|
|
@@ -14,8 +14,8 @@ const general_1 = require("../../../../../eval/values/general");
|
|
|
14
14
|
const alias_tracking_1 = require("../../../../../eval/resolve/alias-tracking");
|
|
15
15
|
const reference_to_maybe_1 = require("../../../../../environments/reference-to-maybe");
|
|
16
16
|
const linker_1 = require("../../../../linker");
|
|
17
|
-
const r_argument_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument");
|
|
18
17
|
const built_in_1 = require("../../../../../environments/built-in");
|
|
18
|
+
const r_argument_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument");
|
|
19
19
|
function getArguments(config, args) {
|
|
20
20
|
let condArg;
|
|
21
21
|
let thenArg;
|
|
@@ -28,9 +28,9 @@ function getArguments(config, args) {
|
|
|
28
28
|
'...': '...'
|
|
29
29
|
};
|
|
30
30
|
const argMaps = (0, linker_1.invertArgumentMap)((0, linker_1.pMatch)((0, common_1.convertFnArguments)(args), params));
|
|
31
|
-
condArg = (0, unpack_argument_1.unpackArg)(
|
|
32
|
-
thenArg = (0, unpack_argument_1.unpackArg)(
|
|
33
|
-
otherwiseArg = (0, unpack_argument_1.unpackArg)(
|
|
31
|
+
condArg = (0, unpack_argument_1.unpackArg)(r_argument_1.RArgument.getWithId(args, argMaps.get('cond')?.[0]));
|
|
32
|
+
thenArg = (0, unpack_argument_1.unpackArg)(r_argument_1.RArgument.getWithId(args, argMaps.get('yes')?.[0]));
|
|
33
|
+
otherwiseArg = (0, unpack_argument_1.unpackArg)(r_argument_1.RArgument.getWithId(args, argMaps.get('no')?.[0]));
|
|
34
34
|
}
|
|
35
35
|
else {
|
|
36
36
|
[condArg, thenArg, otherwiseArg] = args.map(e => (0, unpack_argument_1.unpackArg)(e));
|