@eagleoutice/flowr 2.2.12 → 2.2.14
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 +82 -20
- package/benchmark/slicer.js +2 -2
- package/benchmark/summarizer/first-phase/input.js +1 -1
- package/benchmark/summarizer/first-phase/process.js +3 -3
- package/benchmark/summarizer/second-phase/process.js +1 -1
- package/benchmark/summarizer/summarizer.js +1 -1
- package/cli/common/options.js +4 -4
- package/cli/common/script.js +1 -1
- package/cli/flowr.js +1 -1
- package/cli/repl/commands/repl-cfg.d.ts +2 -0
- package/cli/repl/commands/repl-cfg.js +38 -24
- package/cli/repl/commands/repl-commands.js +4 -2
- package/cli/repl/commands/repl-dataflow.js +3 -3
- package/cli/repl/commands/repl-execute.js +1 -1
- package/cli/repl/commands/repl-main.d.ts +1 -1
- package/cli/repl/commands/repl-main.js +1 -1
- package/cli/repl/commands/repl-normalize.js +1 -1
- package/cli/repl/commands/repl-query.js +2 -2
- package/cli/repl/core.js +1 -1
- package/cli/repl/prompt.js +1 -1
- package/cli/repl/server/connection.js +4 -4
- package/cli/repl/server/messages/message-analysis.d.ts +1 -1
- package/cli/script-core/statistics-core.js +1 -1
- package/cli/script-core/statistics-helper-core.js +4 -4
- package/config.d.ts +47 -24
- package/config.js +3 -3
- package/control-flow/basic-cfg-guided-visitor.d.ts +39 -0
- package/control-flow/basic-cfg-guided-visitor.js +114 -0
- package/control-flow/cfg-properties.d.ts +26 -0
- package/control-flow/cfg-properties.js +100 -0
- package/control-flow/cfg-simplification.d.ts +18 -0
- package/control-flow/cfg-simplification.js +55 -0
- package/control-flow/cfg-to-basic-blocks.d.ts +5 -0
- package/control-flow/cfg-to-basic-blocks.js +81 -0
- package/control-flow/control-flow-graph.d.ts +247 -0
- package/control-flow/control-flow-graph.js +290 -0
- package/control-flow/dfg-cfg-guided-visitor.d.ts +32 -0
- package/control-flow/dfg-cfg-guided-visitor.js +71 -0
- package/control-flow/diff-cfg.d.ts +11 -0
- package/control-flow/diff-cfg.js +161 -0
- package/control-flow/extract-cfg.d.ts +30 -0
- package/control-flow/extract-cfg.js +475 -0
- package/control-flow/happens-before.d.ts +7 -0
- package/{util/cfg → control-flow}/happens-before.js +3 -3
- package/control-flow/semantic-cfg-guided-visitor.d.ts +452 -0
- package/control-flow/semantic-cfg-guided-visitor.js +492 -0
- package/control-flow/simple-visitor.d.ts +25 -0
- package/control-flow/simple-visitor.js +80 -0
- package/control-flow/syntax-cfg-guided-visitor.d.ts +128 -0
- package/control-flow/syntax-cfg-guided-visitor.js +166 -0
- package/core/print/print.d.ts +1 -1
- package/core/print/slice-diff-ansi.js +1 -1
- package/core/steps/pipeline/create-pipeline.js +1 -1
- package/dataflow/environments/built-in-config.js +9 -6
- package/dataflow/environments/built-in.d.ts +8 -4
- package/dataflow/environments/built-in.js +47 -5
- package/dataflow/environments/default-builtin-config.d.ts +2 -0
- package/dataflow/environments/default-builtin-config.js +81 -14
- package/dataflow/environments/resolve-by-name.js +15 -4
- package/dataflow/extractor.js +2 -2
- package/dataflow/graph/dataflowgraph-builder.d.ts +3 -1
- package/dataflow/graph/dataflowgraph-builder.js +4 -2
- package/dataflow/graph/diff-dataflow-graph.d.ts +16 -0
- package/dataflow/graph/{diff.js → diff-dataflow-graph.js} +30 -56
- package/dataflow/graph/graph.d.ts +11 -3
- package/dataflow/graph/graph.js +27 -12
- package/dataflow/graph/vertex.d.ts +17 -2
- package/dataflow/internal/linker.d.ts +3 -2
- package/dataflow/internal/linker.js +33 -24
- package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +1 -1
- package/dataflow/internal/process/functions/call/argument/unpack-argument.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +12 -9
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +84 -16
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +23 -16
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +9 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +3 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +15 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-get.js +4 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +4 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-library.js +4 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-list.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +9 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +3 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +1 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +19 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +19 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.js +4 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +3 -3
- package/dataflow/internal/process/functions/call/common.d.ts +4 -1
- package/dataflow/internal/process/functions/call/common.js +5 -3
- package/dataflow/internal/process/functions/call/known-call-handling.d.ts +3 -2
- package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
- package/dataflow/internal/process/functions/call/named-call-handling.js +1 -1
- package/dataflow/internal/process/functions/call/unnamed-call-handling.d.ts +1 -0
- package/dataflow/internal/process/functions/call/unnamed-call-handling.js +6 -4
- package/dataflow/internal/process/process-named-call.d.ts +1 -1
- package/dataflow/internal/process/process-named-call.js +5 -5
- package/dataflow/origin/dfg-get-origin.d.ts +82 -0
- package/dataflow/origin/dfg-get-origin.js +116 -0
- package/documentation/doc-util/doc-cfg.d.ts +13 -6
- package/documentation/doc-util/doc-cfg.js +20 -15
- package/documentation/doc-util/doc-cli-option.js +4 -2
- package/documentation/doc-util/doc-dfg.js +3 -3
- package/documentation/doc-util/doc-escape.d.ts +7 -0
- package/documentation/doc-util/doc-escape.js +19 -0
- package/documentation/doc-util/doc-files.d.ts +1 -0
- package/documentation/doc-util/doc-files.js +2 -1
- package/documentation/doc-util/doc-normalized-ast.js +3 -3
- package/documentation/doc-util/doc-query.js +2 -2
- package/documentation/doc-util/doc-repl.js +1 -1
- package/documentation/doc-util/doc-search.js +1 -1
- package/documentation/doc-util/doc-server-message.js +2 -2
- package/documentation/doc-util/doc-structure.d.ts +1 -0
- package/documentation/doc-util/doc-structure.js +5 -0
- package/documentation/doc-util/doc-types.d.ts +7 -1
- package/documentation/doc-util/doc-types.js +13 -2
- package/documentation/print-capabilities-markdown.js +27 -1
- package/documentation/print-cfg-wiki.js +508 -20
- package/documentation/print-dataflow-graph-wiki.js +180 -25
- package/documentation/print-engines-wiki.js +1 -1
- package/documentation/print-faq-wiki.d.ts +1 -0
- package/documentation/print-faq-wiki.js +75 -0
- package/documentation/print-interface-wiki.js +1 -1
- package/documentation/print-linter-wiki.d.ts +1 -0
- package/documentation/print-linter-wiki.js +76 -0
- package/documentation/print-linting-and-testing-wiki.js +52 -36
- package/documentation/print-normalized-ast-wiki.js +1 -1
- package/documentation/print-onboarding-wiki.d.ts +1 -0
- package/documentation/print-onboarding-wiki.js +42 -0
- package/documentation/print-query-wiki.js +21 -1
- package/documentation/print-readme.js +10 -3
- package/linter/linter-executor.d.ts +9 -0
- package/linter/linter-executor.js +26 -0
- package/linter/linter-format.d.ts +65 -0
- package/linter/linter-format.js +9 -0
- package/linter/linter-rules.d.ts +42 -0
- package/linter/linter-rules.js +14 -0
- package/linter/rules/1-deprecated-functions.d.ts +34 -0
- package/linter/rules/1-deprecated-functions.js +54 -0
- package/linter/rules/2-file-path-validity.d.ts +48 -0
- package/linter/rules/2-file-path-validity.js +93 -0
- package/package.json +10 -6
- package/queries/catalog/call-context-query/call-context-query-executor.js +5 -5
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +3 -3
- package/queries/catalog/call-context-query/call-context-query-format.js +7 -3
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +2 -2
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +24 -21
- package/queries/catalog/cluster-query/cluster-query-format.d.ts +3 -1
- package/queries/catalog/cluster-query/cluster-query-format.js +6 -2
- package/queries/catalog/config-query/config-query-format.d.ts +2 -1
- package/queries/catalog/config-query/config-query-format.js +4 -3
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +2 -1
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +4 -3
- package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +3 -1
- package/queries/catalog/dataflow-query/dataflow-query-format.js +11 -3
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -2
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +2 -1
- package/queries/catalog/dependencies-query/dependencies-query-format.js +12 -3
- package/queries/catalog/happens-before-query/happens-before-query-executor.d.ts +1 -1
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +4 -4
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +2 -1
- package/queries/catalog/happens-before-query/happens-before-query-format.js +4 -3
- package/queries/catalog/id-map-query/id-map-query-format.d.ts +2 -1
- package/queries/catalog/id-map-query/id-map-query-format.js +4 -3
- package/queries/catalog/lineage-query/lineage-query-format.d.ts +2 -1
- package/queries/catalog/lineage-query/lineage-query-format.js +7 -3
- package/queries/catalog/linter-query/linter-query-executor.d.ts +3 -0
- package/queries/catalog/linter-query/linter-query-executor.js +28 -0
- package/queries/catalog/linter-query/linter-query-format.d.ts +80 -0
- package/queries/catalog/linter-query/linter-query-format.js +43 -0
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +2 -1
- package/queries/catalog/location-map-query/location-map-query-format.js +4 -3
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +2 -1
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +4 -3
- package/queries/catalog/origin-query/origin-query-executor.d.ts +5 -0
- package/queries/catalog/origin-query/origin-query-executor.js +33 -0
- package/queries/catalog/origin-query/origin-query-format.d.ts +73 -0
- package/queries/catalog/origin-query/origin-query-format.js +31 -0
- package/queries/catalog/project-query/project-query-executor.js +1 -1
- package/queries/catalog/project-query/project-query-format.d.ts +2 -1
- package/queries/catalog/project-query/project-query-format.js +4 -3
- package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +2 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-format.js +4 -3
- package/queries/catalog/search-query/search-query-format.d.ts +2 -1
- package/queries/catalog/search-query/search-query-format.js +7 -3
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +3 -1
- package/queries/catalog/static-slice-query/static-slice-query-format.js +11 -3
- package/queries/query-print.d.ts +1 -1
- package/queries/query-print.js +4 -4
- package/queries/query.d.ts +143 -2
- package/queries/query.js +5 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +3 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +5 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +3 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +5 -0
- package/r-bridge/lang-4.x/ast/model/processing/decorate.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/decorate.js +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/fold.js +3 -1
- package/r-bridge/lang-4.x/ast/model/processing/stateful-fold.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/expression/normalize-expression.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-argument.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-call.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-definition.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/normalize-access.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/operators/normalize-binary.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/structure/normalize-root.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/values/normalize-symbol.js +1 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +2 -2
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +26 -8
- package/r-bridge/retriever.js +2 -2
- package/search/flowr-search-builder.d.ts +31 -2
- package/search/flowr-search-builder.js +30 -0
- package/search/flowr-search.d.ts +7 -1
- package/search/search-executor/search-enrichers.d.ts +73 -0
- package/search/search-executor/search-enrichers.js +98 -0
- package/search/search-executor/search-generators.d.ts +7 -2
- package/search/search-executor/search-generators.js +21 -1
- package/search/search-executor/search-mappers.d.ts +19 -0
- package/search/search-executor/search-mappers.js +21 -0
- package/search/search-executor/search-transformer.d.ts +13 -1
- package/search/search-executor/search-transformer.js +11 -1
- package/slicing/criterion/collect-all.js +1 -1
- package/slicing/static/slice-call.js +13 -3
- package/statistics/features/supported/assignments/post-process.js +1 -1
- package/statistics/features/supported/defined-functions/post-process.js +2 -2
- package/statistics/features/supported/used-functions/post-process.js +1 -1
- package/statistics/features/supported/used-packages/post-process.js +2 -2
- package/statistics/features/supported/values/post-process.js +2 -2
- package/statistics/output/print-stats.js +2 -2
- package/statistics/summarizer/post-process/clusterer.d.ts +1 -1
- package/statistics/summarizer/post-process/clusterer.js +1 -1
- package/statistics/summarizer/post-process/histogram.js +3 -3
- package/statistics/summarizer/post-process/post-process-output.js +3 -3
- package/statistics/summarizer/second-phase/process.js +2 -2
- package/statistics/summarizer/summarizer.js +2 -2
- package/util/assert.js +36 -1
- package/util/cfg/cfg.d.ts +0 -80
- package/util/cfg/cfg.js +0 -549
- package/util/{arrays.d.ts → collections/arrays.d.ts} +1 -1
- package/util/{arrays.js → collections/arrays.js} +3 -3
- package/util/collections/set.js +17 -0
- package/util/diff-graph.d.ts +47 -0
- package/util/diff-graph.js +61 -0
- package/util/diff.d.ts +6 -6
- package/util/diff.js +1 -1
- package/util/mermaid/cfg.d.ts +9 -2
- package/util/mermaid/cfg.js +64 -12
- package/util/mermaid/dfg.d.ts +2 -1
- package/util/mermaid/dfg.js +26 -10
- package/util/mermaid/mermaid.d.ts +2 -0
- package/util/mermaid/mermaid.js +6 -0
- package/util/quads.js +1 -1
- package/util/schema.d.ts +1 -1
- package/util/schema.js +1 -1
- package/util/summarizer.js +1 -1
- package/util/{text.js → text/text.js} +1 -1
- package/util/{time.js → text/time.js} +1 -1
- package/util/version.js +1 -1
- package/dataflow/graph/diff.d.ts +0 -36
- package/util/cfg/happens-before.d.ts +0 -7
- package/util/cfg/visitor.d.ts +0 -9
- package/util/cfg/visitor.js +0 -30
- package/util/set.js +0 -31
- /package/util/{bimap.d.ts → collections/bimap.d.ts} +0 -0
- /package/util/{bimap.js → collections/bimap.js} +0 -0
- /package/util/{defaultmap.d.ts → collections/defaultmap.d.ts} +0 -0
- /package/util/{defaultmap.js → collections/defaultmap.js} +0 -0
- /package/util/{set.d.ts → collections/set.d.ts} +0 -0
- /package/util/{ansi.d.ts → text/ansi.d.ts} +0 -0
- /package/util/{ansi.js → text/ansi.js} +0 -0
- /package/util/{args.d.ts → text/args.d.ts} +0 -0
- /package/util/{args.js → text/args.js} +0 -0
- /package/util/{strings.d.ts → text/strings.d.ts} +0 -0
- /package/util/{strings.js → text/strings.js} +0 -0
- /package/util/{text.d.ts → text/text.d.ts} +0 -0
- /package/util/{time.d.ts → text/time.d.ts} +0 -0
|
@@ -3,6 +3,7 @@ import type { DataflowFunctionFlowInformation, FunctionArgument } from './graph'
|
|
|
3
3
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
4
4
|
import type { REnvironmentInformation } from '../environments/environment';
|
|
5
5
|
import type { ControlDependency } from '../info';
|
|
6
|
+
import type { BuiltInMappingName } from '../environments/built-in';
|
|
6
7
|
export declare enum VertexType {
|
|
7
8
|
Value = "value",
|
|
8
9
|
Use = "use",
|
|
@@ -135,6 +136,14 @@ interface DataflowGraphVertexBase extends MergeableRecord {
|
|
|
135
136
|
* this attribute links a vertex to indices (pointer links) it may be affected by or related to
|
|
136
137
|
*/
|
|
137
138
|
indicesCollection?: ContainerIndicesCollection;
|
|
139
|
+
/**
|
|
140
|
+
* Describes the collection of AST vertices that contributed to this vertex.
|
|
141
|
+
* For example, this is useful with replacement operators, telling you which assignment operator caused them
|
|
142
|
+
*/
|
|
143
|
+
link?: DataflowGraphVertexAstLink;
|
|
144
|
+
}
|
|
145
|
+
export interface DataflowGraphVertexAstLink {
|
|
146
|
+
origin: NodeId[];
|
|
138
147
|
}
|
|
139
148
|
/**
|
|
140
149
|
* Marker vertex for a value in the dataflow of the program.
|
|
@@ -173,7 +182,9 @@ export interface DataflowGraphVertexUse extends DataflowGraphVertexBase {
|
|
|
173
182
|
readonly environment?: undefined;
|
|
174
183
|
}
|
|
175
184
|
/**
|
|
176
|
-
* Arguments required to construct a vertex which represents the
|
|
185
|
+
* Arguments required to construct a vertex which represents the call to a function in the {@link DataflowGraph|dataflow graph}.
|
|
186
|
+
* This describes all kinds of function calls, including calls to built-ins and control-flow structures such as `if` or `for` (they are
|
|
187
|
+
* treated as function calls in R).
|
|
177
188
|
*
|
|
178
189
|
* @see {@link isFunctionCallVertex} - to check if a vertex is a function call vertex
|
|
179
190
|
*/
|
|
@@ -186,13 +197,17 @@ export interface DataflowGraphVertexFunctionCall extends DataflowGraphVertexBase
|
|
|
186
197
|
* have the compound name (e.g., `[<-`).
|
|
187
198
|
*/
|
|
188
199
|
readonly name: string;
|
|
189
|
-
/** The arguments of the function call, in order (as they are passed to the respective call if executed in R. */
|
|
200
|
+
/** The arguments of the function call, in order (as they are passed to the respective call if executed in R). */
|
|
190
201
|
args: FunctionArgument[];
|
|
191
202
|
/** a performance flag to indicate that the respective call is _only_ calling a builtin function without any df graph attached */
|
|
192
203
|
onlyBuiltin: boolean;
|
|
193
204
|
/** The environment attached to the call (if such an attachment is necessary, e.g., because it represents the calling closure */
|
|
194
205
|
environment: REnvironmentInformation | undefined;
|
|
206
|
+
/** More detailed Information on this function call */
|
|
207
|
+
origin: FunctionOriginInformation[] | 'unnamed';
|
|
195
208
|
}
|
|
209
|
+
/** Describes the processor responsible for a function call */
|
|
210
|
+
export type FunctionOriginInformation = BuiltInMappingName | string;
|
|
196
211
|
/**
|
|
197
212
|
* Arguments required to construct a vertex which represents the definition of a variable in the {@link DataflowGraph|dataflow graph}.
|
|
198
213
|
*
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { DefaultMap } from '../../util/defaultmap';
|
|
1
|
+
import { DefaultMap } from '../../util/collections/defaultmap';
|
|
2
2
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
3
3
|
import type { IdentifierReference } from '../environments/identifier';
|
|
4
4
|
import type { DataflowGraph, FunctionArgument } from '../graph/graph';
|
|
5
5
|
import type { RParameter } from '../../r-bridge/lang-4.x/ast/model/nodes/r-parameter';
|
|
6
6
|
import type { AstIdMap, ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
7
7
|
import type { DataflowGraphVertexFunctionCall, DataflowGraphVertexFunctionDefinition, DataflowGraphVertexInfo } from '../graph/vertex';
|
|
8
|
+
import type { BuiltIn } from '../environments/built-in';
|
|
8
9
|
import type { REnvironmentInformation } from '../environments/environment';
|
|
9
10
|
export type NameIdMap = DefaultMap<string, IdentifierReference[]>;
|
|
10
11
|
export declare function findNonLocalReads(graph: DataflowGraph, ignore: readonly IdentifierReference[]): IdentifierReference[];
|
|
@@ -27,7 +28,7 @@ export declare function linkFunctionCalls(graph: DataflowGraph, idMap: AstIdMap,
|
|
|
27
28
|
* convenience function returning all known call targets, as well as the name source which defines them
|
|
28
29
|
*/
|
|
29
30
|
export declare function getAllFunctionCallTargets(call: NodeId, graph: DataflowGraph, environment?: REnvironmentInformation): NodeId[];
|
|
30
|
-
export declare function getAllLinkedFunctionDefinitions(functionDefinitionReadIds: ReadonlySet<NodeId>, dataflowGraph: DataflowGraph): Set<DataflowGraphVertexInfo
|
|
31
|
+
export declare function getAllLinkedFunctionDefinitions(functionDefinitionReadIds: ReadonlySet<NodeId>, dataflowGraph: DataflowGraph): [Set<DataflowGraphVertexInfo>, Set<BuiltIn>];
|
|
31
32
|
/**
|
|
32
33
|
* This method links a set of read variables to definitions in an environment.
|
|
33
34
|
*
|
|
@@ -9,7 +9,7 @@ exports.getAllFunctionCallTargets = getAllFunctionCallTargets;
|
|
|
9
9
|
exports.getAllLinkedFunctionDefinitions = getAllLinkedFunctionDefinitions;
|
|
10
10
|
exports.linkInputs = linkInputs;
|
|
11
11
|
exports.linkCircularRedefinitionsWithinALoop = linkCircularRedefinitionsWithinALoop;
|
|
12
|
-
const defaultmap_1 = require("../../util/defaultmap");
|
|
12
|
+
const defaultmap_1 = require("../../util/collections/defaultmap");
|
|
13
13
|
const assert_1 = require("../../util/assert");
|
|
14
14
|
const log_1 = require("../../util/log");
|
|
15
15
|
const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
|
|
@@ -22,7 +22,6 @@ const type_1 = require("../../r-bridge/lang-4.x/ast/model/type");
|
|
|
22
22
|
const vertex_1 = require("../graph/vertex");
|
|
23
23
|
const resolve_by_name_1 = require("../environments/resolve-by-name");
|
|
24
24
|
const built_in_1 = require("../environments/built-in");
|
|
25
|
-
const static_slicer_1 = require("../../slicing/static/static-slicer");
|
|
26
25
|
const prefix_1 = require("../../util/prefix");
|
|
27
26
|
function findNonLocalReads(graph, ignore) {
|
|
28
27
|
const ignores = new Set(ignore.map(i => i.nodeId));
|
|
@@ -75,7 +74,7 @@ function produceNameSharedIdMap(references) {
|
|
|
75
74
|
}
|
|
76
75
|
function linkArgumentsOnCall(args, params, graph) {
|
|
77
76
|
const nameArgMap = new Map(args.filter(graph_1.isNamedArgument).map(a => [a.name, a]));
|
|
78
|
-
const nameParamMap = new Map(params.map(p => [p.name.content, p]));
|
|
77
|
+
const nameParamMap = new Map(params.filter(p => p !== undefined && p.name !== undefined && p.name.content !== undefined).map(p => [p.name.content, p]));
|
|
79
78
|
const specialDotParameter = params.find(p => p.special);
|
|
80
79
|
// all parameters matched by name
|
|
81
80
|
const matchedParameters = new Set();
|
|
@@ -83,19 +82,19 @@ function linkArgumentsOnCall(args, params, graph) {
|
|
|
83
82
|
for (const [name, arg] of nameArgMap) {
|
|
84
83
|
const pmatchName = (0, prefix_1.findByPrefixIfUnique)(name, [...nameParamMap.keys()]) ?? name;
|
|
85
84
|
const param = nameParamMap.get(pmatchName);
|
|
86
|
-
if (param !== undefined) {
|
|
85
|
+
if (param !== undefined && param.name) {
|
|
87
86
|
logger_1.dataflowLogger.trace(`mapping named argument "${name}" to parameter "${param.name.content}"`);
|
|
88
87
|
graph.addEdge(arg.nodeId, param.name.info.id, edge_1.EdgeType.DefinesOnCall);
|
|
89
88
|
graph.addEdge(param.name.info.id, arg.nodeId, edge_1.EdgeType.DefinedByOnCall);
|
|
90
89
|
matchedParameters.add(name);
|
|
91
90
|
}
|
|
92
|
-
else if (specialDotParameter !== undefined) {
|
|
91
|
+
else if (specialDotParameter !== undefined && specialDotParameter.name) {
|
|
93
92
|
logger_1.dataflowLogger.trace(`mapping named argument "${name}" to dot-dot-dot parameter`);
|
|
94
93
|
graph.addEdge(arg.nodeId, specialDotParameter.name.info.id, edge_1.EdgeType.DefinesOnCall);
|
|
95
94
|
graph.addEdge(specialDotParameter.name.info.id, arg.nodeId, edge_1.EdgeType.DefinedByOnCall);
|
|
96
95
|
}
|
|
97
96
|
}
|
|
98
|
-
const remainingParameter = params.filter(p => !matchedParameters.has(p.name.content));
|
|
97
|
+
const remainingParameter = params.filter(p => !p || !p.name || !matchedParameters.has(p.name.content));
|
|
99
98
|
const remainingArguments = args.filter(a => !(0, graph_1.isNamedArgument)(a));
|
|
100
99
|
for (let i = 0; i < remainingArguments.length; i++) {
|
|
101
100
|
const arg = remainingArguments[i];
|
|
@@ -115,9 +114,11 @@ function linkArgumentsOnCall(args, params, graph) {
|
|
|
115
114
|
continue;
|
|
116
115
|
}
|
|
117
116
|
const param = remainingParameter[i];
|
|
118
|
-
logger_1.dataflowLogger.trace(`mapping unnamed argument ${i} (id: ${arg.nodeId}) to parameter "${param.name
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
logger_1.dataflowLogger.trace(`mapping unnamed argument ${i} (id: ${arg.nodeId}) to parameter "${param.name?.content ?? '??'}"`);
|
|
118
|
+
if (param.name) {
|
|
119
|
+
graph.addEdge(arg.nodeId, param.name.info.id, edge_1.EdgeType.DefinesOnCall);
|
|
120
|
+
graph.addEdge(param.name.info.id, arg.nodeId, edge_1.EdgeType.DefinedByOnCall);
|
|
121
|
+
}
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
function linkFunctionCallArguments(targetId, idMap, functionCallName, functionRootId, callArgs, finalGraph) {
|
|
@@ -144,8 +145,10 @@ function linkFunctionCallWithSingleTarget(graph, def, info, idMap) {
|
|
|
144
145
|
continue;
|
|
145
146
|
}
|
|
146
147
|
for (const def of defs) {
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
if (!(0, built_in_1.isBuiltIn)(def.nodeId)) {
|
|
149
|
+
graph.addEdge(ingoing, def, edge_1.EdgeType.DefinedByOnCall);
|
|
150
|
+
graph.addEdge(id, def, edge_1.EdgeType.DefinesOnCall);
|
|
151
|
+
}
|
|
149
152
|
}
|
|
150
153
|
}
|
|
151
154
|
}
|
|
@@ -168,7 +171,7 @@ function linkFunctionCall(graph, id, info, idMap, thisGraph, calledFunctionDefin
|
|
|
168
171
|
const readBits = edge_1.EdgeType.Reads | edge_1.EdgeType.Calls;
|
|
169
172
|
const functionDefinitionReadIds = [...edges].filter(([_, e]) => (0, edge_1.edgeDoesNotIncludeType)(e.types, edge_1.EdgeType.Argument)
|
|
170
173
|
&& (0, edge_1.edgeIncludesType)(e.types, readBits)).map(([target, _]) => target);
|
|
171
|
-
const functionDefs = getAllLinkedFunctionDefinitions(new Set(functionDefinitionReadIds), graph);
|
|
174
|
+
const functionDefs = getAllLinkedFunctionDefinitions(new Set(functionDefinitionReadIds), graph)[0];
|
|
172
175
|
for (const def of functionDefs.values()) {
|
|
173
176
|
(0, assert_1.guard)(def.tag === vertex_1.VertexType.FunctionDefinition, () => `expected function definition, but got ${def.tag}`);
|
|
174
177
|
linkFunctionCallWithSingleTarget(graph, def, info, idMap);
|
|
@@ -198,7 +201,7 @@ function linkFunctionCalls(graph, idMap, thisGraph) {
|
|
|
198
201
|
* convenience function returning all known call targets, as well as the name source which defines them
|
|
199
202
|
*/
|
|
200
203
|
function getAllFunctionCallTargets(call, graph, environment) {
|
|
201
|
-
|
|
204
|
+
let found = [];
|
|
202
205
|
const callVertex = graph.get(call, true);
|
|
203
206
|
if (callVertex === undefined) {
|
|
204
207
|
return [];
|
|
@@ -214,29 +217,28 @@ function getAllFunctionCallTargets(call, graph, environment) {
|
|
|
214
217
|
functionCallDefs.push(target);
|
|
215
218
|
}
|
|
216
219
|
}
|
|
217
|
-
const functionCallTargets = getAllLinkedFunctionDefinitions(new Set(functionCallDefs), graph);
|
|
220
|
+
const [functionCallTargets, builtInTargets] = getAllLinkedFunctionDefinitions(new Set(functionCallDefs), graph);
|
|
218
221
|
for (const target of functionCallTargets) {
|
|
219
222
|
found.push(target.id);
|
|
220
223
|
}
|
|
221
|
-
|
|
222
|
-
found.push(def);
|
|
223
|
-
}
|
|
224
|
+
found = found.concat(...builtInTargets, functionCallDefs);
|
|
224
225
|
}
|
|
225
226
|
return found;
|
|
226
227
|
}
|
|
227
228
|
function getAllLinkedFunctionDefinitions(functionDefinitionReadIds, dataflowGraph) {
|
|
228
|
-
|
|
229
|
+
let potential = [...functionDefinitionReadIds];
|
|
229
230
|
const visited = new Set();
|
|
230
231
|
const result = new Set();
|
|
232
|
+
const builtIns = new Set();
|
|
231
233
|
while (potential.length > 0) {
|
|
232
234
|
const currentId = potential.pop();
|
|
233
|
-
// do not traverse builtins
|
|
234
|
-
if (
|
|
235
|
+
// do not traverse builtins further
|
|
236
|
+
if ((0, built_in_1.isBuiltIn)(currentId)) {
|
|
237
|
+
builtIns.add(currentId);
|
|
235
238
|
continue;
|
|
236
239
|
}
|
|
237
240
|
const currentInfo = dataflowGraph.get(currentId, true);
|
|
238
241
|
if (currentInfo === undefined) {
|
|
239
|
-
static_slicer_1.slicerLogger.trace('skipping unknown link');
|
|
240
242
|
continue;
|
|
241
243
|
}
|
|
242
244
|
visited.add(currentId);
|
|
@@ -244,7 +246,7 @@ function getAllLinkedFunctionDefinitions(functionDefinitionReadIds, dataflowGrap
|
|
|
244
246
|
const returnEdges = outgoingEdges.filter(([_, e]) => (0, edge_1.edgeIncludesType)(e.types, edge_1.EdgeType.Returns));
|
|
245
247
|
if (returnEdges.length > 0) {
|
|
246
248
|
// only traverse return edges and do not follow `calls` etc. as this indicates that we have a function call which returns a result, and not the function calls itself
|
|
247
|
-
potential.
|
|
249
|
+
potential = potential.concat(...returnEdges.map(([target]) => target).filter(id => !visited.has(id)));
|
|
248
250
|
continue;
|
|
249
251
|
}
|
|
250
252
|
const followBits = edge_1.EdgeType.Reads | edge_1.EdgeType.DefinedBy | edge_1.EdgeType.DefinedByOnCall;
|
|
@@ -253,9 +255,9 @@ function getAllLinkedFunctionDefinitions(functionDefinitionReadIds, dataflowGrap
|
|
|
253
255
|
result.add(currentInfo[0]);
|
|
254
256
|
}
|
|
255
257
|
// trace all joined reads
|
|
256
|
-
potential.
|
|
258
|
+
potential = potential.concat(followEdges.map(([target]) => target).filter(id => !visited.has(id)));
|
|
257
259
|
}
|
|
258
|
-
return result;
|
|
260
|
+
return [result, builtIns];
|
|
259
261
|
}
|
|
260
262
|
/**
|
|
261
263
|
* This method links a set of read variables to definitions in an environment.
|
|
@@ -279,9 +281,16 @@ function linkInputs(referencesToLinkAgainstEnvironment, environmentInformation,
|
|
|
279
281
|
givenInputs.push(bodyInput);
|
|
280
282
|
}
|
|
281
283
|
else {
|
|
284
|
+
let allBuiltIn = true;
|
|
282
285
|
for (const target of probableTarget) {
|
|
283
286
|
// we can stick with maybe even if readId.attribute is always
|
|
284
287
|
graph.addEdge(bodyInput, target, edge_1.EdgeType.Reads);
|
|
288
|
+
if (!(0, identifier_1.isReferenceType)(target.type, identifier_1.ReferenceType.BuiltInConstant | identifier_1.ReferenceType.BuiltInFunction)) {
|
|
289
|
+
allBuiltIn = false;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (allBuiltIn) {
|
|
293
|
+
givenInputs.push(bodyInput);
|
|
285
294
|
}
|
|
286
295
|
}
|
|
287
296
|
}
|
|
@@ -3,4 +3,4 @@ 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
|
*/
|
|
6
|
-
export declare function unpackArgument<OtherInfo>(arg: RFunctionArgument<OtherInfo
|
|
6
|
+
export declare function unpackArgument<OtherInfo>(arg: RFunctionArgument<OtherInfo> | undefined, noNameOnly?: boolean): RNode<OtherInfo> | undefined;
|
|
@@ -6,6 +6,6 @@ const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model
|
|
|
6
6
|
* Retrieve the value from an argument, if it is not empty.
|
|
7
7
|
*/
|
|
8
8
|
function unpackArgument(arg, noNameOnly = true) {
|
|
9
|
-
return arg === r_function_call_1.EmptyArgument || (noNameOnly && arg.name) ? undefined : arg.value;
|
|
9
|
+
return arg === undefined || arg === r_function_call_1.EmptyArgument || (noNameOnly && arg.name) ? undefined : arg.value;
|
|
10
10
|
}
|
|
11
11
|
//# sourceMappingURL=unpack-argument.js.map
|
|
@@ -16,7 +16,7 @@ const containers_1 = require("../../../../../../util/containers");
|
|
|
16
16
|
const config_1 = require("../../../../../../config");
|
|
17
17
|
function tableAssignmentProcessor(name, args, rootId, data, outInfo) {
|
|
18
18
|
outInfo.definitionRootNodes.push(rootId);
|
|
19
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
19
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'table:assign' }).information;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
22
|
* Processes different types of access operations.
|
|
@@ -32,13 +32,13 @@ function tableAssignmentProcessor(name, args, rootId, data, outInfo) {
|
|
|
32
32
|
function processAccess(name, args, rootId, data, config) {
|
|
33
33
|
if (args.length < 2) {
|
|
34
34
|
logger_1.dataflowLogger.warn(`Access ${name.content} has less than 2 arguments, skipping`);
|
|
35
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs }).information;
|
|
35
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs, origin: 'default' }).information;
|
|
36
36
|
}
|
|
37
37
|
const head = args[0];
|
|
38
38
|
let fnCall;
|
|
39
39
|
if (head === r_function_call_1.EmptyArgument) {
|
|
40
40
|
// in this case we may be within a pipe
|
|
41
|
-
fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs });
|
|
41
|
+
fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs, origin: 'builtin:access' });
|
|
42
42
|
}
|
|
43
43
|
else if (!config.treatIndicesAsString) {
|
|
44
44
|
/* within an access operation which treats its fields, we redefine the table assignment ':=' as a trigger if this is to be treated as a definition */
|
|
@@ -97,16 +97,17 @@ function processAccess(name, args, rootId, data, config) {
|
|
|
97
97
|
function processNumberBasedAccess(data, name, args, rootId, config, head) {
|
|
98
98
|
const existing = data.environment.current.memory.get(':=');
|
|
99
99
|
const outInfo = { definitionRootNodes: [] };
|
|
100
|
+
const tableAssignId = (0, built_in_1.builtInId)(':=-table');
|
|
100
101
|
data.environment.current.memory.set(':=', [{
|
|
101
102
|
type: identifier_1.ReferenceType.BuiltInFunction,
|
|
102
|
-
definedAt:
|
|
103
|
+
definedAt: tableAssignId,
|
|
103
104
|
controlDependencies: undefined,
|
|
104
105
|
processor: (name, args, rootId, data) => tableAssignmentProcessor(name, args, rootId, data, outInfo),
|
|
105
106
|
config: {},
|
|
106
107
|
name: ':=',
|
|
107
|
-
nodeId:
|
|
108
|
+
nodeId: tableAssignId
|
|
108
109
|
}]);
|
|
109
|
-
const fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs });
|
|
110
|
+
const fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs, origin: 'builtin:access' });
|
|
110
111
|
/* recover the environment */
|
|
111
112
|
if (existing !== undefined) {
|
|
112
113
|
data.environment.current.memory.set(':=', existing);
|
|
@@ -153,7 +154,9 @@ function symbolArgumentsToStrings(args, firstIndexInclusive = 1, lastIndexInclus
|
|
|
153
154
|
*/
|
|
154
155
|
function processStringBasedAccess(args, data, name, rootId, config) {
|
|
155
156
|
const newArgs = symbolArgumentsToStrings(args);
|
|
156
|
-
const fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args: newArgs, rootId, data, forceArgs: config.forceArgs
|
|
157
|
+
const fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args: newArgs, rootId, data, forceArgs: config.forceArgs,
|
|
158
|
+
origin: 'builtin:access'
|
|
159
|
+
});
|
|
157
160
|
if ((0, config_1.getConfig)().solver.pointerTracking) {
|
|
158
161
|
referenceAccessedIndices(newArgs, data, fnCall, rootId, false);
|
|
159
162
|
}
|
|
@@ -201,8 +204,8 @@ function referenceAccessedIndices(newArgs, data, fnCall, rootId, isIndexBasedAcc
|
|
|
201
204
|
* the node with {@link parentNodeId}.
|
|
202
205
|
*
|
|
203
206
|
* @param accessedIndicesCollection - All indices that were accessed by the access operation
|
|
204
|
-
* @param fnCall
|
|
205
|
-
* @param parentNodeId
|
|
207
|
+
* @param fnCall - The {@link ProcessKnownFunctionCallResult} of the access operation
|
|
208
|
+
* @param parentNodeId - {@link NodeId} of the parent from which the edge starts
|
|
206
209
|
*/
|
|
207
210
|
function referenceIndices(accessedIndicesCollection, fnCall, parentNodeId) {
|
|
208
211
|
const accessedIndices = accessedIndicesCollection?.flatMap(indices => indices.indices);
|
|
@@ -17,4 +17,4 @@ export interface BuiltInApplyConfiguration extends MergeableRecord {
|
|
|
17
17
|
/** Should the value of the function be resolved? */
|
|
18
18
|
readonly resolveValue?: boolean;
|
|
19
19
|
}
|
|
20
|
-
export declare function processApply<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>,
|
|
20
|
+
export declare function processApply<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: BuiltInApplyConfiguration): DataflowInformation;
|
|
@@ -9,13 +9,18 @@ const vertex_1 = require("../../../../../graph/vertex");
|
|
|
9
9
|
const edge_1 = require("../../../../../graph/edge");
|
|
10
10
|
const identifier_1 = require("../../../../../environments/identifier");
|
|
11
11
|
const resolve_by_name_1 = require("../../../../../environments/resolve-by-name");
|
|
12
|
-
|
|
12
|
+
const unnamed_call_handling_1 = require("../unnamed-call-handling");
|
|
13
|
+
const log_1 = require("../../../../../../util/log");
|
|
14
|
+
function processApply(name, args, rootId, data, config) {
|
|
15
|
+
const { indexOfFunction = 1, nameOfFunctionArgument, unquoteFunction, resolveInEnvironment, resolveValue } = config;
|
|
13
16
|
/* as the length is one-based and the argument filter mapping is zero-based, we do not have to subtract 1 */
|
|
14
17
|
const forceArgsMask = new Array(indexOfFunction).fill(false);
|
|
15
18
|
forceArgsMask.push(true);
|
|
16
|
-
const
|
|
17
|
-
name, args, rootId, data, forceArgs: forceArgsMask
|
|
19
|
+
const resFn = (0, known_call_handling_1.processKnownFunctionCall)({
|
|
20
|
+
name, args, rootId, data, forceArgs: forceArgsMask, origin: 'builtin:apply'
|
|
18
21
|
});
|
|
22
|
+
let information = resFn.information;
|
|
23
|
+
const processedArguments = resFn.processedArguments;
|
|
19
24
|
let index = indexOfFunction;
|
|
20
25
|
/* search, if one of the arguments actually contains the argument name if given in the config */
|
|
21
26
|
if (nameOfFunctionArgument !== undefined) {
|
|
@@ -30,16 +35,21 @@ function processApply(name, args, rootId, data, { indexOfFunction = 1, nameOfFun
|
|
|
30
35
|
return information;
|
|
31
36
|
}
|
|
32
37
|
const arg = args[index];
|
|
33
|
-
if (arg === r_function_call_1.EmptyArgument || !arg.value || (!unquoteFunction && arg.value.type !== type_1.RType.Symbol)) {
|
|
38
|
+
if (arg === r_function_call_1.EmptyArgument || !arg.value || (!unquoteFunction && arg.value.type !== type_1.RType.Symbol && arg.value.type !== type_1.RType.FunctionDefinition)) {
|
|
34
39
|
logger_1.dataflowLogger.warn(`Expected symbol as argument at index ${index}, but got ${JSON.stringify(arg)} instead.`);
|
|
35
40
|
return information;
|
|
36
41
|
}
|
|
37
42
|
let functionId = undefined;
|
|
38
43
|
let functionName = undefined;
|
|
44
|
+
let anonymous = false;
|
|
39
45
|
const val = arg.value;
|
|
40
46
|
if (unquoteFunction && val.type === type_1.RType.String) {
|
|
41
47
|
functionId = val.info.id;
|
|
42
48
|
functionName = val.content.str;
|
|
49
|
+
information = {
|
|
50
|
+
...information,
|
|
51
|
+
in: [...information.in, { type: identifier_1.ReferenceType.Function, name: functionName, controlDependencies: data.controlDependencies, nodeId: functionId }]
|
|
52
|
+
};
|
|
43
53
|
}
|
|
44
54
|
else if (val.type === type_1.RType.Symbol) {
|
|
45
55
|
functionId = val.info.id;
|
|
@@ -53,15 +63,20 @@ function processApply(name, args, rootId, data, { indexOfFunction = 1, nameOfFun
|
|
|
53
63
|
functionName = val.content;
|
|
54
64
|
}
|
|
55
65
|
}
|
|
66
|
+
else if (val.type === type_1.RType.FunctionDefinition) {
|
|
67
|
+
anonymous = true;
|
|
68
|
+
functionId = val.info.id;
|
|
69
|
+
functionName = `${unnamed_call_handling_1.UnnamedFunctionCallPrefix}${functionId}`;
|
|
70
|
+
}
|
|
56
71
|
if (functionName === undefined || functionId === undefined) {
|
|
57
72
|
logger_1.dataflowLogger.warn(`Expected symbol or string as function argument at index ${index}, but got ${JSON.stringify(val)} instead.`);
|
|
58
73
|
return information;
|
|
59
74
|
}
|
|
60
75
|
const allOtherArguments = processedArguments.filter((_, i) => i !== index).map((arg, i) => {
|
|
61
76
|
const counterpart = args[i];
|
|
62
|
-
if (arg && counterpart !== r_function_call_1.EmptyArgument
|
|
77
|
+
if (arg && counterpart !== r_function_call_1.EmptyArgument) {
|
|
63
78
|
return {
|
|
64
|
-
name: counterpart.name
|
|
79
|
+
name: counterpart.name?.content,
|
|
65
80
|
controlDependencies: data.controlDependencies,
|
|
66
81
|
type: identifier_1.ReferenceType.Argument,
|
|
67
82
|
nodeId: arg.entryPoint
|
|
@@ -71,16 +86,69 @@ function processApply(name, args, rootId, data, { indexOfFunction = 1, nameOfFun
|
|
|
71
86
|
return r_function_call_1.EmptyArgument;
|
|
72
87
|
}
|
|
73
88
|
});
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
89
|
+
if (anonymous) {
|
|
90
|
+
const rootFnId = functionId;
|
|
91
|
+
functionId = 'anon-' + rootFnId;
|
|
92
|
+
information.graph.addVertex({
|
|
93
|
+
tag: vertex_1.VertexType.FunctionCall,
|
|
94
|
+
id: functionId,
|
|
95
|
+
environment: data.environment,
|
|
96
|
+
name: functionName,
|
|
97
|
+
/* can never be a direct built-in-call */
|
|
98
|
+
onlyBuiltin: false,
|
|
99
|
+
cds: data.controlDependencies,
|
|
100
|
+
args: allOtherArguments, // same reference
|
|
101
|
+
origin: ['function']
|
|
102
|
+
});
|
|
103
|
+
information.graph.addEdge(rootId, rootFnId, edge_1.EdgeType.Calls | edge_1.EdgeType.Reads);
|
|
104
|
+
information.graph.addEdge(rootId, functionId, edge_1.EdgeType.Calls | edge_1.EdgeType.Argument);
|
|
105
|
+
information = {
|
|
106
|
+
...information,
|
|
107
|
+
in: [
|
|
108
|
+
...information.in,
|
|
109
|
+
{ type: identifier_1.ReferenceType.Function, name: functionName, controlDependencies: data.controlDependencies, nodeId: functionId }
|
|
110
|
+
]
|
|
111
|
+
};
|
|
112
|
+
const dfVert = information.graph.getVertex(rootId);
|
|
113
|
+
if (dfVert && dfVert.tag === vertex_1.VertexType.FunctionDefinition) {
|
|
114
|
+
// resolve all ingoings against the environment
|
|
115
|
+
const ingoingRefs = dfVert.subflow.in;
|
|
116
|
+
const remainingIn = [];
|
|
117
|
+
for (const ingoing of ingoingRefs) {
|
|
118
|
+
const resolved = ingoing.name ? (0, resolve_by_name_1.resolveByName)(ingoing.name, data.environment, ingoing.type) : undefined;
|
|
119
|
+
if (resolved === undefined) {
|
|
120
|
+
remainingIn.push(ingoing);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
(0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Found ${resolved.length} references to open ref ${ingoing.nodeId} in closure of function definition ${rootId}`);
|
|
124
|
+
let allBuiltIn = true;
|
|
125
|
+
for (const ref of resolved) {
|
|
126
|
+
information.graph.addEdge(ingoing, ref, edge_1.EdgeType.Reads);
|
|
127
|
+
information.graph.addEdge(rootId, ref, edge_1.EdgeType.Reads); // because the def. is the anonymous call
|
|
128
|
+
if (!(0, identifier_1.isReferenceType)(ref.type, identifier_1.ReferenceType.BuiltInConstant | identifier_1.ReferenceType.BuiltInFunction)) {
|
|
129
|
+
allBuiltIn = false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (allBuiltIn) {
|
|
133
|
+
remainingIn.push(ingoing);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
dfVert.subflow.in = remainingIn;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
/* identify it as a full-blown function call :) */
|
|
141
|
+
information.graph.updateToFunctionCall({
|
|
142
|
+
tag: vertex_1.VertexType.FunctionCall,
|
|
143
|
+
id: functionId,
|
|
144
|
+
name: functionName,
|
|
145
|
+
args: allOtherArguments,
|
|
146
|
+
environment: resolveInEnvironment === 'global' ? undefined : data.environment,
|
|
147
|
+
onlyBuiltin: resolveInEnvironment === 'global',
|
|
148
|
+
cds: data.controlDependencies,
|
|
149
|
+
origin: ['function']
|
|
150
|
+
});
|
|
151
|
+
}
|
|
84
152
|
for (const arg of processedArguments) {
|
|
85
153
|
if (arg) {
|
|
86
154
|
information.graph.addEdge(functionId, arg.entryPoint, edge_1.EdgeType.Argument);
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.processAssignment = processAssignment;
|
|
4
4
|
exports.markAsAssignment = markAsAssignment;
|
|
5
5
|
const known_call_handling_1 = require("../known-call-handling");
|
|
6
|
-
const assert_1 = require("../../../../../../util/assert");
|
|
7
6
|
const log_1 = require("../../../../../../util/log");
|
|
8
7
|
const unpack_argument_1 = require("../argument/unpack-argument");
|
|
9
8
|
const process_named_call_1 = require("../../../process-named-call");
|
|
@@ -19,8 +18,8 @@ const edge_1 = require("../../../../../graph/edge");
|
|
|
19
18
|
const resolve_by_name_1 = require("../../../../../environments/resolve-by-name");
|
|
20
19
|
const containers_1 = require("../../../../../../util/containers");
|
|
21
20
|
const config_1 = require("../../../../../../config");
|
|
22
|
-
const built_in_replacement_1 = require("./built-in-replacement");
|
|
23
21
|
const named_call_handling_1 = require("../named-call-handling");
|
|
22
|
+
const built_in_1 = require("../../../../../environments/built-in");
|
|
24
23
|
function toReplacementSymbol(target, prefix, superAssignment) {
|
|
25
24
|
return {
|
|
26
25
|
type: type_1.RType.Symbol,
|
|
@@ -47,13 +46,13 @@ function findRootAccess(node) {
|
|
|
47
46
|
return undefined;
|
|
48
47
|
}
|
|
49
48
|
}
|
|
50
|
-
function tryReplacementPassingIndices(functionName, data, name, args, indices) {
|
|
49
|
+
function tryReplacementPassingIndices(rootId, functionName, data, name, args, indices) {
|
|
51
50
|
const resolved = (0, resolve_by_name_1.resolveByName)(functionName.content, data.environment, identifier_1.ReferenceType.Function) ?? [];
|
|
52
51
|
// yield for unsupported pass along!
|
|
53
52
|
if (resolved.length !== 1 || resolved[0].type !== identifier_1.ReferenceType.BuiltInFunction) {
|
|
54
53
|
return (0, process_named_call_1.processAsNamedCall)(functionName, data, name, args);
|
|
55
54
|
}
|
|
56
|
-
const info =
|
|
55
|
+
const info = built_in_1.BuiltInProcessorMapper['builtin:replacement']({
|
|
57
56
|
type: type_1.RType.Symbol,
|
|
58
57
|
info: functionName.info,
|
|
59
58
|
content: name,
|
|
@@ -62,7 +61,8 @@ function tryReplacementPassingIndices(functionName, data, name, args, indices) {
|
|
|
62
61
|
namespace: undefined
|
|
63
62
|
}, (0, make_argument_1.wrapArgumentsUnnamed)(args, data.completeAst.idMap), functionName.info.id, data, {
|
|
64
63
|
...(resolved[0].config ?? {}),
|
|
65
|
-
activeIndices: indices
|
|
64
|
+
activeIndices: indices,
|
|
65
|
+
assignRootId: rootId
|
|
66
66
|
});
|
|
67
67
|
(0, named_call_handling_1.markAsOnlyBuiltIn)(info.graph, functionName.info.id);
|
|
68
68
|
return info;
|
|
@@ -77,13 +77,17 @@ function processAssignment(name,
|
|
|
77
77
|
args, rootId, data, config) {
|
|
78
78
|
if (!config.mayHaveMoreArgs && args.length !== 2) {
|
|
79
79
|
logger_1.dataflowLogger.warn(`Assignment ${name.content} has something else than 2 arguments, skipping`);
|
|
80
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs }).information;
|
|
80
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs, origin: 'default' }).information;
|
|
81
81
|
}
|
|
82
82
|
const effectiveArgs = getEffectiveOrder(config, args);
|
|
83
|
-
const { target, source } = extractSourceAndTarget(effectiveArgs
|
|
83
|
+
const { target, source } = extractSourceAndTarget(effectiveArgs);
|
|
84
|
+
if (target === undefined || source === undefined) {
|
|
85
|
+
logger_1.dataflowLogger.warn(`Assignment ${name.content} has an undefined target or source, skipping`);
|
|
86
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs, origin: 'default' }).information;
|
|
87
|
+
}
|
|
84
88
|
const { type, named } = target;
|
|
85
89
|
if (!config.targetVariable && type === type_1.RType.Symbol) {
|
|
86
|
-
const res = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, reverseOrder: !config.swapSourceAndTarget, forceArgs: config.forceArgs });
|
|
90
|
+
const res = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, reverseOrder: !config.swapSourceAndTarget, forceArgs: config.forceArgs, origin: 'builtin:assignment' });
|
|
87
91
|
return processAssignmentToSymbol({
|
|
88
92
|
...config,
|
|
89
93
|
nameOfAssignmentFunction: name.content,
|
|
@@ -99,12 +103,12 @@ args, rootId, data, config) {
|
|
|
99
103
|
/* as replacement functions take precedence over the lhs fn-call (i.e., `names(x) <- ...` is independent from the definition of `names`), we do not have to process the call */
|
|
100
104
|
logger_1.dataflowLogger.debug(`Assignment ${name.content} has a function call as target ==> replacement function ${target.lexeme}`);
|
|
101
105
|
const replacement = toReplacementSymbol(target, target.functionName.content, config.superAssignment ?? false);
|
|
102
|
-
return tryReplacementPassingIndices(replacement, data, replacement.content, [...target.arguments, source], config.indicesCollection);
|
|
106
|
+
return tryReplacementPassingIndices(rootId, replacement, data, replacement.content, [...target.arguments, source], config.indicesCollection);
|
|
103
107
|
}
|
|
104
108
|
else if (config.canBeReplacement && type === type_1.RType.Access) {
|
|
105
109
|
logger_1.dataflowLogger.debug(`Assignment ${name.content} has an access-type node as target ==> replacement function ${target.lexeme}`);
|
|
106
110
|
const replacement = toReplacementSymbol(target, target.operator, config.superAssignment ?? false);
|
|
107
|
-
return tryReplacementPassingIndices(replacement, data, replacement.content, [(0, make_argument_1.toUnnamedArgument)(target.accessed, data.completeAst.idMap), ...target.access, source], config.indicesCollection);
|
|
111
|
+
return tryReplacementPassingIndices(rootId, replacement, data, replacement.content, [(0, make_argument_1.toUnnamedArgument)(target.accessed, data.completeAst.idMap), ...target.access, source], config.indicesCollection);
|
|
108
112
|
}
|
|
109
113
|
else if (type === type_1.RType.Access) {
|
|
110
114
|
const rootArg = findRootAccess(target);
|
|
@@ -115,7 +119,8 @@ args, rootId, data, config) {
|
|
|
115
119
|
rootId,
|
|
116
120
|
data,
|
|
117
121
|
reverseOrder: !config.swapSourceAndTarget,
|
|
118
|
-
forceArgs: config.forceArgs
|
|
122
|
+
forceArgs: config.forceArgs,
|
|
123
|
+
origin: 'builtin:assignment'
|
|
119
124
|
});
|
|
120
125
|
return processAssignmentToSymbol({
|
|
121
126
|
...config,
|
|
@@ -133,15 +138,16 @@ args, rootId, data, config) {
|
|
|
133
138
|
return processAssignmentToString(target, args, name, rootId, data, config, source);
|
|
134
139
|
}
|
|
135
140
|
logger_1.dataflowLogger.warn(`Assignment ${name.content} has an unknown target type ${target.type} => unknown impact`);
|
|
136
|
-
const info = (0, known_call_handling_1.processKnownFunctionCall)({
|
|
141
|
+
const info = (0, known_call_handling_1.processKnownFunctionCall)({
|
|
142
|
+
name, args: effectiveArgs, rootId, data, forceArgs: config.forceArgs,
|
|
143
|
+
origin: 'builtin:assignment'
|
|
144
|
+
}).information;
|
|
137
145
|
info.graph.markIdForUnknownSideEffects(rootId);
|
|
138
146
|
return info;
|
|
139
147
|
}
|
|
140
|
-
function extractSourceAndTarget(args
|
|
148
|
+
function extractSourceAndTarget(args) {
|
|
141
149
|
const source = (0, unpack_argument_1.unpackArgument)(args[1], false);
|
|
142
150
|
const target = (0, unpack_argument_1.unpackArgument)(args[0], false);
|
|
143
|
-
(0, assert_1.guard)(source !== undefined, () => `Assignment ${name.content} has no source, impossible!`);
|
|
144
|
-
(0, assert_1.guard)(target !== undefined, () => `Assignment ${name.content} has no target, impossible!`);
|
|
145
151
|
return { source, target };
|
|
146
152
|
}
|
|
147
153
|
/**
|
|
@@ -176,7 +182,8 @@ function processAssignmentToString(target, args, name, rootId, data, config, sou
|
|
|
176
182
|
rootId,
|
|
177
183
|
data,
|
|
178
184
|
reverseOrder: !config.swapSourceAndTarget,
|
|
179
|
-
forceArgs: config.forceArgs
|
|
185
|
+
forceArgs: config.forceArgs,
|
|
186
|
+
origin: 'builtin:assignment'
|
|
180
187
|
});
|
|
181
188
|
return processAssignmentToSymbol({
|
|
182
189
|
...config,
|
|
@@ -15,14 +15,14 @@ const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
|
|
|
15
15
|
const resolve_by_name_1 = require("../../../../../environments/resolve-by-name");
|
|
16
16
|
const append_1 = require("../../../../../environments/append");
|
|
17
17
|
const assert_1 = require("../../../../../../util/assert");
|
|
18
|
-
const arrays_1 = require("../../../../../../util/arrays");
|
|
18
|
+
const arrays_1 = require("../../../../../../util/collections/arrays");
|
|
19
19
|
function processEvalCall(name, args, rootId, data, config) {
|
|
20
20
|
if (args.length !== 1 || args[0] === r_function_call_1.EmptyArgument || !args[0].value) {
|
|
21
21
|
logger_1.dataflowLogger.warn(`Expected exactly one argument for eval currently, but got ${args.length} instead, skipping`);
|
|
22
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
22
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
23
23
|
}
|
|
24
24
|
const information = config.includeFunctionCall ?
|
|
25
|
-
(0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: [true] }).information
|
|
25
|
+
(0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: [true], origin: 'builtin:eval' }).information
|
|
26
26
|
: (0, info_1.initializeCleanDataflowInformation)(rootId, data);
|
|
27
27
|
const evalArgument = args[0];
|
|
28
28
|
if (config.includeFunctionCall) {
|
|
@@ -78,7 +78,7 @@ function resolveEvalToCode(evalArgument, env, idMap) {
|
|
|
78
78
|
}
|
|
79
79
|
else if (arg.value?.type === type_1.RType.Symbol) {
|
|
80
80
|
const resolve = (0, resolve_by_name_1.resolveValueOfVariable)(arg.value.content, env, idMap);
|
|
81
|
-
if (resolve
|
|
81
|
+
if (resolve?.every(r => typeof r === 'object' && r !== null && 'str' in r)) {
|
|
82
82
|
return resolve.map(r => r.str);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
@@ -105,7 +105,7 @@ function getAsString(val, env, idMap) {
|
|
|
105
105
|
}
|
|
106
106
|
else if (val.type === type_1.RType.Symbol) {
|
|
107
107
|
const resolved = (0, resolve_by_name_1.resolveValueOfVariable)(val.content, env, idMap);
|
|
108
|
-
if (resolved
|
|
108
|
+
if (resolved?.every(r => typeof r === 'object' && r !== null && 'str' in r)) {
|
|
109
109
|
return resolved.map(r => r.str);
|
|
110
110
|
}
|
|
111
111
|
}
|