@eagleoutice/flowr 2.6.3 → 2.7.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 +22 -22
- package/abstract-interpretation/absint-visitor.d.ts +160 -0
- package/abstract-interpretation/absint-visitor.js +279 -0
- package/abstract-interpretation/data-frame/dataframe-domain.d.ts +4 -7
- package/abstract-interpretation/data-frame/dataframe-domain.js +26 -16
- package/abstract-interpretation/data-frame/mappers/access-mapper.d.ts +6 -4
- package/abstract-interpretation/data-frame/mappers/access-mapper.js +11 -14
- package/abstract-interpretation/data-frame/mappers/arguments.d.ts +10 -9
- package/abstract-interpretation/data-frame/mappers/arguments.js +8 -5
- package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +18 -18
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +53 -58
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.d.ts +7 -5
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +26 -29
- package/abstract-interpretation/data-frame/semantics.js +48 -44
- package/abstract-interpretation/data-frame/shape-inference.d.ts +52 -28
- package/abstract-interpretation/data-frame/shape-inference.js +67 -90
- package/abstract-interpretation/domains/abstract-domain.d.ts +1 -0
- package/abstract-interpretation/domains/abstract-domain.js +3 -2
- package/abstract-interpretation/domains/bounded-set-domain.d.ts +2 -2
- package/abstract-interpretation/domains/bounded-set-domain.js +1 -1
- package/abstract-interpretation/domains/interval-domain.d.ts +4 -4
- package/abstract-interpretation/domains/interval-domain.js +3 -6
- package/abstract-interpretation/domains/lattice.d.ts +2 -0
- package/abstract-interpretation/domains/lattice.js +3 -1
- package/abstract-interpretation/domains/positive-interval-domain.d.ts +1 -1
- package/abstract-interpretation/domains/positive-interval-domain.js +1 -1
- package/abstract-interpretation/domains/satisfiable-domain.d.ts +2 -2
- package/abstract-interpretation/domains/satisfiable-domain.js +2 -2
- package/abstract-interpretation/domains/set-range-domain.d.ts +104 -0
- package/abstract-interpretation/domains/set-range-domain.js +406 -0
- package/abstract-interpretation/domains/set-upper-bound-domain.d.ts +2 -2
- package/abstract-interpretation/domains/set-upper-bound-domain.js +2 -2
- package/abstract-interpretation/domains/singleton-domain.d.ts +2 -2
- package/abstract-interpretation/domains/singleton-domain.js +2 -2
- package/benchmark/slicer.d.ts +2 -1
- package/benchmark/slicer.js +50 -29
- package/benchmark/stats/print.js +8 -5
- package/benchmark/stats/stats.d.ts +3 -2
- package/benchmark/summarizer/data.d.ts +11 -8
- package/benchmark/summarizer/first-phase/process.js +11 -8
- package/benchmark/summarizer/second-phase/process.js +24 -18
- package/cli/common/options.d.ts +431 -8
- package/cli/common/options.js +1 -1
- package/cli/common/scripts-info.d.ts +431 -7
- package/cli/flowr-main-options.d.ts +102 -2
- package/cli/flowr.d.ts +102 -2
- package/cli/repl/commands/repl-commands.d.ts +25 -0
- package/cli/repl/commands/repl-query.js +17 -5
- package/cli/wiki.d.ts +13 -0
- package/cli/wiki.js +7 -2
- package/config.d.ts +4 -4
- package/config.js +1 -1
- package/control-flow/basic-cfg-guided-visitor.js +7 -8
- package/control-flow/cfg-dead-code.js +3 -2
- package/control-flow/control-flow-graph.d.ts +1 -1
- package/control-flow/semantic-cfg-guided-visitor.d.ts +1 -1
- package/control-flow/semantic-cfg-guided-visitor.js +1 -1
- package/control-flow/useless-loop.js +4 -2
- package/core/steps/all/static-slicing/00-slice.d.ts +3 -0
- package/core/steps/all/static-slicing/00-slice.js +2 -1
- package/core/steps/pipeline/default-pipelines.d.ts +42 -42
- package/dataflow/cluster.js +2 -2
- package/dataflow/environments/append.d.ts +5 -0
- package/dataflow/environments/append.js +6 -20
- package/dataflow/environments/built-in.d.ts +2 -1
- package/dataflow/environments/clone.d.ts +1 -1
- package/dataflow/environments/clone.js +3 -27
- package/dataflow/environments/define.d.ts +7 -3
- package/dataflow/environments/define.js +9 -56
- package/dataflow/environments/diff.js +1 -1
- package/dataflow/environments/environment.d.ts +48 -28
- package/dataflow/environments/environment.js +187 -62
- package/dataflow/environments/overwrite.js +2 -45
- package/dataflow/environments/reference-to-maybe.d.ts +13 -0
- package/dataflow/environments/reference-to-maybe.js +54 -0
- package/dataflow/environments/resolve-by-name.d.ts +6 -1
- package/dataflow/environments/resolve-by-name.js +56 -4
- package/dataflow/environments/scoping.d.ts +2 -2
- package/dataflow/environments/scoping.js +7 -7
- package/dataflow/eval/resolve/alias-tracking.d.ts +10 -4
- package/dataflow/eval/resolve/alias-tracking.js +16 -14
- package/dataflow/eval/resolve/resolve-argument.d.ts +2 -1
- package/dataflow/eval/resolve/resolve-argument.js +8 -8
- package/dataflow/eval/resolve/resolve.d.ts +13 -11
- package/dataflow/eval/resolve/resolve.js +16 -15
- package/dataflow/extractor.js +1 -7
- package/dataflow/fn/higher-order-function.d.ts +2 -1
- package/dataflow/fn/higher-order-function.js +4 -4
- package/dataflow/graph/dataflowgraph-builder.d.ts +9 -5
- package/dataflow/graph/dataflowgraph-builder.js +21 -11
- package/dataflow/graph/diff-dataflow-graph.js +2 -2
- package/dataflow/graph/graph.d.ts +10 -2
- package/dataflow/graph/graph.js +41 -12
- package/dataflow/graph/invert-dfg.d.ts +3 -2
- package/dataflow/graph/invert-dfg.js +3 -3
- package/dataflow/graph/resolve-graph.d.ts +2 -1
- package/dataflow/graph/resolve-graph.js +2 -2
- package/dataflow/graph/vertex.d.ts +3 -3
- package/dataflow/graph/vertex.js +3 -3
- package/dataflow/info.d.ts +1 -1
- package/dataflow/internal/linker.d.ts +2 -0
- package/dataflow/internal/linker.js +13 -19
- package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +7 -1
- package/dataflow/internal/process/functions/call/argument/unpack-argument.js +12 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +9 -9
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +9 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +2 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +9 -13
- package/dataflow/internal/process/functions/call/built-in/built-in-get.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +3 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +8 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-library.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-repeat-loop.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +6 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +5 -5
- package/dataflow/internal/process/functions/call/common.js +2 -3
- package/dataflow/internal/process/functions/call/known-call-handling.js +1 -1
- package/dataflow/internal/process/functions/call/unnamed-call-handling.js +1 -1
- package/dataflow/internal/process/functions/process-argument.js +1 -1
- package/dataflow/internal/process/process-symbol.js +1 -1
- package/dataflow/internal/process/process-value.d.ts +1 -1
- package/dataflow/internal/process/process-value.js +7 -7
- package/dataflow/processor.d.ts +1 -5
- package/documentation/doc-capabilities.d.ts +1 -1
- package/documentation/doc-readme.d.ts +1 -1
- package/documentation/doc-util/doc-cfg.js +1 -1
- package/documentation/doc-util/doc-cli-option.d.ts +6 -6
- package/documentation/doc-util/doc-cli-option.js +3 -3
- package/documentation/doc-util/doc-dfg.d.ts +1 -1
- package/documentation/doc-util/doc-dfg.js +3 -2
- package/documentation/doc-util/doc-files.d.ts +3 -0
- package/documentation/doc-util/doc-files.js +4 -1
- package/documentation/doc-util/doc-normalized-ast.js +5 -4
- package/documentation/doc-util/doc-types.d.ts +1 -1
- package/documentation/doc-util/doc-types.js +2 -2
- package/documentation/issue-linting-rule.d.ts +1 -1
- package/documentation/wiki-analyzer.d.ts +1 -1
- package/documentation/wiki-analyzer.js +14 -1
- package/documentation/wiki-cfg.d.ts +1 -1
- package/documentation/wiki-core.d.ts +1 -1
- package/documentation/wiki-dataflow-graph.d.ts +1 -1
- package/documentation/wiki-dataflow-graph.js +10 -11
- package/documentation/wiki-engine.d.ts +1 -1
- package/documentation/wiki-engine.js +9 -10
- package/documentation/wiki-faq.d.ts +1 -1
- package/documentation/wiki-faq.js +0 -1
- package/documentation/wiki-interface.d.ts +1 -1
- package/documentation/wiki-interface.js +12 -13
- package/documentation/wiki-linter.d.ts +1 -1
- package/documentation/wiki-linter.js +1 -1
- package/documentation/wiki-linting-and-testing.d.ts +1 -1
- package/documentation/wiki-mk/doc-context.d.ts +54 -1
- package/documentation/wiki-mk/doc-context.js +17 -0
- package/documentation/wiki-mk/doc-maker.d.ts +5 -5
- package/documentation/wiki-mk/doc-maker.js +5 -2
- package/documentation/wiki-normalized-ast.d.ts +1 -1
- package/documentation/wiki-onboarding.d.ts +1 -1
- package/documentation/wiki-overview.d.ts +9 -0
- package/documentation/wiki-overview.js +248 -0
- package/documentation/wiki-query.d.ts +1 -1
- package/documentation/wiki-query.js +17 -1
- package/documentation/wiki-search.d.ts +1 -1
- package/documentation/wiki-setup.d.ts +9 -0
- package/documentation/wiki-setup.js +122 -0
- package/linter/linter-rules.d.ts +2 -2
- package/linter/rules/absolute-path.js +4 -4
- package/linter/rules/dataframe-access-validation.d.ts +2 -2
- package/linter/rules/dataframe-access-validation.js +9 -11
- package/linter/rules/function-finder-util.d.ts +2 -2
- package/linter/rules/function-finder-util.js +1 -1
- package/linter/rules/network-functions.js +1 -1
- package/linter/rules/seeded-randomness.d.ts +1 -1
- package/linter/rules/seeded-randomness.js +5 -5
- package/linter/rules/unused-definition.js +1 -1
- package/package.json +1 -2
- package/project/context/flowr-analyzer-context.d.ts +11 -0
- package/project/context/flowr-analyzer-context.js +3 -0
- package/project/context/flowr-analyzer-environment-context.d.ts +47 -0
- package/project/context/flowr-analyzer-environment-context.js +50 -0
- package/project/context/flowr-analyzer-files-context.d.ts +9 -1
- package/project/context/flowr-analyzer-files-context.js +4 -0
- package/project/context/flowr-file.d.ts +2 -0
- package/project/context/flowr-file.js +2 -0
- package/project/plugins/file-plugins/{flowr-description-file.d.ts → files/flowr-description-file.d.ts} +1 -1
- package/project/plugins/file-plugins/files/flowr-description-file.js +75 -0
- package/project/plugins/file-plugins/files/flowr-news-file.d.ts +27 -0
- package/project/plugins/file-plugins/files/flowr-news-file.js +152 -0
- package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.d.ts +1 -1
- package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.js +1 -1
- package/project/plugins/file-plugins/flowr-analyzer-news-file-plugin.d.ts +23 -0
- package/project/plugins/file-plugins/flowr-analyzer-news-file-plugin.js +35 -0
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-jupyter-file-plugin.d.ts +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-jupyter-file-plugin.js +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-qmd-file-plugin.d.ts +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-qmd-file-plugin.js +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-rmd-file-plugin.d.ts +1 -1
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-rmd-file-plugin.js +1 -1
- package/project/plugins/flowr-analyzer-plugin-defaults.js +2 -0
- package/project/plugins/plugin-registry.d.ts +2 -1
- package/project/plugins/plugin-registry.js +2 -0
- package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.js +7 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +1 -4
- package/queries/catalog/control-flow-query/control-flow-query-format.js +3 -2
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-executor.js +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -4
- package/queries/catalog/df-shape-query/df-shape-query-executor.d.ts +1 -1
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +5 -3
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +4 -4
- package/queries/catalog/df-shape-query/df-shape-query-format.js +2 -2
- package/queries/catalog/files-query/files-query-executor.d.ts +6 -0
- package/queries/catalog/files-query/files-query-executor.js +49 -0
- package/queries/catalog/files-query/files-query-format.d.ts +36 -0
- package/queries/catalog/files-query/files-query-format.js +114 -0
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -3
- package/queries/catalog/linter-query/linter-query-format.js +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +1 -1
- package/queries/query.d.ts +10 -1
- package/queries/query.js +3 -1
- package/r-bridge/lang-4.x/ast/model/model.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/decorate.js +8 -8
- package/r-bridge/lang-4.x/ast/model/processing/role.d.ts +8 -8
- package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-parameter.js +0 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +0 -1
- package/slicing/static/slice-call.d.ts +3 -2
- package/slicing/static/slice-call.js +4 -4
- package/slicing/static/static-slicer.d.ts +3 -1
- package/slicing/static/static-slicer.js +6 -7
- package/statistics/features/supported/control-flow/control-flow.js +1 -1
- package/statistics/features/supported/data-access/data-access.js +1 -1
- package/statistics/features/supported/used-functions/used-functions.js +1 -1
- package/statistics/features/supported/variables/variables.js +2 -1
- package/util/containers.js +2 -2
- package/util/files.d.ts +0 -7
- package/util/files.js +0 -41
- package/util/mermaid/ast.d.ts +3 -2
- package/util/mermaid/ast.js +13 -7
- package/util/mermaid/cfg.d.ts +3 -2
- package/util/mermaid/cfg.js +26 -6
- package/util/mermaid/dfg.d.ts +2 -7
- package/util/mermaid/dfg.js +10 -6
- package/util/mermaid/info.d.ts +17 -0
- package/util/mermaid/info.js +5 -0
- package/util/prefix.d.ts +9 -5
- package/util/prefix.js +14 -6
- package/util/r-regex.d.ts +21 -0
- package/util/r-regex.js +25 -0
- package/util/simple-df/dfg-view.d.ts +2 -1
- package/util/simple-df/dfg-view.js +2 -2
- package/util/text/args.js +12 -3
- package/util/version.js +1 -1
- package/abstract-interpretation/data-frame/absint-info.d.ts +0 -109
- package/abstract-interpretation/data-frame/absint-info.js +0 -31
- package/abstract-interpretation/data-frame/absint-visitor.d.ts +0 -57
- package/abstract-interpretation/data-frame/absint-visitor.js +0 -176
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.d.ts +0 -19
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.js +0 -33
- package/dataflow/environments/remove.d.ts +0 -12
- package/dataflow/environments/remove.js +0 -52
- package/documentation/doc-util/doc-print.d.ts +0 -5
- package/documentation/doc-util/doc-print.js +0 -36
- package/project/plugins/file-plugins/flowr-description-file.js +0 -37
- package/project/plugins/file-plugins/notebooks/notebook.d.ts +0 -0
- package/project/plugins/file-plugins/notebooks/notebook.js +0 -2
- /package/project/plugins/file-plugins/{notebooks → files}/flowr-jupyter-file.d.ts +0 -0
- /package/project/plugins/file-plugins/{notebooks → files}/flowr-jupyter-file.js +0 -0
- /package/project/plugins/file-plugins/{notebooks → files}/flowr-rmarkdown-file.d.ts +0 -0
- /package/project/plugins/file-plugins/{notebooks → files}/flowr-rmarkdown-file.js +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
2
2
|
import type { DataflowGraph } from '../graph/graph';
|
|
3
|
+
import type { ReadOnlyFlowrAnalyzerContext } from '../../project/context/flowr-analyzer-context';
|
|
3
4
|
/**
|
|
4
5
|
* Determines whether the function with the given id is a higher-order function, i.e.,
|
|
5
6
|
* either takes a function as an argument or (may) returns a function.
|
|
6
7
|
* If the return is an identity, e.g., `function(x) x`, this is not considered higher-order,
|
|
7
8
|
* if no function is passed as an argument.
|
|
8
9
|
*/
|
|
9
|
-
export declare function isHigherOrder(id: NodeId, graph: DataflowGraph): boolean;
|
|
10
|
+
export declare function isHigherOrder(id: NodeId, graph: DataflowGraph, ctx: ReadOnlyFlowrAnalyzerContext): boolean;
|
|
@@ -32,7 +32,7 @@ function isAnyReturnAFunction(def, graph) {
|
|
|
32
32
|
}
|
|
33
33
|
return false;
|
|
34
34
|
}
|
|
35
|
-
function inspectCallSitesArgumentsFns(def, graph) {
|
|
35
|
+
function inspectCallSitesArgumentsFns(def, graph, ctx) {
|
|
36
36
|
const callSites = graph.ingoingEdges(def.id);
|
|
37
37
|
for (const [callerId, { types }] of callSites ?? []) {
|
|
38
38
|
if (!(0, edge_1.edgeIncludesType)(types, edge_1.EdgeType.Calls)) {
|
|
@@ -46,7 +46,7 @@ function inspectCallSitesArgumentsFns(def, graph) {
|
|
|
46
46
|
if (arg === r_function_call_1.EmptyArgument) {
|
|
47
47
|
continue;
|
|
48
48
|
}
|
|
49
|
-
const value = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(arg.nodeId, { graph, idMap: graph.idMap, resolve: config_1.VariableResolve.Alias, full: true }));
|
|
49
|
+
const value = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(arg.nodeId, { graph, idMap: graph.idMap, resolve: config_1.VariableResolve.Alias, full: true, ctx }));
|
|
50
50
|
if (value?.elements.some(e => e.type === 'function-definition')) {
|
|
51
51
|
return true;
|
|
52
52
|
}
|
|
@@ -60,7 +60,7 @@ function inspectCallSitesArgumentsFns(def, graph) {
|
|
|
60
60
|
* If the return is an identity, e.g., `function(x) x`, this is not considered higher-order,
|
|
61
61
|
* if no function is passed as an argument.
|
|
62
62
|
*/
|
|
63
|
-
function isHigherOrder(id, graph) {
|
|
63
|
+
function isHigherOrder(id, graph, ctx) {
|
|
64
64
|
const vert = graph.getVertex(id);
|
|
65
65
|
if (!vert || !(0, vertex_1.isFunctionDefinitionVertex)(vert)) {
|
|
66
66
|
return false;
|
|
@@ -70,6 +70,6 @@ function isHigherOrder(id, graph) {
|
|
|
70
70
|
return true;
|
|
71
71
|
}
|
|
72
72
|
// 2. check whether any of the callsites passes a function
|
|
73
|
-
return inspectCallSitesArgumentsFns(vert, graph);
|
|
73
|
+
return inspectCallSitesArgumentsFns(vert, graph, ctx);
|
|
74
74
|
}
|
|
75
75
|
//# sourceMappingURL=higher-order-function.js.map
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
import { type NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
2
2
|
import type { AstIdMap } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
3
|
-
import { type DataflowFunctionFlowInformation, type FunctionArgument
|
|
3
|
+
import { type DataflowFunctionFlowInformation, DataflowGraph, type FunctionArgument } from './graph';
|
|
4
4
|
import { type IEnvironment, type REnvironmentInformation } from '../environments/environment';
|
|
5
|
-
import { type DataflowGraphVertexAstLink, type DataflowGraphVertexUse, type FunctionOriginInformation } from './vertex';
|
|
5
|
+
import { type DataflowGraphVertexArgument, type DataflowGraphVertexAstLink, type DataflowGraphVertexInfo, type DataflowGraphVertexUse, type FunctionOriginInformation } from './vertex';
|
|
6
6
|
import type { ControlDependency } from '../info';
|
|
7
7
|
import type { LinkTo } from '../../queries/catalog/call-context-query/call-context-query-format';
|
|
8
8
|
import type { FlowrSearchLike } from '../../search/flowr-search-builder';
|
|
9
9
|
import type { ReadonlyFlowrAnalysisProvider } from '../../project/flowr-analyzer';
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Creates an empty dataflow graph.
|
|
12
|
+
* Should only be used in tests and documentation.
|
|
12
13
|
*/
|
|
13
|
-
export declare function emptyGraph(idMap?: AstIdMap): DataflowGraphBuilder
|
|
14
|
+
export declare function emptyGraph(cleanEnv?: REnvironmentInformation, idMap?: AstIdMap): DataflowGraphBuilder<DataflowGraphVertexInfo>;
|
|
14
15
|
export type DataflowGraphEdgeTarget = NodeId | (readonly NodeId[]);
|
|
15
16
|
/**
|
|
16
17
|
* This DataflowGraphBuilder extends {@link DataflowGraph} with builder methods to
|
|
17
18
|
* easily and compactly add vertices and edges to a dataflow graph. Its usage thus
|
|
18
19
|
* simplifies writing tests for dataflow graphs.
|
|
19
20
|
*/
|
|
20
|
-
export declare class DataflowGraphBuilder extends DataflowGraph {
|
|
21
|
+
export declare class DataflowGraphBuilder<Vertex extends DataflowGraphVertexInfo = DataflowGraphVertexInfo> extends DataflowGraph {
|
|
22
|
+
private readonly defaultEnvironment;
|
|
23
|
+
constructor(cleanEnv?: REnvironmentInformation, idMap?: AstIdMap);
|
|
24
|
+
addVertexWithDefaultEnv(vertex: DataflowGraphVertexArgument & Omit<Vertex, keyof DataflowGraphVertexArgument>, asRoot?: boolean, overwrite?: boolean): this;
|
|
21
25
|
/**
|
|
22
26
|
* Adds a **vertex** for a **function definition** (V1).
|
|
23
27
|
* @param id - AST node ID
|
|
@@ -6,7 +6,6 @@ exports.getBuiltInSideEffect = getBuiltInSideEffect;
|
|
|
6
6
|
const objects_1 = require("../../util/objects");
|
|
7
7
|
const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
|
|
8
8
|
const graph_1 = require("./graph");
|
|
9
|
-
const environment_1 = require("../environments/environment");
|
|
10
9
|
const vertex_1 = require("./vertex");
|
|
11
10
|
const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
12
11
|
const built_in_1 = require("../environments/built-in");
|
|
@@ -14,11 +13,13 @@ const edge_1 = require("./edge");
|
|
|
14
13
|
const default_builtin_config_1 = require("../environments/default-builtin-config");
|
|
15
14
|
const flowr_search_executor_1 = require("../../search/flowr-search-executor");
|
|
16
15
|
const assert_1 = require("../../util/assert");
|
|
16
|
+
const flowr_analyzer_context_1 = require("../../project/context/flowr-analyzer-context");
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* Creates an empty dataflow graph.
|
|
19
|
+
* Should only be used in tests and documentation.
|
|
19
20
|
*/
|
|
20
|
-
function emptyGraph(idMap) {
|
|
21
|
-
return new DataflowGraphBuilder(idMap);
|
|
21
|
+
function emptyGraph(cleanEnv, idMap) {
|
|
22
|
+
return new DataflowGraphBuilder(cleanEnv, idMap);
|
|
22
23
|
}
|
|
23
24
|
/**
|
|
24
25
|
* This DataflowGraphBuilder extends {@link DataflowGraph} with builder methods to
|
|
@@ -26,6 +27,15 @@ function emptyGraph(idMap) {
|
|
|
26
27
|
* simplifies writing tests for dataflow graphs.
|
|
27
28
|
*/
|
|
28
29
|
class DataflowGraphBuilder extends graph_1.DataflowGraph {
|
|
30
|
+
defaultEnvironment;
|
|
31
|
+
constructor(cleanEnv, idMap) {
|
|
32
|
+
super(idMap);
|
|
33
|
+
this.defaultEnvironment = cleanEnv ?? (0, flowr_analyzer_context_1.contextFromInput)('').env.makeCleanEnv();
|
|
34
|
+
}
|
|
35
|
+
addVertexWithDefaultEnv(vertex, asRoot = true, overwrite = false) {
|
|
36
|
+
super.addVertex(vertex, this.defaultEnvironment, asRoot, overwrite);
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
29
39
|
/**
|
|
30
40
|
* Adds a **vertex** for a **function definition** (V1).
|
|
31
41
|
* @param id - AST node ID
|
|
@@ -36,7 +46,7 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
|
|
|
36
46
|
* (i.e., be a valid entry point), or is it nested (e.g., as part of a function definition)
|
|
37
47
|
*/
|
|
38
48
|
defineFunction(id, exitPoints, subflow, info, asRoot = true) {
|
|
39
|
-
return this.
|
|
49
|
+
return this.addVertexWithDefaultEnv({
|
|
40
50
|
tag: vertex_1.VertexType.FunctionDefinition,
|
|
41
51
|
id: (0, node_id_1.normalizeIdToNumberIfPossible)(id),
|
|
42
52
|
subflow: {
|
|
@@ -49,7 +59,7 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
|
|
|
49
59
|
},
|
|
50
60
|
exitPoints: exitPoints.map(node_id_1.normalizeIdToNumberIfPossible),
|
|
51
61
|
cds: info?.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })),
|
|
52
|
-
environment: info?.environment
|
|
62
|
+
environment: info?.environment,
|
|
53
63
|
}, asRoot);
|
|
54
64
|
}
|
|
55
65
|
/**
|
|
@@ -63,12 +73,12 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
|
|
|
63
73
|
*/
|
|
64
74
|
call(id, name, args, info, asRoot = true) {
|
|
65
75
|
const onlyBuiltInAuto = info?.reads?.length === 1 && (0, built_in_1.isBuiltIn)(info?.reads[0]);
|
|
66
|
-
this.
|
|
76
|
+
this.addVertexWithDefaultEnv({
|
|
67
77
|
tag: vertex_1.VertexType.FunctionCall,
|
|
68
78
|
id: (0, node_id_1.normalizeIdToNumberIfPossible)(id),
|
|
69
79
|
name,
|
|
70
80
|
args: args.map(a => a === r_function_call_1.EmptyArgument ? r_function_call_1.EmptyArgument : { ...a, nodeId: (0, node_id_1.normalizeIdToNumberIfPossible)(a.nodeId), controlDependencies: undefined }),
|
|
71
|
-
environment: (info?.onlyBuiltIn || onlyBuiltInAuto) ? undefined : info?.environment ??
|
|
81
|
+
environment: (info?.onlyBuiltIn || onlyBuiltInAuto) ? undefined : info?.environment ?? this.defaultEnvironment,
|
|
72
82
|
cds: info?.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })),
|
|
73
83
|
onlyBuiltin: info?.onlyBuiltIn ?? onlyBuiltInAuto ?? false,
|
|
74
84
|
origin: info?.origin ?? [(0, default_builtin_config_1.getDefaultProcessor)(name) ?? 'function'],
|
|
@@ -115,7 +125,7 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
|
|
|
115
125
|
* (i.e., be a valid entry point), or is it nested (e.g., as part of a function definition)
|
|
116
126
|
*/
|
|
117
127
|
defineVariable(id, name, info, asRoot = true) {
|
|
118
|
-
this.
|
|
128
|
+
this.addVertexWithDefaultEnv({
|
|
119
129
|
tag: vertex_1.VertexType.VariableDefinition,
|
|
120
130
|
id: (0, node_id_1.normalizeIdToNumberIfPossible)(id),
|
|
121
131
|
name,
|
|
@@ -137,7 +147,7 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
|
|
|
137
147
|
* (i.e., be a valid entry point) or is it nested (e.g., as part of a function definition)
|
|
138
148
|
*/
|
|
139
149
|
use(id, name, info, asRoot = true) {
|
|
140
|
-
return this.
|
|
150
|
+
return this.addVertexWithDefaultEnv((0, objects_1.deepMergeObject)({
|
|
141
151
|
tag: vertex_1.VertexType.Use,
|
|
142
152
|
id: (0, node_id_1.normalizeIdToNumberIfPossible)(id),
|
|
143
153
|
name,
|
|
@@ -156,7 +166,7 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
|
|
|
156
166
|
* (i.e., be a valid entry point), or is it nested (e.g., as part of a function definition)
|
|
157
167
|
*/
|
|
158
168
|
constant(id, options, asRoot = true) {
|
|
159
|
-
return this.
|
|
169
|
+
return this.addVertexWithDefaultEnv({
|
|
160
170
|
tag: vertex_1.VertexType.Value,
|
|
161
171
|
id: (0, node_id_1.normalizeIdToNumberIfPossible)(id),
|
|
162
172
|
cds: options?.controlDependencies?.map(c => ({ ...c, id: (0, node_id_1.normalizeIdToNumberIfPossible)(c.id) })),
|
|
@@ -207,8 +207,8 @@ function diffVertices(ctx) {
|
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
|
-
if (lInfo.tag ===
|
|
211
|
-
if (rInfo.tag !==
|
|
210
|
+
if (lInfo.tag === vertex_1.VertexType.FunctionDefinition) {
|
|
211
|
+
if (rInfo.tag !== vertex_1.VertexType.FunctionDefinition) {
|
|
212
212
|
ctx.report.addComment(`Vertex ${id} differs in tags. ${ctx.leftname}: ${lInfo.tag} vs. ${ctx.rightname}: ${rInfo.tag}`, { tag: 'vertex', id });
|
|
213
213
|
}
|
|
214
214
|
else {
|
|
@@ -4,6 +4,7 @@ import { type DataflowGraphVertexArgument, type DataflowGraphVertexFunctionCall,
|
|
|
4
4
|
import { EmptyArgument } from '../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
5
5
|
import type { Identifier, IdentifierDefinition, IdentifierReference } from '../environments/identifier';
|
|
6
6
|
import { type NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
7
|
+
import { type REnvironmentInformation } from '../environments/environment';
|
|
7
8
|
import type { AstIdMap } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
8
9
|
import type { LinkTo } from '../../queries/catalog/call-context-query/call-context-query-format';
|
|
9
10
|
/**
|
|
@@ -71,6 +72,7 @@ export interface DataflowGraphJson {
|
|
|
71
72
|
readonly rootVertices: NodeId[];
|
|
72
73
|
readonly vertexInformation: [NodeId, DataflowGraphVertexInfo][];
|
|
73
74
|
readonly edgeInformation: [NodeId, [NodeId, DataflowGraphEdge][]][];
|
|
75
|
+
readonly _unknownSideEffects: UnknownSideEffect[];
|
|
74
76
|
}
|
|
75
77
|
/**
|
|
76
78
|
* An unknown side effect describes something that we cannot handle correctly (in all cases).
|
|
@@ -98,7 +100,6 @@ export type UnknownSideEffect = NodeId | {
|
|
|
98
100
|
* @see {@link emptyGraph|`emptyGraph`} - to create an empty graph (useful in tests)
|
|
99
101
|
*/
|
|
100
102
|
export declare class DataflowGraph<Vertex extends DataflowGraphVertexInfo = DataflowGraphVertexInfo, Edge extends DataflowGraphEdge = DataflowGraphEdge> {
|
|
101
|
-
private static DEFAULT_ENVIRONMENT;
|
|
102
103
|
private _idMap;
|
|
103
104
|
private readonly _unknownSideEffects;
|
|
104
105
|
constructor(idMap: AstIdMap | undefined);
|
|
@@ -108,6 +109,8 @@ export declare class DataflowGraph<Vertex extends DataflowGraphVertexInfo = Data
|
|
|
108
109
|
private vertexInformation;
|
|
109
110
|
/** All edges in the complete graph (including those nested in function definition) */
|
|
110
111
|
private edgeInformation;
|
|
112
|
+
private types;
|
|
113
|
+
toJSON(): DataflowGraphJson;
|
|
111
114
|
/**
|
|
112
115
|
* Get the {@link DataflowGraphVertexInfo} attached to a node as well as all outgoing edges.
|
|
113
116
|
* @param id - The id of the node to get
|
|
@@ -147,6 +150,10 @@ export declare class DataflowGraph<Vertex extends DataflowGraphVertexInfo = Data
|
|
|
147
150
|
* @see #edges
|
|
148
151
|
*/
|
|
149
152
|
vertices(includeDefinedFunctions: boolean): MapIterator<[NodeId, Vertex]>;
|
|
153
|
+
verticesOfType<T extends Vertex['tag']>(type: T): MapIterator<[NodeId, Vertex & {
|
|
154
|
+
tag: T;
|
|
155
|
+
}]>;
|
|
156
|
+
vertexIdsOfType<T extends Vertex['tag']>(type: T): NodeId[];
|
|
150
157
|
/**
|
|
151
158
|
* @returns the ids of all edges in the graph together with their edge information
|
|
152
159
|
* @see #vertices
|
|
@@ -166,13 +173,14 @@ export declare class DataflowGraph<Vertex extends DataflowGraphVertexInfo = Data
|
|
|
166
173
|
/**
|
|
167
174
|
* Adds a new vertex to the graph, for ease of use, some arguments are optional and filled automatically.
|
|
168
175
|
* @param vertex - The vertex to add
|
|
176
|
+
* @param fallbackEnv - A clean environment to use if no environment is given in the vertex
|
|
169
177
|
* @param asRoot - If false, this will only add the vertex but do not add it to the {@link rootIds|root vertices} of the graph.
|
|
170
178
|
* This is probably only of use, when you construct dataflow graphs for tests.
|
|
171
179
|
* @param overwrite - If true, this will overwrite the vertex if it already exists in the graph (based on the id).
|
|
172
180
|
* @see DataflowGraphVertexInfo
|
|
173
181
|
* @see DataflowGraphVertexArgument
|
|
174
182
|
*/
|
|
175
|
-
addVertex(vertex: DataflowGraphVertexArgument & Omit<Vertex, keyof DataflowGraphVertexArgument>, asRoot?: boolean, overwrite?: boolean): this;
|
|
183
|
+
addVertex(vertex: DataflowGraphVertexArgument & Omit<Vertex, keyof DataflowGraphVertexArgument>, fallbackEnv: REnvironmentInformation, asRoot?: boolean, overwrite?: boolean): this;
|
|
176
184
|
/** {@inheritDoc} */
|
|
177
185
|
addEdge(from: NodeId, to: NodeId, type: EdgeType | number): this;
|
|
178
186
|
/** {@inheritDoc} */
|
package/dataflow/graph/graph.js
CHANGED
|
@@ -51,7 +51,6 @@ function getReferenceOfArgument(arg) {
|
|
|
51
51
|
* @see {@link emptyGraph|`emptyGraph`} - to create an empty graph (useful in tests)
|
|
52
52
|
*/
|
|
53
53
|
class DataflowGraph {
|
|
54
|
-
static DEFAULT_ENVIRONMENT = undefined;
|
|
55
54
|
_idMap;
|
|
56
55
|
/*
|
|
57
56
|
* Set of vertices which have sideEffects that we do not know anything about.
|
|
@@ -60,7 +59,6 @@ class DataflowGraph {
|
|
|
60
59
|
*/
|
|
61
60
|
_unknownSideEffects = new Set();
|
|
62
61
|
constructor(idMap) {
|
|
63
|
-
DataflowGraph.DEFAULT_ENVIRONMENT ??= (0, environment_1.initializeCleanEnvironments)();
|
|
64
62
|
this._idMap = idMap;
|
|
65
63
|
}
|
|
66
64
|
/** Contains the vertices of the root level graph (i.e., included those vertices from the complete graph, that are nested within function definitions) */
|
|
@@ -69,6 +67,15 @@ class DataflowGraph {
|
|
|
69
67
|
vertexInformation = new Map();
|
|
70
68
|
/** All edges in the complete graph (including those nested in function definition) */
|
|
71
69
|
edgeInformation = new Map();
|
|
70
|
+
types = new Map();
|
|
71
|
+
toJSON() {
|
|
72
|
+
return {
|
|
73
|
+
rootVertices: Array.from(this.rootVertices),
|
|
74
|
+
vertexInformation: Array.from(this.vertexInformation.entries()),
|
|
75
|
+
edgeInformation: Array.from(this.edgeInformation.entries()).map(([id, edges]) => [id, Array.from(edges.entries())]),
|
|
76
|
+
_unknownSideEffects: Array.from(this._unknownSideEffects)
|
|
77
|
+
};
|
|
78
|
+
}
|
|
72
79
|
/**
|
|
73
80
|
* Get the {@link DataflowGraphVertexInfo} attached to a node as well as all outgoing edges.
|
|
74
81
|
* @param id - The id of the node to get
|
|
@@ -150,6 +157,15 @@ class DataflowGraph {
|
|
|
150
157
|
}
|
|
151
158
|
}
|
|
152
159
|
}
|
|
160
|
+
*verticesOfType(type) {
|
|
161
|
+
const ids = this.types.get(type) ?? [];
|
|
162
|
+
for (const id of ids) {
|
|
163
|
+
yield [id, this.vertexInformation.get(id)];
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
vertexIdsOfType(type) {
|
|
167
|
+
return this.types.get(type) ?? [];
|
|
168
|
+
}
|
|
153
169
|
/**
|
|
154
170
|
* @returns the ids of all edges in the graph together with their edge information
|
|
155
171
|
* @see #vertices
|
|
@@ -177,24 +193,32 @@ class DataflowGraph {
|
|
|
177
193
|
/**
|
|
178
194
|
* Adds a new vertex to the graph, for ease of use, some arguments are optional and filled automatically.
|
|
179
195
|
* @param vertex - The vertex to add
|
|
196
|
+
* @param fallbackEnv - A clean environment to use if no environment is given in the vertex
|
|
180
197
|
* @param asRoot - If false, this will only add the vertex but do not add it to the {@link rootIds|root vertices} of the graph.
|
|
181
198
|
* This is probably only of use, when you construct dataflow graphs for tests.
|
|
182
199
|
* @param overwrite - If true, this will overwrite the vertex if it already exists in the graph (based on the id).
|
|
183
200
|
* @see DataflowGraphVertexInfo
|
|
184
201
|
* @see DataflowGraphVertexArgument
|
|
185
202
|
*/
|
|
186
|
-
addVertex(vertex, asRoot = true, overwrite = false) {
|
|
203
|
+
addVertex(vertex, fallbackEnv, asRoot = true, overwrite = false) {
|
|
187
204
|
const oldVertex = this.vertexInformation.get(vertex.id);
|
|
188
205
|
if (oldVertex !== undefined && !overwrite) {
|
|
189
206
|
return this;
|
|
190
207
|
}
|
|
191
|
-
const fallback = vertex.tag === vertex_1.VertexType.
|
|
208
|
+
const fallback = vertex.tag === vertex_1.VertexType.FunctionDefinition || (vertex.tag === vertex_1.VertexType.FunctionCall && !vertex.onlyBuiltin) ? fallbackEnv : undefined;
|
|
192
209
|
// keep a clone of the original environment
|
|
193
210
|
const environment = vertex.environment ? (0, clone_1.cloneEnvironmentInformation)(vertex.environment) : fallback;
|
|
194
211
|
this.vertexInformation.set(vertex.id, {
|
|
195
212
|
...vertex,
|
|
196
213
|
environment
|
|
197
214
|
});
|
|
215
|
+
const has = this.types.get(vertex.tag);
|
|
216
|
+
if (has) {
|
|
217
|
+
has.push(vertex.id);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
this.types.set(vertex.tag, [vertex.id]);
|
|
221
|
+
}
|
|
198
222
|
if (asRoot) {
|
|
199
223
|
this.rootVertices.add(vertex.id);
|
|
200
224
|
}
|
|
@@ -246,6 +270,10 @@ class DataflowGraph {
|
|
|
246
270
|
const currentInfo = this.vertexInformation.get(id);
|
|
247
271
|
this.vertexInformation.set(id, currentInfo === undefined ? info : mergeNodeInfos(currentInfo, info));
|
|
248
272
|
}
|
|
273
|
+
for (const [type, ids] of otherGraph.types) {
|
|
274
|
+
const existing = this.types.get(type);
|
|
275
|
+
this.types.set(type, existing ? existing.concat(ids) : ids.slice());
|
|
276
|
+
}
|
|
249
277
|
this.mergeEdges(otherGraph);
|
|
250
278
|
return this;
|
|
251
279
|
}
|
|
@@ -289,7 +317,10 @@ class DataflowGraph {
|
|
|
289
317
|
updateToFunctionCall(info) {
|
|
290
318
|
const vertex = this.getVertex(info.id, true);
|
|
291
319
|
(0, assert_1.guard)(vertex !== undefined && (vertex.tag === vertex_1.VertexType.Use || vertex.tag === vertex_1.VertexType.Value), () => `node must be a use or value node for ${JSON.stringify(info.id)} to update it to a function call but is ${vertex?.tag}`);
|
|
320
|
+
const previousTag = vertex.tag;
|
|
292
321
|
this.vertexInformation.set(info.id, { ...vertex, ...info, tag: vertex_1.VertexType.FunctionCall });
|
|
322
|
+
this.types.set(previousTag, (this.types.get(previousTag) ?? []).filter(id => id !== info.id));
|
|
323
|
+
this.types.set(vertex_1.VertexType.FunctionCall, (this.types.get(vertex_1.VertexType.FunctionCall) ?? []).concat([info.id]));
|
|
293
324
|
}
|
|
294
325
|
/** If you do not pass the `to` node, this will just mark the node as maybe */
|
|
295
326
|
addControlDependency(from, to, when) {
|
|
@@ -338,6 +369,9 @@ class DataflowGraph {
|
|
|
338
369
|
}
|
|
339
370
|
}
|
|
340
371
|
graph.edgeInformation = new Map(data.edgeInformation.map(([id, edges]) => [id, new Map(edges)]));
|
|
372
|
+
for (const unknown of data._unknownSideEffects) {
|
|
373
|
+
graph._unknownSideEffects.add(unknown);
|
|
374
|
+
}
|
|
341
375
|
return graph;
|
|
342
376
|
}
|
|
343
377
|
}
|
|
@@ -373,14 +407,9 @@ function envFromJson(json) {
|
|
|
373
407
|
for (const [key, value] of Object.entries(json.memory)) {
|
|
374
408
|
memory.set(key, value);
|
|
375
409
|
}
|
|
376
|
-
const obj =
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
memory
|
|
380
|
-
};
|
|
381
|
-
if (json.builtInEnv) {
|
|
382
|
-
obj.builtInEnv = true;
|
|
383
|
-
}
|
|
410
|
+
const obj = new environment_1.Environment(parent, json.builtInEnv);
|
|
411
|
+
obj.id = json.id;
|
|
412
|
+
obj.memory = memory;
|
|
384
413
|
return obj;
|
|
385
414
|
}
|
|
386
415
|
function renvFromJson(json) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DataflowGraph } from './graph';
|
|
2
|
+
import type { REnvironmentInformation } from '../environments/environment';
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
+
* Inverts the given dataflow graph by reversing all edges.
|
|
4
5
|
*/
|
|
5
|
-
export declare function invertDfg(graph: DataflowGraph): DataflowGraph;
|
|
6
|
+
export declare function invertDfg(graph: DataflowGraph, cleanEnv: REnvironmentInformation): DataflowGraph;
|
|
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.invertDfg = invertDfg;
|
|
4
4
|
const graph_1 = require("./graph");
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Inverts the given dataflow graph by reversing all edges.
|
|
7
7
|
*/
|
|
8
|
-
function invertDfg(graph) {
|
|
8
|
+
function invertDfg(graph, cleanEnv) {
|
|
9
9
|
const invertedGraph = new graph_1.DataflowGraph(graph.idMap);
|
|
10
10
|
for (const [, v] of graph.vertices(true)) {
|
|
11
|
-
invertedGraph.addVertex(v);
|
|
11
|
+
invertedGraph.addVertex(v, cleanEnv);
|
|
12
12
|
}
|
|
13
13
|
for (const [from, targets] of graph.edges()) {
|
|
14
14
|
for (const [to, { types }] of targets) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { DataflowGraph } from './graph';
|
|
2
2
|
import { type AstIdMap } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
3
|
+
import type { ReadOnlyFlowrAnalyzerContext } from '../../project/context/flowr-analyzer-context';
|
|
3
4
|
/**
|
|
4
5
|
* Resolves the dataflow graph ids from slicing criterion form to ids.
|
|
5
6
|
* This returns a **new** graph with the resolved ids.
|
|
6
7
|
*/
|
|
7
|
-
export declare function resolveDataflowGraph(graph: DataflowGraph, idMap?: AstIdMap): DataflowGraph;
|
|
8
|
+
export declare function resolveDataflowGraph(graph: DataflowGraph, ctx: ReadOnlyFlowrAnalyzerContext, idMap?: AstIdMap): DataflowGraph;
|
|
@@ -9,7 +9,7 @@ const edge_1 = require("./edge");
|
|
|
9
9
|
* Resolves the dataflow graph ids from slicing criterion form to ids.
|
|
10
10
|
* This returns a **new** graph with the resolved ids.
|
|
11
11
|
*/
|
|
12
|
-
function resolveDataflowGraph(graph, idMap) {
|
|
12
|
+
function resolveDataflowGraph(graph, ctx, idMap) {
|
|
13
13
|
const resolveMap = idMap ?? graph.idMap;
|
|
14
14
|
(0, assert_1.guard)(resolveMap !== undefined, 'idMap must be provided to resolve the graph');
|
|
15
15
|
const cache = new Map();
|
|
@@ -36,7 +36,7 @@ function resolveDataflowGraph(graph, idMap) {
|
|
|
36
36
|
resultGraph.addVertex({
|
|
37
37
|
...vertex,
|
|
38
38
|
id: resolve(id)
|
|
39
|
-
}, roots.has(id));
|
|
39
|
+
}, ctx.env.makeCleanEnv(), roots.has(id));
|
|
40
40
|
}
|
|
41
41
|
/* recreate edges */
|
|
42
42
|
for (const [from, targets] of graph.edges()) {
|
|
@@ -7,9 +7,9 @@ import type { BuiltInMappingName } from '../environments/built-in';
|
|
|
7
7
|
export declare enum VertexType {
|
|
8
8
|
Value = "value",
|
|
9
9
|
Use = "use",
|
|
10
|
-
FunctionCall = "
|
|
11
|
-
VariableDefinition = "
|
|
12
|
-
FunctionDefinition = "
|
|
10
|
+
FunctionCall = "fcall",
|
|
11
|
+
VariableDefinition = "vdef",
|
|
12
|
+
FunctionDefinition = "fdef"
|
|
13
13
|
}
|
|
14
14
|
export declare const ValidVertexTypes: Set<string>;
|
|
15
15
|
export declare const ValidVertexTypeReverse: {
|
package/dataflow/graph/vertex.js
CHANGED
|
@@ -14,9 +14,9 @@ var VertexType;
|
|
|
14
14
|
(function (VertexType) {
|
|
15
15
|
VertexType["Value"] = "value";
|
|
16
16
|
VertexType["Use"] = "use";
|
|
17
|
-
VertexType["FunctionCall"] = "
|
|
18
|
-
VertexType["VariableDefinition"] = "
|
|
19
|
-
VertexType["FunctionDefinition"] = "
|
|
17
|
+
VertexType["FunctionCall"] = "fcall";
|
|
18
|
+
VertexType["VariableDefinition"] = "vdef";
|
|
19
|
+
VertexType["FunctionDefinition"] = "fdef";
|
|
20
20
|
})(VertexType || (exports.VertexType = VertexType = {}));
|
|
21
21
|
exports.ValidVertexTypes = new Set(Object.values(VertexType));
|
|
22
22
|
exports.ValidVertexTypeReverse = Object.fromEntries(Object.entries(VertexType).map(([k, v]) => [v, k]));
|
package/dataflow/info.d.ts
CHANGED
|
@@ -102,7 +102,7 @@ export interface DataflowInformation extends DataflowCfgInformation {
|
|
|
102
102
|
* This is to be used as a "starting point" when processing leaf nodes during the dataflow extraction.
|
|
103
103
|
* @see {@link DataflowInformation}
|
|
104
104
|
*/
|
|
105
|
-
export declare function initializeCleanDataflowInformation<T>(entryPoint: NodeId, data: Pick<DataflowProcessorInformation<T>, 'environment' | '
|
|
105
|
+
export declare function initializeCleanDataflowInformation<T>(entryPoint: NodeId, data: Pick<DataflowProcessorInformation<T>, 'environment' | 'completeAst'>): DataflowInformation;
|
|
106
106
|
/**
|
|
107
107
|
* Checks whether the given control dependencies are exhaustive (i.e. if for every control dependency on a boolean,
|
|
108
108
|
* the list contains a dependency on the `true` and on the `false` case).
|
|
@@ -19,6 +19,8 @@ export declare function findNonLocalReads(graph: DataflowGraph, ignore: readonly
|
|
|
19
19
|
export declare function produceNameSharedIdMap(references: IdentifierReference[]): NameIdMap;
|
|
20
20
|
/**
|
|
21
21
|
* Links the given arguments to the given parameters within the given graph.
|
|
22
|
+
* This follows the `pmatch` semantics of R
|
|
23
|
+
* @see https://cran.r-project.org/doc/manuals/R-lang.html#Argument-matching
|
|
22
24
|
*/
|
|
23
25
|
export declare function linkArgumentsOnCall(args: FunctionArgument[], params: RParameter<ParentInformation>[], graph: DataflowGraph): void;
|
|
24
26
|
/**
|
|
@@ -29,9 +29,7 @@ const prefix_1 = require("../../util/prefix");
|
|
|
29
29
|
*/
|
|
30
30
|
function findNonLocalReads(graph, ignore) {
|
|
31
31
|
const ignores = new Set(ignore.map(i => i.nodeId));
|
|
32
|
-
const ids = new Set(graph.
|
|
33
|
-
.filter(([_, info]) => info.tag === vertex_1.VertexType.Use || info.tag === vertex_1.VertexType.FunctionCall)
|
|
34
|
-
.map(([id, _]) => id));
|
|
32
|
+
const ids = new Set(graph.vertexIdsOfType(vertex_1.VertexType.Use).concat(graph.vertexIdsOfType(vertex_1.VertexType.FunctionCall)));
|
|
35
33
|
/* find all variable use ids which do not link to a given id */
|
|
36
34
|
const nonLocalReads = [];
|
|
37
35
|
for (const id of ids) {
|
|
@@ -81,27 +79,28 @@ function produceNameSharedIdMap(references) {
|
|
|
81
79
|
}
|
|
82
80
|
/**
|
|
83
81
|
* Links the given arguments to the given parameters within the given graph.
|
|
82
|
+
* This follows the `pmatch` semantics of R
|
|
83
|
+
* @see https://cran.r-project.org/doc/manuals/R-lang.html#Argument-matching
|
|
84
84
|
*/
|
|
85
85
|
function linkArgumentsOnCall(args, params, graph) {
|
|
86
86
|
const nameArgMap = new Map(args.filter(graph_1.isNamedArgument).map(a => [a.name, a]));
|
|
87
|
-
const nameParamMap = new Map(params.filter(p => p?.name?.content !== undefined)
|
|
87
|
+
const nameParamMap = new Map(params.filter(p => p?.name?.content !== undefined)
|
|
88
|
+
.map(p => [p.name.content, p]));
|
|
88
89
|
const specialDotParameter = params.find(p => p.special);
|
|
89
90
|
// all parameters matched by name
|
|
90
91
|
const matchedParameters = new Set();
|
|
91
92
|
// first map names
|
|
92
|
-
for (const [name,
|
|
93
|
+
for (const [name, { nodeId: argId }] of nameArgMap) {
|
|
93
94
|
const pmatchName = (0, prefix_1.findByPrefixIfUnique)(name, nameParamMap.keys()) ?? name;
|
|
94
95
|
const param = nameParamMap.get(pmatchName);
|
|
95
96
|
if (param?.name) {
|
|
96
|
-
|
|
97
|
-
graph.addEdge(
|
|
98
|
-
graph.addEdge(param.name.info.id, arg.nodeId, edge_1.EdgeType.DefinedByOnCall);
|
|
97
|
+
graph.addEdge(argId, param.name.info.id, edge_1.EdgeType.DefinesOnCall);
|
|
98
|
+
graph.addEdge(param.name.info.id, argId, edge_1.EdgeType.DefinedByOnCall);
|
|
99
99
|
matchedParameters.add(name);
|
|
100
100
|
}
|
|
101
101
|
else if (specialDotParameter?.name) {
|
|
102
|
-
|
|
103
|
-
graph.addEdge(
|
|
104
|
-
graph.addEdge(specialDotParameter.name.info.id, arg.nodeId, edge_1.EdgeType.DefinedByOnCall);
|
|
102
|
+
graph.addEdge(argId, specialDotParameter.name.info.id, edge_1.EdgeType.DefinesOnCall);
|
|
103
|
+
graph.addEdge(specialDotParameter.name.info.id, argId, edge_1.EdgeType.DefinedByOnCall);
|
|
105
104
|
}
|
|
106
105
|
}
|
|
107
106
|
const remainingParameter = params.filter(p => !p?.name || !matchedParameters.has(p.name.content));
|
|
@@ -109,12 +108,10 @@ function linkArgumentsOnCall(args, params, graph) {
|
|
|
109
108
|
for (let i = 0; i < remainingArguments.length; i++) {
|
|
110
109
|
const arg = remainingArguments[i];
|
|
111
110
|
if (arg === r_function_call_1.EmptyArgument) {
|
|
112
|
-
logger_1.dataflowLogger.trace(`skipping value argument for ${i}`);
|
|
113
111
|
continue;
|
|
114
112
|
}
|
|
115
113
|
if (remainingParameter.length <= i) {
|
|
116
114
|
if (specialDotParameter !== undefined) {
|
|
117
|
-
logger_1.dataflowLogger.trace(`mapping unnamed argument ${i} (id: ${arg.nodeId}) to dot-dot-dot parameter`);
|
|
118
115
|
graph.addEdge(arg.nodeId, specialDotParameter.name.info.id, edge_1.EdgeType.DefinesOnCall);
|
|
119
116
|
graph.addEdge(specialDotParameter.name.info.id, arg.nodeId, edge_1.EdgeType.DefinedByOnCall);
|
|
120
117
|
}
|
|
@@ -135,14 +132,13 @@ function linkFunctionCallArguments(targetId, idMap, functionCallName, functionRo
|
|
|
135
132
|
// we get them by just choosing the rhs of the definition
|
|
136
133
|
const linkedFunction = idMap.get(targetId);
|
|
137
134
|
if (linkedFunction === undefined) {
|
|
138
|
-
logger_1.dataflowLogger.trace(`no
|
|
135
|
+
logger_1.dataflowLogger.trace(`no fdef found for ${functionCallName} (${functionRootId})`);
|
|
139
136
|
return;
|
|
140
137
|
}
|
|
141
138
|
if (linkedFunction.type !== type_1.RType.FunctionDefinition) {
|
|
142
139
|
logger_1.dataflowLogger.trace(`function call definition base ${functionCallName} does not lead to a function definition (${functionRootId}) but got ${linkedFunction.type}`);
|
|
143
140
|
return;
|
|
144
141
|
}
|
|
145
|
-
(0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `linking arguments for ${functionCallName} (${functionRootId}) to ${JSON.stringify(linkedFunction.location)}`);
|
|
146
142
|
linkArgumentsOnCall(callArgs, linkedFunction.parameters, finalGraph);
|
|
147
143
|
}
|
|
148
144
|
/**
|
|
@@ -202,10 +198,8 @@ function linkFunctionCall(graph, id, info, idMap, thisGraph, calledFunctionDefin
|
|
|
202
198
|
*/
|
|
203
199
|
function linkFunctionCalls(graph, idMap, thisGraph) {
|
|
204
200
|
const calledFunctionDefinitions = [];
|
|
205
|
-
for (const [id, info] of thisGraph.
|
|
206
|
-
|
|
207
|
-
linkFunctionCall(graph, id, info, idMap, thisGraph, calledFunctionDefinitions);
|
|
208
|
-
}
|
|
201
|
+
for (const [id, info] of thisGraph.verticesOfType(vertex_1.VertexType.FunctionCall)) {
|
|
202
|
+
linkFunctionCall(graph, id, info, idMap, thisGraph, calledFunctionDefinitions);
|
|
209
203
|
}
|
|
210
204
|
return calledFunctionDefinitions;
|
|
211
205
|
}
|
|
@@ -2,5 +2,11 @@ import { type RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/
|
|
|
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
|
+
* @see {@link unpackArg} - to specifically retrieve non-named arguments
|
|
5
6
|
*/
|
|
6
|
-
export declare function
|
|
7
|
+
export declare function unpackNonameArg<OtherInfo>(arg: RFunctionArgument<OtherInfo> | undefined): RNode<OtherInfo> | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Retrieve the value from a non-named argument, if it is not empty.
|
|
10
|
+
* @see {@link unpackNonameArg} - to specifically retrieve non-named arguments
|
|
11
|
+
*/
|
|
12
|
+
export declare function unpackArg<OtherInfo>(arg: RFunctionArgument<OtherInfo> | undefined): RNode<OtherInfo> | undefined;
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.unpackNonameArg = unpackNonameArg;
|
|
4
|
+
exports.unpackArg = unpackArg;
|
|
4
5
|
const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
5
6
|
/**
|
|
6
7
|
* Retrieve the value from an argument, if it is not empty.
|
|
8
|
+
* @see {@link unpackArg} - to specifically retrieve non-named arguments
|
|
7
9
|
*/
|
|
8
|
-
function
|
|
9
|
-
return arg ===
|
|
10
|
+
function unpackNonameArg(arg) {
|
|
11
|
+
return arg === r_function_call_1.EmptyArgument || arg?.name !== undefined ? undefined : arg?.value;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Retrieve the value from a non-named argument, if it is not empty.
|
|
15
|
+
* @see {@link unpackNonameArg} - to specifically retrieve non-named arguments
|
|
16
|
+
*/
|
|
17
|
+
function unpackArg(arg) {
|
|
18
|
+
return arg === r_function_call_1.EmptyArgument ? undefined : arg?.value;
|
|
10
19
|
}
|
|
11
20
|
//# sourceMappingURL=unpack-argument.js.map
|