@eagleoutice/flowr 2.9.14 → 2.10.2
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 +52 -29
- package/abstract-interpretation/absint-visitor.d.ts +13 -8
- package/abstract-interpretation/absint-visitor.js +35 -26
- package/abstract-interpretation/data-frame/dataframe-domain.d.ts +1 -2
- package/abstract-interpretation/data-frame/dataframe-domain.js +14 -15
- package/abstract-interpretation/data-frame/mappers/access-mapper.js +2 -15
- package/abstract-interpretation/data-frame/mappers/arguments.d.ts +11 -17
- package/abstract-interpretation/data-frame/mappers/arguments.js +18 -18
- package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +41 -15
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +74 -48
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +2 -1
- package/abstract-interpretation/data-frame/semantics.d.ts +1 -1
- package/abstract-interpretation/data-frame/semantics.js +31 -35
- package/abstract-interpretation/data-frame/shape-inference.js +1 -1
- package/abstract-interpretation/domains/interval-domain.d.ts +1 -0
- package/abstract-interpretation/domains/interval-domain.js +3 -0
- package/abstract-interpretation/domains/product-domain.d.ts +9 -0
- package/abstract-interpretation/domains/product-domain.js +26 -6
- package/abstract-interpretation/domains/state-abstract-domain.d.ts +36 -22
- package/abstract-interpretation/domains/state-abstract-domain.js +169 -62
- package/abstract-interpretation/unsupported-functions.d.ts +10 -0
- package/abstract-interpretation/unsupported-functions.js +45 -0
- package/benchmark/slicer.js +10 -13
- package/benchmark/stats/stats.d.ts +2 -2
- package/cli/flowr.js +1 -1
- package/cli/repl/parser/slice-query-parser.d.ts +2 -2
- package/config.d.ts +4 -0
- package/config.js +5 -3
- package/control-flow/control-flow-graph.js +13 -9
- package/control-flow/semantic-cfg-guided-visitor.d.ts +6 -0
- package/control-flow/semantic-cfg-guided-visitor.js +6 -0
- package/dataflow/environments/built-in-proc-name.d.ts +6 -0
- package/dataflow/environments/built-in-proc-name.js +6 -0
- package/dataflow/environments/built-in.d.ts +7 -5
- package/dataflow/environments/built-in.js +2 -0
- package/dataflow/environments/default-builtin-config.d.ts +442 -6
- package/dataflow/environments/default-builtin-config.js +158 -3
- package/dataflow/environments/identifier.d.ts +4 -0
- package/dataflow/environments/identifier.js +17 -0
- package/dataflow/environments/overwrite.js +2 -5
- package/dataflow/graph/call-graph.d.ts +4 -7
- package/dataflow/graph/call-graph.js +0 -22
- package/dataflow/graph/df-helper.d.ts +23 -12
- package/dataflow/graph/df-helper.js +44 -7
- package/dataflow/graph/graph-helper.d.ts +9 -4
- package/dataflow/graph/graph-helper.js +26 -3
- package/dataflow/graph/graph.d.ts +23 -2
- package/dataflow/graph/graph.js +38 -4
- package/dataflow/graph/vertex.d.ts +2 -0
- package/dataflow/instrument/instrument-dataflow-count.d.ts +10 -0
- package/dataflow/instrument/instrument-dataflow-count.js +10 -0
- package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +4 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +1 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.d.ts +2 -2
- 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.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +8 -19
- package/dataflow/internal/process/functions/call/built-in/built-in-get.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-library.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-list.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-local.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.d.ts +23 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +80 -12
- package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.d.ts +41 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.js +179 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.d.ts +7 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +62 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-recall.d.ts +7 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-recall.js +15 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-dispatch.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.d.ts +2 -2
- 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-special-bin-op.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.d.ts +2 -2
- package/dataflow/internal/process/functions/call/common.d.ts +2 -2
- package/dataflow/internal/process/functions/call/common.js +6 -4
- package/dataflow/internal/process/functions/call/known-call-handling.d.ts +2 -2
- package/dataflow/internal/process/functions/call/named-call-handling.d.ts +2 -2
- package/dataflow/internal/process/functions/process-parameter.js +1 -1
- package/documentation/doc-readme.js +2 -1
- package/documentation/wiki-absint.js +6 -5
- package/documentation/wiki-analyzer.js +0 -2
- package/documentation/wiki-linter.js +6 -0
- package/documentation/wiki-normalized-ast.js +7 -7
- package/linter/linter-rules.d.ts +49 -1
- package/linter/linter-rules.js +5 -1
- package/linter/rules/dataframe-access-validation.d.ts +1 -1
- package/linter/rules/dataframe-access-validation.js +3 -4
- package/linter/rules/problematic-eval.d.ts +44 -0
- package/linter/rules/problematic-eval.js +83 -0
- package/linter/rules/roxygen-arguments.d.ts +35 -0
- package/linter/rules/roxygen-arguments.js +100 -0
- package/package.json +8 -9
- package/project/context/flowr-analyzer-context.d.ts +1 -8
- package/project/context/flowr-analyzer-context.js +1 -7
- package/project/context/flowr-analyzer-environment-context.d.ts +5 -0
- package/project/context/flowr-analyzer-environment-context.js +6 -0
- package/project/context/flowr-analyzer-files-context.d.ts +6 -0
- package/project/context/flowr-analyzer-files-context.js +4 -2
- package/project/flowr-analyzer-builder.js +1 -4
- package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +10 -5
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +1 -1
- package/queries/catalog/dependencies-query/function-info/library-functions.js +2 -0
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +1 -1
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +3 -3
- package/queries/catalog/df-shape-query/df-shape-query-format.js +7 -2
- package/queries/catalog/does-call-query/does-call-query-executor.js +1 -1
- package/queries/catalog/does-call-query/does-call-query-format.d.ts +2 -2
- package/queries/catalog/files-query/files-query-executor.js +0 -1
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -2
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +3 -3
- package/queries/catalog/input-sources-query/input-sources-query-executor.d.ts +6 -0
- package/queries/catalog/input-sources-query/input-sources-query-executor.js +66 -0
- package/queries/catalog/input-sources-query/input-sources-query-format.d.ts +36 -0
- package/queries/catalog/input-sources-query/input-sources-query-format.js +63 -0
- package/queries/catalog/input-sources-query/simple-input-classifier.d.ts +92 -0
- package/queries/catalog/input-sources-query/simple-input-classifier.js +310 -0
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +2 -2
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +1 -1
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +2 -2
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +1 -1
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +2 -2
- package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +2 -2
- package/queries/catalog/location-map-query/location-map-query-executor.js +1 -1
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +2 -2
- package/queries/catalog/origin-query/origin-query-executor.d.ts +2 -2
- package/queries/catalog/origin-query/origin-query-executor.js +1 -1
- package/queries/catalog/origin-query/origin-query-format.d.ts +3 -3
- package/queries/catalog/provenance-query/provenance-query-executor.d.ts +1 -4
- package/queries/catalog/provenance-query/provenance-query-executor.js +3 -6
- package/queries/catalog/provenance-query/provenance-query-format.d.ts +2 -2
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +1 -1
- package/queries/query.d.ts +9 -1
- package/queries/query.js +2 -0
- package/r-bridge/data/data.d.ts +2 -2
- package/r-bridge/data/data.js +2 -2
- package/r-bridge/lang-4.x/ast/model/model.d.ts +3 -0
- package/r-bridge/lang-4.x/ast/model/model.js +3 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +29 -6
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +16 -2
- 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 +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +15 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +15 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +19 -4
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +21 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +16 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +25 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +15 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.js +2 -0
- 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 +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.js +2 -0
- package/r-bridge/lang-4.x/ast/model/versions.d.ts +2 -0
- package/r-bridge/lang-4.x/ast/model/versions.js +3 -1
- package/r-bridge/roxygen2/documentation-provider.js +15 -6
- package/r-bridge/roxygen2/roxygen-ast.d.ts +3 -1
- package/search/flowr-search-builder.js +3 -2
- package/search/search-executor/search-generators.js +1 -1
- package/slicing/criterion/parse.d.ts +11 -10
- package/slicing/criterion/parse.js +9 -8
- package/slicing/static/static-slicer.js +24 -1
- package/util/collections/arrays.d.ts +4 -0
- package/util/collections/arrays.js +7 -0
- package/util/mermaid/ast.js +2 -1
- package/util/mermaid/dfg.js +2 -1
- package/util/record.d.ts +23 -0
- package/util/record.js +33 -0
- package/util/version.js +1 -1
- package/abstract-interpretation/domains/mapped-abstract-domain.d.ts +0 -41
- package/abstract-interpretation/domains/mapped-abstract-domain.js +0 -213
package/dataflow/graph/graph.js
CHANGED
|
@@ -68,18 +68,48 @@ exports.FunctionArgument = {
|
|
|
68
68
|
return arg !== r_function_call_1.EmptyArgument;
|
|
69
69
|
},
|
|
70
70
|
/**
|
|
71
|
-
* Returns the
|
|
71
|
+
* Returns the id of a non-empty argument.
|
|
72
72
|
* @example
|
|
73
73
|
* ```r
|
|
74
|
-
* foo(a=3, 2) # returns the node id of either `
|
|
74
|
+
* foo(a=3, 2) # returns the node id of either `a` or `2`
|
|
75
75
|
* ```
|
|
76
|
+
* @see {@link FunctionArgument.getReference}
|
|
77
|
+
* @see {@link FunctionArgument.getName}
|
|
76
78
|
*/
|
|
77
|
-
|
|
79
|
+
getId(arg) {
|
|
78
80
|
if (arg !== r_function_call_1.EmptyArgument) {
|
|
79
81
|
return arg?.nodeId;
|
|
80
82
|
}
|
|
81
83
|
return undefined;
|
|
82
84
|
},
|
|
85
|
+
/**
|
|
86
|
+
* Returns the name of a named argument.
|
|
87
|
+
* @example
|
|
88
|
+
* ```r
|
|
89
|
+
* foo(a = 3, 2) # returns 'a' or undefined
|
|
90
|
+
* ```
|
|
91
|
+
* @see {@link FunctionArgument.getId}
|
|
92
|
+
*/
|
|
93
|
+
getName(arg) {
|
|
94
|
+
return exports.FunctionArgument.isNamed(arg) ? arg.name : undefined;
|
|
95
|
+
},
|
|
96
|
+
/**
|
|
97
|
+
* Returns the reference of a non-empty argument.
|
|
98
|
+
* @example
|
|
99
|
+
* ```r
|
|
100
|
+
* foo(a=3, 2) # returns the node id of either `3` or `2`, but skips a
|
|
101
|
+
* ```
|
|
102
|
+
* @see {@link FunctionArgument.getId}
|
|
103
|
+
*/
|
|
104
|
+
getReference(arg) {
|
|
105
|
+
if (arg === r_function_call_1.EmptyArgument) {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
else if (arg.name === undefined) {
|
|
109
|
+
return arg.nodeId;
|
|
110
|
+
}
|
|
111
|
+
return arg.valueId;
|
|
112
|
+
},
|
|
83
113
|
/**
|
|
84
114
|
* Checks whether the given argument is a named argument with the specified name.
|
|
85
115
|
* Please note that this only checks whether the name is exactly identical and not whether
|
|
@@ -369,8 +399,9 @@ class DataflowGraph {
|
|
|
369
399
|
/**
|
|
370
400
|
* Marks a vertex in the graph to be a definition
|
|
371
401
|
* @param reference - The reference to the vertex to mark as definition
|
|
402
|
+
* @param sourceIds - The id of the source vertex of the def, if available
|
|
372
403
|
*/
|
|
373
|
-
setDefinitionOfVertex(reference) {
|
|
404
|
+
setDefinitionOfVertex(reference, sourceIds) {
|
|
374
405
|
const vertex = this.getVertex(reference.nodeId);
|
|
375
406
|
(0, assert_1.guard)(vertex !== undefined, () => `node must be defined for ${JSON.stringify(reference)} to set reference`);
|
|
376
407
|
if (vertex.tag === vertex_1.VertexType.FunctionDefinition || vertex.tag === vertex_1.VertexType.VariableDefinition) {
|
|
@@ -379,6 +410,9 @@ class DataflowGraph {
|
|
|
379
410
|
else {
|
|
380
411
|
const oldTag = vertex.tag;
|
|
381
412
|
vertex.tag = vertex_1.VertexType.VariableDefinition;
|
|
413
|
+
if (sourceIds) {
|
|
414
|
+
vertex.source = sourceIds;
|
|
415
|
+
}
|
|
382
416
|
this.types.set(oldTag, (this.types.get(oldTag) ?? []).filter(id => id !== reference.nodeId));
|
|
383
417
|
this.types.set(vertex_1.VertexType.VariableDefinition, (this.types.get(vertex_1.VertexType.VariableDefinition) ?? []).concat([reference.nodeId]));
|
|
384
418
|
}
|
|
@@ -123,6 +123,8 @@ export interface DataflowGraphVertexVariableDefinition extends DataflowGraphVert
|
|
|
123
123
|
readonly environment?: undefined;
|
|
124
124
|
/** Indicates whether the variable definition is a *partial* definition (e.g,. in `x[a] <- b`) */
|
|
125
125
|
readonly par?: true;
|
|
126
|
+
/** Points to the source ids of the "value" if there is one, this is more of a best-effort flag and not guaranteed to be there */
|
|
127
|
+
readonly source?: readonly NodeId[];
|
|
126
128
|
}
|
|
127
129
|
/**
|
|
128
130
|
* Arguments required to construct a vertex which represents the definition of a function in the {@link DataflowGraph|dataflow graph}.
|
|
@@ -5,5 +5,15 @@ import type { RType } from '../../r-bridge/lang-4.x/ast/model/type';
|
|
|
5
5
|
/**
|
|
6
6
|
* This takes the out parameter `countMap` and fills it with the count of how many times each RType was processed.
|
|
7
7
|
* The accompanying `reset` function can be used to reset the map to an empty state.
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const map = new Map<RType, number>();
|
|
11
|
+
* const analyzer = await new FlowrAnalyzerBuilder()
|
|
12
|
+
* .configure('solver.instrument.dataflowExtractors', instrumentDataflowCount(map, () => map.clear()))
|
|
13
|
+
* .build();
|
|
14
|
+
* analyzer.addRequest(requestFromInput(code));
|
|
15
|
+
* await analyzer.dataflow();
|
|
16
|
+
* ```
|
|
17
|
+
* Now, you can inspect the counts in the `map` objects, these will be reset for each new analysis request using the `() => map.clear()` function.
|
|
8
18
|
*/
|
|
9
19
|
export declare function instrumentDataflowCount(countMap: Map<RType, number>, reset: (map: Map<RType, number>) => void): (extractor: DataflowProcessors<ParentInformation>, ctx: FlowrAnalyzerContext) => DataflowProcessors<ParentInformation>;
|
|
@@ -4,6 +4,16 @@ exports.instrumentDataflowCount = instrumentDataflowCount;
|
|
|
4
4
|
/**
|
|
5
5
|
* This takes the out parameter `countMap` and fills it with the count of how many times each RType was processed.
|
|
6
6
|
* The accompanying `reset` function can be used to reset the map to an empty state.
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const map = new Map<RType, number>();
|
|
10
|
+
* const analyzer = await new FlowrAnalyzerBuilder()
|
|
11
|
+
* .configure('solver.instrument.dataflowExtractors', instrumentDataflowCount(map, () => map.clear()))
|
|
12
|
+
* .build();
|
|
13
|
+
* analyzer.addRequest(requestFromInput(code));
|
|
14
|
+
* await analyzer.dataflow();
|
|
15
|
+
* ```
|
|
16
|
+
* Now, you can inspect the counts in the `map` objects, these will be reset for each new analysis request using the `() => map.clear()` function.
|
|
7
17
|
*/
|
|
8
18
|
function instrumentDataflowCount(countMap, reset) {
|
|
9
19
|
return (extractor, _ctx) => {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
2
2
|
import type { RNode } from '../../../../../../r-bridge/lang-4.x/ast/model/model';
|
|
3
3
|
/**
|
|
4
4
|
* Retrieve the value from an argument, if it is not empty.
|
|
5
5
|
* @see {@link unpackArg} - to specifically retrieve non-named arguments
|
|
6
6
|
*/
|
|
7
|
-
export declare function unpackNonameArg<OtherInfo>(arg:
|
|
7
|
+
export declare function unpackNonameArg<OtherInfo>(arg: PotentiallyEmptyRArgument<OtherInfo> | undefined): RNode<OtherInfo> | undefined;
|
|
8
8
|
/**
|
|
9
9
|
* Retrieve the value from a non-named argument, if it is not empty.
|
|
10
10
|
* @see {@link unpackNonameArg} - to specifically retrieve non-named arguments
|
|
11
11
|
*/
|
|
12
|
-
export declare function unpackArg<OtherInfo>(arg:
|
|
12
|
+
export declare function unpackArg<OtherInfo>(arg: PotentiallyEmptyRArgument<OtherInfo> | undefined): RNode<OtherInfo> | undefined;
|
|
13
13
|
/**
|
|
14
14
|
* Try to unpack the given argument, if it is not empty.
|
|
15
15
|
*/
|
|
16
|
-
export declare function tryUnpackNoNameArg<OtherInfo>(arg:
|
|
16
|
+
export declare function tryUnpackNoNameArg<OtherInfo>(arg: PotentiallyEmptyRArgument<OtherInfo>): RNode<OtherInfo> | PotentiallyEmptyRArgument<OtherInfo>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { DataflowProcessorInformation } from '../../../../../processor';
|
|
2
2
|
import type { DataflowInformation } from '../../../../../info';
|
|
3
3
|
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
4
|
-
import { type
|
|
4
|
+
import { type PotentiallyEmptyRArgument } 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 { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
7
7
|
import type { ForceArguments } from '../common';
|
|
@@ -16,10 +16,10 @@ import type { ForceArguments } from '../common';
|
|
|
16
16
|
* a@foo
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
-
export declare function processAccess<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
19
|
+
export declare function processAccess<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: {
|
|
20
20
|
treatIndicesAsString: boolean;
|
|
21
21
|
} & ForceArguments): DataflowInformation;
|
|
22
22
|
/**
|
|
23
23
|
* Converts symbol arguments to string arguments within the specified range.
|
|
24
24
|
*/
|
|
25
|
-
export declare function symbolArgumentsToStrings<OtherInfo>(args: readonly
|
|
25
|
+
export declare function symbolArgumentsToStrings<OtherInfo>(args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], firstIndexInclusive?: number, lastIndexInclusive?: number): PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DataflowProcessorInformation } from '../../../../../processor';
|
|
2
2
|
import type { DataflowInformation } from '../../../../../info';
|
|
3
|
-
import { type
|
|
3
|
+
import { type PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
4
4
|
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
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';
|
|
@@ -20,4 +20,4 @@ export interface BuiltInApplyConfiguration extends MergeableRecord {
|
|
|
20
20
|
/**
|
|
21
21
|
* Process an apply call like `vapply` or `mapply`.
|
|
22
22
|
*/
|
|
23
|
-
export declare function processApply<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
23
|
+
export declare function processApply<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: BuiltInApplyConfiguration): DataflowInformation;
|
|
@@ -98,6 +98,7 @@ function processApply(name, args, rootId, data, config) {
|
|
|
98
98
|
if (arg && counterpart !== r_function_call_1.EmptyArgument) {
|
|
99
99
|
return {
|
|
100
100
|
name: counterpart.name?.content,
|
|
101
|
+
valueId: counterpart.value?.info.id,
|
|
101
102
|
cds: data.cds,
|
|
102
103
|
type: identifier_1.ReferenceType.Argument,
|
|
103
104
|
nodeId: arg.entryPoint
|
|
@@ -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 { 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
|
-
import type {
|
|
6
|
+
import type { PotentiallyEmptyRArgument } 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 { Identifier, type InGraphIdentifierDefinition } from '../../../../../environments/identifier';
|
|
9
9
|
import type { DataflowGraphVertexFunctionDefinition } from '../../../../../graph/vertex';
|
|
@@ -35,13 +35,13 @@ export interface ExtendedAssignmentConfiguration extends AssignmentConfiguration
|
|
|
35
35
|
/**
|
|
36
36
|
* In contrast to `processAssignment`, this function allows more flexible handling of assignment-like functions.
|
|
37
37
|
*/
|
|
38
|
-
export declare function processAssignmentLike<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
38
|
+
export declare function processAssignmentLike<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: ExtendedAssignmentConfiguration): DataflowInformation;
|
|
39
39
|
/**
|
|
40
40
|
* Processes an assignment, i.e., `<target> <- <source>`.
|
|
41
41
|
* Handling it as a function call \`<-\` `(<target>, <source>)`.
|
|
42
42
|
* This includes handling of replacement functions (e.g., `names(x) <- ...` as \`names<-\` `(x, ...)`).
|
|
43
43
|
*/
|
|
44
|
-
export declare function processAssignment<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
44
|
+
export declare function processAssignment<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: AssignmentConfiguration): DataflowInformation;
|
|
45
45
|
export interface AssignmentToSymbolParameters<OtherInfo> extends AssignmentConfiguration {
|
|
46
46
|
readonly nameOfAssignmentFunction: Identifier;
|
|
47
47
|
readonly source: RNode<OtherInfo & ParentInformation>;
|
|
@@ -297,7 +297,7 @@ function checkTargetReferenceType(sourceInfo, fnModes) {
|
|
|
297
297
|
*/
|
|
298
298
|
function markAsAssignment(information, nodeToDefine, sourceIds, rootIdOfAssignment, data, assignmentConfig) {
|
|
299
299
|
information.environment = (0, define_1.define)(nodeToDefine, assignmentConfig?.superAssignment, information.environment);
|
|
300
|
-
information.graph.setDefinitionOfVertex(nodeToDefine);
|
|
300
|
+
information.graph.setDefinitionOfVertex(nodeToDefine, sourceIds);
|
|
301
301
|
const nid = nodeToDefine.nodeId;
|
|
302
302
|
if (!assignmentConfig?.quoteSource) {
|
|
303
303
|
for (const sourceId of sourceIds) {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { type DataflowProcessorInformation } from '../../../../../processor';
|
|
2
2
|
import { DataflowInformation } from '../../../../../info';
|
|
3
3
|
import { type ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
4
|
-
import { type
|
|
4
|
+
import { type PotentiallyEmptyRArgument } 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
|
/**
|
|
8
8
|
* Process a call to `eval()`, trying to resolve the code being evaluated if possible.
|
|
9
9
|
*/
|
|
10
|
-
export declare function processEvalCall<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
10
|
+
export declare function processEvalCall<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: {
|
|
11
11
|
/** should this produce an explicit source function call in the graph? */
|
|
12
12
|
includeFunctionCall?: boolean;
|
|
13
13
|
}): DataflowInformation;
|
|
@@ -6,9 +6,9 @@ import type { DataflowInformation } from '../../../../../info';
|
|
|
6
6
|
import { type DataflowProcessorInformation } from '../../../../../processor';
|
|
7
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
|
-
import type {
|
|
9
|
+
import type { PotentiallyEmptyRArgument } 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';
|
|
11
11
|
/**
|
|
12
12
|
* Processes a list of expressions joining their dataflow graphs accordingly.
|
|
13
13
|
*/
|
|
14
|
-
export declare function processExpressionList<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
14
|
+
export declare function processExpressionList<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type DataflowProcessorInformation } from '../../../../../processor';
|
|
2
2
|
import { type DataflowInformation } from '../../../../../info';
|
|
3
3
|
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
4
|
-
import type {
|
|
4
|
+
import type { PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
5
5
|
import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
6
6
|
import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
7
7
|
/**
|
|
@@ -11,4 +11,4 @@ import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/node
|
|
|
11
11
|
* `for`(<variable>, <vector>, <body>)
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
14
|
-
export declare function processForLoop<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
14
|
+
export declare function processForLoop<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
|
|
@@ -60,7 +60,7 @@ function processForLoop(name, args, rootId, data) {
|
|
|
60
60
|
const nameIdShares = (0, linker_1.produceNameSharedIdMap)((0, linker_1.findNonLocalReads)(nextGraph, writtenIds));
|
|
61
61
|
for (const write of writtenVariable) {
|
|
62
62
|
nextGraph.addEdge(write.nodeId, vector.entryPoint, edge_1.EdgeType.DefinedBy);
|
|
63
|
-
nextGraph.setDefinitionOfVertex(write);
|
|
63
|
+
nextGraph.setDefinitionOfVertex(write, [vector.entryPoint]);
|
|
64
64
|
}
|
|
65
65
|
(0, reference_to_maybe_1.applyCdToReferences)(body.out, cd);
|
|
66
66
|
const outgoing = variable.out.concat(writtenVariable, body.out);
|
|
@@ -2,7 +2,7 @@ import { type DataflowProcessorInformation } from '../../../../../processor';
|
|
|
2
2
|
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
|
-
import { type
|
|
5
|
+
import { type PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
6
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';
|
|
@@ -10,7 +10,7 @@ import type { ReadOnlyFlowrAnalyzerContext } from '../../../../../../project/con
|
|
|
10
10
|
/**
|
|
11
11
|
* Process a function definition, i.e., `function(a, b) { ... }`
|
|
12
12
|
*/
|
|
13
|
-
export declare function processFunctionDefinition<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
13
|
+
export declare function processFunctionDefinition<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
|
|
14
14
|
/**
|
|
15
15
|
* Retrieve the active environment when entering a function definition or call
|
|
16
16
|
* @param callerEnvironment - environment at the call site / function definition site
|
|
@@ -99,10 +99,10 @@ function processFunctionDefinition(name, args, rootId, data) {
|
|
|
99
99
|
return r_function_call_1.EmptyArgument;
|
|
100
100
|
}
|
|
101
101
|
else if (!p.name && p.value && p.value.type === type_1.RType.Parameter) {
|
|
102
|
-
return { type: identifier_1.ReferenceType.Argument, cds: data.cds, nodeId: p.value.name.info.id, name: p.value.name.content };
|
|
102
|
+
return { type: identifier_1.ReferenceType.Argument, cds: data.cds, nodeId: p.value.name.info.id, name: p.value.name.content, valueId: p.value.defaultValue?.info.id };
|
|
103
103
|
}
|
|
104
104
|
else if (p.name) {
|
|
105
|
-
return { type: identifier_1.ReferenceType.Argument, cds: data.cds, nodeId: p.name.info.id, name: p.name.content };
|
|
105
|
+
return { type: identifier_1.ReferenceType.Argument, valueId: p.value?.info.id, cds: data.cds, nodeId: p.name.info.id, name: p.name.content };
|
|
106
106
|
}
|
|
107
107
|
else {
|
|
108
108
|
return r_function_call_1.EmptyArgument;
|
|
@@ -231,20 +231,10 @@ function updateNestedFunctionCalls(graph, outEnvironment) {
|
|
|
231
231
|
// track *all* function definitions - including those nested within the current graph,
|
|
232
232
|
// try to resolve their 'in' by only using the lowest scope which will be popped after this definition
|
|
233
233
|
for (const [id, { onlyBuiltin, environment, name, args, origin }] of graph.verticesOfType(vertex_1.VertexType.FunctionCall)) {
|
|
234
|
-
if (onlyBuiltin ||
|
|
234
|
+
if (onlyBuiltin || name === undefined) {
|
|
235
235
|
continue;
|
|
236
236
|
}
|
|
237
|
-
|
|
238
|
-
// only the call environment counts!
|
|
239
|
-
if (environment) {
|
|
240
|
-
while (outEnvironment.level > environment.level) {
|
|
241
|
-
outEnvironment = (0, scoping_1.popLocalEnvironment)(outEnvironment);
|
|
242
|
-
}
|
|
243
|
-
while (outEnvironment.level < environment.level) {
|
|
244
|
-
outEnvironment = (0, scoping_1.pushLocalEnvironment)(outEnvironment);
|
|
245
|
-
}
|
|
246
|
-
effectiveEnvironment = (0, overwrite_1.overwriteEnvironment)(outEnvironment, environment);
|
|
247
|
-
}
|
|
237
|
+
const effectiveEnvironment = environment ? (0, overwrite_1.overwriteEnvironment)(outEnvironment, environment) : outEnvironment;
|
|
248
238
|
const targets = new Set((0, linker_1.getAllFunctionCallTargets)(id, graph, effectiveEnvironment));
|
|
249
239
|
const collectedNextMethods = new Set();
|
|
250
240
|
const treatAsS3 = origin.includes(built_in_proc_name_1.BuiltInProcName.S3Dispatch);
|
|
@@ -255,11 +245,10 @@ function updateNestedFunctionCalls(graph, outEnvironment) {
|
|
|
255
245
|
}
|
|
256
246
|
const targetVertex = graph.getVertex(target);
|
|
257
247
|
// support reads on symbols
|
|
258
|
-
if (targetVertex?.tag
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
else if (targetVertex?.tag !== vertex_1.VertexType.FunctionDefinition) {
|
|
248
|
+
if (targetVertex?.tag !== vertex_1.VertexType.FunctionDefinition) {
|
|
249
|
+
if (targetVertex?.tag === vertex_1.VertexType.Use) {
|
|
250
|
+
graph.addEdge(id, target, edge_1.EdgeType.Reads);
|
|
251
|
+
}
|
|
263
252
|
continue;
|
|
264
253
|
}
|
|
265
254
|
graph.addEdge(id, target, edge_1.EdgeType.Calls);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { DataflowProcessorInformation } from '../../../../../processor';
|
|
2
2
|
import type { DataflowInformation } from '../../../../../info';
|
|
3
3
|
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
4
|
-
import type {
|
|
4
|
+
import type { PotentiallyEmptyRArgument } 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
|
/**
|
|
8
8
|
* Processes a built-in 'get' function call.
|
|
9
9
|
*/
|
|
10
|
-
export declare function processGet<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
10
|
+
export declare function processGet<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
|
|
@@ -2,7 +2,7 @@ import { type DataflowProcessorInformation } from '../../../../../processor';
|
|
|
2
2
|
import { type DataflowInformation } from '../../../../../info';
|
|
3
3
|
import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
4
4
|
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
5
|
-
import type {
|
|
5
|
+
import type { PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
6
6
|
import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
7
7
|
/** `if(<cond>) <then> else <else>` built-in function configuration, make sure to not reuse indices */
|
|
8
8
|
export interface IfThenElseConfig {
|
|
@@ -20,4 +20,4 @@ export interface IfThenElseConfig {
|
|
|
20
20
|
* For example, `if(cond) thenExpr else elseExpr` and `if(cond) thenExpr`.
|
|
21
21
|
* The arguments will be either `[cond, thenExpr]` or `[cond, thenExpr, elseExpr]`.
|
|
22
22
|
*/
|
|
23
|
-
export declare function processIfThenElse<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
23
|
+
export declare function processIfThenElse<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config?: IfThenElseConfig): DataflowInformation;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { type DataflowProcessorInformation } from '../../../../../processor';
|
|
2
2
|
import type { DataflowInformation } from '../../../../../info';
|
|
3
3
|
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
4
|
-
import type {
|
|
4
|
+
import type { PotentiallyEmptyRArgument } 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
|
/**
|
|
8
8
|
* Process a library call like `library` or `require`
|
|
9
9
|
*/
|
|
10
|
-
export declare function processLibrary<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
10
|
+
export declare function processLibrary<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
2
2
|
import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
3
3
|
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
4
4
|
import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
@@ -12,4 +12,4 @@ import type { DataflowProcessorInformation } from '../../../../../processor';
|
|
|
12
12
|
* list(a = 1, b = 2)
|
|
13
13
|
* ```
|
|
14
14
|
*/
|
|
15
|
-
export declare function processList<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
15
|
+
export declare function processList<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { DataflowProcessorInformation } from '../../../../../processor';
|
|
2
2
|
import { DataflowInformation } from '../../../../../info';
|
|
3
3
|
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
4
|
-
import type {
|
|
4
|
+
import type { PotentiallyEmptyRArgument } 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
|
export interface LocalFunctionConfiguration {
|
|
@@ -15,4 +15,4 @@ export interface LocalFunctionConfiguration {
|
|
|
15
15
|
/**
|
|
16
16
|
* Processes a built-in 'local' function call.
|
|
17
17
|
*/
|
|
18
|
-
export declare function processLocal<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly
|
|
18
|
+
export declare function processLocal<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: LocalFunctionConfiguration): DataflowInformation;
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
import type { DataflowProcessorInformation } from '../../../../../processor';
|
|
2
2
|
import type { DataflowInformation } from '../../../../../info';
|
|
3
|
-
import type {
|
|
3
|
+
import type { PotentiallyEmptyRArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
4
4
|
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
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 { BrandedIdentifier } from '../../../../../environments/identifier';
|
|
7
8
|
/**
|
|
8
|
-
*
|
|
9
|
+
* Configuration options for the basic R pipe
|
|
9
10
|
*/
|
|
10
|
-
|
|
11
|
+
interface PipeConfiguration {
|
|
12
|
+
pipePlaceholderName: BrandedIdentifier;
|
|
13
|
+
/**
|
|
14
|
+
* this is for a pipe like `%<>%` which assigns its lhs
|
|
15
|
+
*/
|
|
16
|
+
assignLhs: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Whether to return the lhs (e.g., with the TPipe)
|
|
19
|
+
*/
|
|
20
|
+
returnLhs: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* If so, also allow a symbol instead of a function as rhs, if it is the case, this automatically converts the symbol on the rhs to a function call
|
|
23
|
+
*/
|
|
24
|
+
rhsMightBeSymbol?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Support for R's pipe functions like `|>` or magrittr's `%>%`
|
|
28
|
+
*/
|
|
29
|
+
export declare function processPipe<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, { pipePlaceholderName, assignLhs, returnLhs, rhsMightBeSymbol }: PipeConfiguration): DataflowInformation;
|
|
30
|
+
export {};
|
|
@@ -4,41 +4,109 @@ exports.processPipe = processPipe;
|
|
|
4
4
|
const known_call_handling_1 = require("../known-call-handling");
|
|
5
5
|
const assert_1 = require("../../../../../../util/assert");
|
|
6
6
|
const unpack_argument_1 = require("../argument/unpack-argument");
|
|
7
|
+
const model_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/model");
|
|
7
8
|
const logger_1 = require("../../../../../logger");
|
|
8
9
|
const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
|
|
9
10
|
const vertex_1 = require("../../../../../graph/vertex");
|
|
10
11
|
const edge_1 = require("../../../../../graph/edge");
|
|
11
12
|
const identifier_1 = require("../../../../../environments/identifier");
|
|
13
|
+
const make_argument_1 = require("../argument/make-argument");
|
|
14
|
+
const built_in_assignment_1 = require("./built-in-assignment");
|
|
12
15
|
const built_in_proc_name_1 = require("../../../../../environments/built-in-proc-name");
|
|
16
|
+
const log_1 = require("../../../../../../util/log");
|
|
13
17
|
/**
|
|
14
|
-
*
|
|
18
|
+
* Support for R's pipe functions like `|>` or magrittr's `%>%`
|
|
15
19
|
*/
|
|
16
|
-
function processPipe(name, args, rootId, data) {
|
|
17
|
-
const
|
|
20
|
+
function processPipe(name, args, rootId, data, { pipePlaceholderName, assignLhs, returnLhs, rhsMightBeSymbol = false }) {
|
|
21
|
+
const fCallInfo = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: built_in_proc_name_1.BuiltInProcName.Pipe });
|
|
22
|
+
const processedArguments = fCallInfo.processedArguments;
|
|
23
|
+
let information = fCallInfo.information;
|
|
18
24
|
if (args.length !== 2) {
|
|
19
25
|
logger_1.dataflowLogger.warn(`Pipe ${identifier_1.Identifier.toString(name.content)} has something else than 2 arguments, skipping`);
|
|
20
26
|
return information;
|
|
21
27
|
}
|
|
22
28
|
const [lhs, rhs] = args.map(e => (0, unpack_argument_1.unpackNonameArg)(e));
|
|
23
29
|
(0, assert_1.guard)(lhs !== undefined && rhs !== undefined, () => `lhs and rhs must be present, but ${JSON.stringify(lhs)} and ${JSON.stringify(rhs)} were found instead.`);
|
|
24
|
-
|
|
30
|
+
// If this is an assigning pipe (e.g., %<>%), perform the assignment writeback using the built-in
|
|
31
|
+
// assignment processor: target <- source where target is the original lhs and source is the rhs call
|
|
32
|
+
if (assignLhs) {
|
|
33
|
+
// create unnamed args for target and source
|
|
34
|
+
const targetArg = (0, make_argument_1.toUnnamedArgument)(lhs, data.completeAst.idMap);
|
|
35
|
+
const sourceArg = (0, make_argument_1.toUnnamedArgument)(rhs, data.completeAst.idMap);
|
|
36
|
+
// construct a synthetic symbol for the assignment operator '<-'
|
|
37
|
+
const assignSym = {
|
|
38
|
+
type: type_1.RType.Symbol,
|
|
39
|
+
info: name.info,
|
|
40
|
+
content: identifier_1.Identifier.make('<-', 'base'),
|
|
41
|
+
lexeme: '<-',
|
|
42
|
+
location: name.location
|
|
43
|
+
};
|
|
44
|
+
information = (0, built_in_assignment_1.processAssignment)(assignSym, [targetArg, sourceArg], rootId, data, { canBeReplacement: true, mayHaveMoreArgs: true });
|
|
45
|
+
}
|
|
46
|
+
let treatedAsFunctionCall = false;
|
|
47
|
+
if (rhs.type === type_1.RType.Symbol && rhsMightBeSymbol) {
|
|
48
|
+
// convert a plain symbol on the RHS into a function-call vertex so we can treat it like `df %>% head`
|
|
49
|
+
const maybeVertex = information.graph.getVertex(rhs.info.id);
|
|
50
|
+
if (maybeVertex && maybeVertex.tag === vertex_1.VertexType.Use) {
|
|
51
|
+
information.graph.updateToFunctionCall({
|
|
52
|
+
tag: vertex_1.VertexType.FunctionCall,
|
|
53
|
+
id: rhs.info.id,
|
|
54
|
+
name: rhs.content,
|
|
55
|
+
args: [],
|
|
56
|
+
environment: data.environment,
|
|
57
|
+
onlyBuiltin: false,
|
|
58
|
+
cds: data.cds,
|
|
59
|
+
origin: [built_in_proc_name_1.BuiltInProcName.Function]
|
|
60
|
+
});
|
|
61
|
+
treatedAsFunctionCall = true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (treatedAsFunctionCall || rhs.type === type_1.RType.FunctionCall) {
|
|
25
65
|
const functionCallNode = information.graph.getVertex(rhs.info.id);
|
|
26
66
|
(0, assert_1.guard)(functionCallNode?.tag === vertex_1.VertexType.FunctionCall, () => `Expected function call node with id ${rhs.info.id} to be a function call node, but got ${functionCallNode?.tag} instead.`);
|
|
27
|
-
// make the lhs an argument node:
|
|
67
|
+
// make the lhs an argument node (or link it to placeholders within the rhs call):
|
|
28
68
|
const argId = lhs.info.id;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
69
|
+
// find all symbol occurrences inside the rhs function call AST that match the placeholder name
|
|
70
|
+
const occurrenceIds = [];
|
|
71
|
+
model_1.RNode.visitAst(rhs, (node) => {
|
|
72
|
+
if (node.type === type_1.RType.Symbol && node.content === pipePlaceholderName) {
|
|
73
|
+
occurrenceIds.push(node.info.id);
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
35
76
|
});
|
|
36
|
-
|
|
77
|
+
if (occurrenceIds.length > 0) {
|
|
78
|
+
if (occurrenceIds.length !== 1) {
|
|
79
|
+
log_1.log.warn(`Expected exactly one occurrence of the pipe placeholder '${identifier_1.Identifier.toString(pipePlaceholderName)}' in the rhs of the pipe, but found ${occurrenceIds.length}. Linking all occurrences to the lhs.`);
|
|
80
|
+
}
|
|
81
|
+
for (const occId of occurrenceIds) {
|
|
82
|
+
information.graph.addEdge(occId, argId, edge_1.EdgeType.Reads);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
logger_1.dataflowLogger.trace(`Linking pipe arg ${argId} as first argument of ${rhs.info.id}`);
|
|
87
|
+
functionCallNode.args.unshift({
|
|
88
|
+
name: undefined,
|
|
89
|
+
nodeId: argId,
|
|
90
|
+
cds: data.cds,
|
|
91
|
+
type: identifier_1.ReferenceType.Function
|
|
92
|
+
});
|
|
93
|
+
information.graph.addEdge(functionCallNode.id, argId, edge_1.EdgeType.Argument | edge_1.EdgeType.Reads);
|
|
94
|
+
}
|
|
37
95
|
}
|
|
38
96
|
else {
|
|
39
97
|
logger_1.dataflowLogger.warn(`Expected rhs of pipe to be a function call, but got ${rhs.type} instead.`);
|
|
40
98
|
}
|
|
41
99
|
const firstArgument = processedArguments[0];
|
|
100
|
+
// If requested, return the lhs value (tee/TPipe semantics): add a Returns edge to the lhs entry
|
|
101
|
+
if (firstArgument && returnLhs) {
|
|
102
|
+
information.graph.addEdge(rootId, firstArgument.entryPoint, edge_1.EdgeType.Returns);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const secondArgument = processedArguments[1];
|
|
106
|
+
if (secondArgument && !returnLhs) {
|
|
107
|
+
information.graph.addEdge(rootId, secondArgument.entryPoint, edge_1.EdgeType.Returns);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
42
110
|
const uniqueIn = information.in.slice();
|
|
43
111
|
for (const ing of (firstArgument?.in ?? [])) {
|
|
44
112
|
if (!uniqueIn.some(e => e.nodeId === ing.nodeId)) {
|