@eagleoutice/flowr 2.9.13 → 2.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -28
- package/abstract-interpretation/absint-visitor.d.ts +1 -1
- package/abstract-interpretation/absint-visitor.js +20 -20
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +2 -2
- package/benchmark/slicer.d.ts +1 -1
- package/benchmark/slicer.js +7 -5
- package/benchmark/stats/stats.d.ts +2 -2
- package/cli/repl/commands/repl-dataflow.js +5 -5
- package/cli/repl/parser/slice-query-parser.d.ts +3 -3
- package/cli/repl/parser/slice-query-parser.js +2 -2
- package/cli/repl/server/connection.js +2 -2
- package/cli/repl/server/messages/message-slice.d.ts +1 -1
- package/cli/repl/server/messages/message-slice.js +2 -2
- package/config.d.ts +12 -8
- package/config.js +5 -3
- package/control-flow/extract-cfg.js +2 -2
- package/control-flow/semantic-cfg-guided-visitor.d.ts +1 -1
- package/control-flow/semantic-cfg-guided-visitor.js +43 -43
- package/control-flow/useless-loop.d.ts +1 -1
- package/control-flow/useless-loop.js +3 -3
- package/core/print/dataflow-printer.d.ts +0 -14
- package/core/print/dataflow-printer.js +0 -21
- package/core/steps/all/core/20-dataflow.d.ts +3 -3
- package/core/steps/all/core/20-dataflow.js +3 -2
- package/core/steps/all/static-slicing/00-slice.d.ts +2 -5
- package/core/steps/all/static-slicing/00-slice.js +6 -8
- package/core/steps/pipeline/default-pipelines.d.ts +89 -89
- package/dataflow/environments/built-in-proc-name.d.ts +83 -0
- package/dataflow/environments/built-in-proc-name.js +88 -0
- package/dataflow/environments/built-in.d.ts +1 -83
- package/dataflow/environments/built-in.js +37 -120
- package/dataflow/environments/default-builtin-config.d.ts +1 -1
- package/dataflow/environments/default-builtin-config.js +75 -75
- package/dataflow/environments/identifier.d.ts +5 -0
- package/dataflow/environments/identifier.js +18 -0
- package/dataflow/eval/resolve/resolve.js +2 -2
- package/dataflow/fn/exceptions-of-function.d.ts +1 -1
- package/dataflow/fn/exceptions-of-function.js +2 -2
- package/dataflow/graph/call-graph.d.ts +46 -19
- package/dataflow/graph/call-graph.js +95 -114
- package/dataflow/graph/dataflowgraph-builder.d.ts +1 -1
- package/dataflow/graph/dataflowgraph-builder.js +2 -2
- package/dataflow/graph/df-helper.d.ts +133 -0
- package/dataflow/graph/df-helper.js +138 -0
- package/dataflow/graph/diff-dataflow-graph.d.ts +5 -10
- package/dataflow/graph/diff-dataflow-graph.js +3 -28
- package/dataflow/graph/edge.d.ts +1 -0
- package/dataflow/graph/edge.js +1 -0
- package/dataflow/graph/graph-helper.d.ts +60 -0
- package/dataflow/graph/graph-helper.js +128 -0
- package/dataflow/graph/graph.d.ts +19 -3
- package/dataflow/graph/graph.js +32 -5
- package/dataflow/graph/vertex.d.ts +3 -1
- package/dataflow/info.d.ts +14 -4
- package/dataflow/info.js +28 -16
- package/dataflow/internal/linker.d.ts +14 -10
- package/dataflow/internal/linker.js +29 -32
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +5 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +8 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +2 -2
- 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.js +6 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-get.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-library.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-local.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-local.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-recall.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +5 -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-s-seven-dispatch.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.js +7 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.js +6 -9
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +2 -2
- package/dataflow/internal/process/functions/call/common.js +2 -1
- package/dataflow/internal/process/functions/call/known-call-handling.js +2 -2
- package/dataflow/internal/process/functions/call/named-call-handling.d.ts +1 -1
- package/dataflow/internal/process/functions/call/named-call-handling.js +1 -1
- package/dataflow/internal/process/functions/call/unnamed-call-handling.js +2 -2
- package/dataflow/internal/process/functions/process-parameter.js +1 -1
- package/dataflow/internal/process/process-uninteresting-leaf.d.ts +1 -1
- package/dataflow/internal/process/process-uninteresting-leaf.js +1 -1
- package/dataflow/origin/dfg-get-origin.d.ts +1 -1
- package/dataflow/origin/dfg-get-symbol-refs.js +6 -6
- package/documentation/doc-readme.js +2 -1
- package/documentation/doc-util/doc-dfg.d.ts +3 -0
- package/documentation/doc-util/doc-dfg.js +5 -7
- package/documentation/doc-util/doc-normalized-ast.d.ts +0 -6
- package/documentation/doc-util/doc-normalized-ast.js +0 -23
- package/documentation/doc-util/doc-structure.js +3 -3
- package/documentation/doc-util/doc-types.js +3 -3
- package/documentation/wiki-core.js +5 -4
- package/documentation/wiki-dataflow-graph.js +14 -12
- package/documentation/wiki-interface.js +3 -3
- package/documentation/wiki-linter.js +6 -0
- package/documentation/wiki-normalized-ast.js +5 -4
- package/documentation/wiki-query.js +28 -3
- package/linter/linter-rules.d.ts +49 -1
- package/linter/linter-rules.js +5 -1
- package/linter/rules/problematic-eval.d.ts +44 -0
- package/linter/rules/problematic-eval.js +83 -0
- package/linter/rules/seeded-randomness.js +2 -2
- package/linter/rules/stop-with-call-arg.d.ts +35 -0
- package/linter/rules/stop-with-call-arg.js +72 -0
- package/linter/rules/useless-loop.d.ts +1 -1
- package/package.json +7 -7
- package/project/cache/flowr-analyzer-cache.d.ts +1 -1
- package/project/cache/flowr-analyzer-cache.js +1 -1
- package/project/flowr-analyzer-builder.d.ts +3 -0
- package/project/flowr-analyzer.d.ts +1 -1
- package/queries/catalog/call-context-query/identify-link-to-nested-call-relation.js +2 -2
- package/queries/catalog/call-graph-query/call-graph-query-format.d.ts +1 -1
- package/queries/catalog/call-graph-query/call-graph-query-format.js +2 -2
- package/queries/catalog/cluster-query/cluster-query-format.js +2 -2
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +2 -2
- package/queries/catalog/dataflow-query/dataflow-query-format.js +2 -2
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +1 -2
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +3 -3
- package/queries/catalog/does-call-query/does-call-query-executor.js +2 -2
- package/queries/catalog/does-call-query/does-call-query-format.d.ts +2 -2
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -2
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +3 -3
- package/queries/catalog/input-sources-query/input-sources-query-executor.d.ts +6 -0
- package/queries/catalog/input-sources-query/input-sources-query-executor.js +66 -0
- package/queries/catalog/input-sources-query/input-sources-query-format.d.ts +36 -0
- package/queries/catalog/input-sources-query/input-sources-query-format.js +63 -0
- package/queries/catalog/input-sources-query/simple-input-classifier.d.ts +90 -0
- package/queries/catalog/input-sources-query/simple-input-classifier.js +308 -0
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +2 -2
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +1 -1
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +2 -2
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -3
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +2 -2
- package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +2 -2
- package/queries/catalog/location-map-query/location-map-query-executor.js +2 -2
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +2 -2
- package/queries/catalog/origin-query/origin-query-executor.d.ts +2 -2
- package/queries/catalog/origin-query/origin-query-executor.js +3 -3
- package/queries/catalog/origin-query/origin-query-format.d.ts +3 -3
- package/queries/catalog/provenance-query/provenance-query-executor.d.ts +6 -0
- package/queries/catalog/provenance-query/provenance-query-executor.js +34 -0
- package/queries/catalog/provenance-query/provenance-query-format.d.ts +35 -0
- package/queries/catalog/provenance-query/provenance-query-format.js +62 -0
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +2 -2
- package/queries/catalog/search-query/search-query-format.js +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +4 -2
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +2 -2
- package/queries/catalog/static-slice-query/static-slice-query-format.js +3 -3
- package/queries/query.d.ts +17 -1
- package/queries/query.js +4 -0
- package/r-bridge/lang-4.x/ast/model/model.d.ts +9 -0
- package/r-bridge/lang-4.x/ast/model/model.js +10 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +15 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +15 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +29 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +29 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.js +2 -0
- package/search/flowr-search-filters.d.ts +1 -1
- package/search/flowr-search-printer.js +3 -3
- package/search/search-executor/search-enrichers.js +2 -2
- package/search/search-executor/search-generators.js +1 -1
- package/slicing/criterion/parse.d.ts +43 -18
- package/slicing/criterion/parse.js +68 -63
- package/slicing/static/slicer-types.d.ts +2 -3
- package/slicing/static/static-slicer.d.ts +3 -4
- package/slicing/static/static-slicer.js +32 -12
- package/util/collections/arrays.d.ts +4 -0
- package/util/collections/arrays.js +7 -0
- package/util/diff.d.ts +2 -2
- package/util/mermaid/ast.js +4 -4
- package/util/mermaid/cfg.js +5 -5
- package/util/mermaid/dfg.d.ts +33 -18
- package/util/mermaid/dfg.js +47 -31
- package/util/mermaid/mermaid.d.ts +57 -12
- package/util/mermaid/mermaid.js +74 -67
- package/util/range.d.ts +8 -0
- package/util/range.js +13 -1
- package/util/slice-direction.d.ts +7 -0
- package/util/slice-direction.js +12 -0
- package/util/version.js +1 -1
- package/dataflow/graph/invert-dfg.d.ts +0 -6
- package/dataflow/graph/invert-dfg.js +0 -20
- package/dataflow/graph/resolve-graph.d.ts +0 -8
- package/dataflow/graph/resolve-graph.js +0 -59
|
@@ -1,30 +1,57 @@
|
|
|
1
1
|
import { DataflowGraph } from './graph';
|
|
2
2
|
import type { DataflowGraphVertexFunctionCall, DataflowGraphVertexFunctionDefinition } from './vertex';
|
|
3
|
+
import type { REnvironmentInformation } from '../environments/environment';
|
|
3
4
|
import { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
4
5
|
import { DefaultMap } from '../../util/collections/defaultmap';
|
|
5
6
|
/**
|
|
6
7
|
* A call graph is a dataflow graph where all vertices are function calls.
|
|
7
|
-
* You can create a call graph from a dataflow graph using {@link
|
|
8
|
-
* If you want to extract a sub call graph, use {@link
|
|
8
|
+
* You can create a call graph from a dataflow graph using {@link CallGraph.compute}.
|
|
9
|
+
* If you want to extract a sub call graph, use {@link CallGraph.computeSubCallGraph}.
|
|
9
10
|
* @see {@link dropTransitiveEdges} - to reduce the call graph by dropping transitive edges
|
|
10
11
|
*/
|
|
11
12
|
export type CallGraph = DataflowGraph<Required<DataflowGraphVertexFunctionCall | DataflowGraphVertexFunctionDefinition>>;
|
|
13
|
+
export interface State {
|
|
14
|
+
visited: Set<NodeId>;
|
|
15
|
+
potentials: [NodeId, Set<NodeId>][];
|
|
16
|
+
}
|
|
12
17
|
/**
|
|
13
|
-
*
|
|
18
|
+
* Helper object for call-graphs, you can compute new call graphs based on {@link CallGraph.compute}.
|
|
19
|
+
* @see {@link Dataflow}
|
|
20
|
+
* @see {@link CallGraph}
|
|
14
21
|
*/
|
|
15
|
-
export declare
|
|
16
|
-
/**
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
export declare const CallGraph: {
|
|
23
|
+
/**
|
|
24
|
+
* Extracts the sub call graph from the given call graph, starting from the given entry points.
|
|
25
|
+
*/
|
|
26
|
+
readonly computeSubCallGraph: (this: void, graph: CallGraph, entryPoints: Set<NodeId>) => CallGraph;
|
|
27
|
+
/**
|
|
28
|
+
* Reduces the call graph by dropping all transitive edges.
|
|
29
|
+
*/
|
|
30
|
+
readonly dropTransitiveEdges: (this: void, graph: CallGraph) => CallGraph;
|
|
31
|
+
/**
|
|
32
|
+
* Computes the call graph from the given dataflow graph.
|
|
33
|
+
* @see {@link CallGraph} - for details
|
|
34
|
+
* @see {@link CallGraph.computeSubCallGraph} - to extract sub call graphs
|
|
35
|
+
* @see {@link CallGraph.dropTransitiveEdges} - to reduce the call graph by dropping transitive edges
|
|
36
|
+
*/
|
|
37
|
+
readonly compute: (this: void, graph: DataflowGraph) => CallGraph;
|
|
38
|
+
readonly visualize: {
|
|
39
|
+
readonly mermaid: {
|
|
40
|
+
readonly name: "DataflowMermaid";
|
|
41
|
+
readonly convert: (this: void, config: import("../../util/mermaid/dfg").MermaidGraphConfiguration) => {
|
|
42
|
+
string: string;
|
|
43
|
+
mermaid: import("../../util/mermaid/dfg").MermaidGraph;
|
|
44
|
+
};
|
|
45
|
+
readonly raw: (this: void, graph: DataflowGraph | import("../info").DataflowInformation, includeEnvironments?: boolean, mark?: ReadonlySet<NodeId>, simplified?: boolean) => string;
|
|
46
|
+
readonly url: (this: void, graph: DataflowGraph | import("../info").DataflowInformation, includeEnvironments?: boolean, mark?: ReadonlySet<NodeId>, simplified?: boolean) => string;
|
|
47
|
+
};
|
|
48
|
+
readonly quads: {
|
|
49
|
+
readonly convert: typeof import("./quads").df2quads;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
readonly diffGraphs: <G extends DataflowGraph>(this: void, left: import("../../util/diff-graph").NamedGraph<G>, right: import("../../util/diff-graph").NamedGraph<G>, config?: Partial<import("../../util/diff").GenericDiffConfiguration>) => import("../../util/diff-graph").GraphDifferenceReport;
|
|
53
|
+
readonly invertGraph: <G extends DataflowGraph>(this: void, graph: G, cleanEnv: REnvironmentInformation) => G;
|
|
54
|
+
readonly resolveGraphCriteria: <G extends DataflowGraph>(graph: G, ctx: import("../../project/context/flowr-analyzer-context").ReadOnlyFlowrAnalyzerContext, idMap?: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").AstIdMap) => G;
|
|
55
|
+
readonly reaches: <G extends DataflowGraph>(this: void, from: NodeId, to: NodeId, graph: G, knownReachability?: DefaultMap<NodeId, Set<NodeId>>) => boolean;
|
|
56
|
+
readonly name: "CallGraph";
|
|
57
|
+
};
|
|
@@ -1,124 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.reaches = reaches;
|
|
5
|
-
exports.dropTransitiveEdges = dropTransitiveEdges;
|
|
6
|
-
exports.computeCallGraph = computeCallGraph;
|
|
3
|
+
exports.CallGraph = void 0;
|
|
7
4
|
const graph_1 = require("./graph");
|
|
8
5
|
const vertex_1 = require("./vertex");
|
|
9
6
|
const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
|
|
10
7
|
const linker_1 = require("../internal/linker");
|
|
11
8
|
const edge_1 = require("./edge");
|
|
12
|
-
const
|
|
9
|
+
const built_in_proc_name_1 = require("../environments/built-in-proc-name");
|
|
13
10
|
const defaultmap_1 = require("../../util/collections/defaultmap");
|
|
14
|
-
|
|
15
|
-
* Extracts the sub call graph from the given call graph, starting from the given entry points.
|
|
16
|
-
*/
|
|
17
|
-
function getSubCallGraph(graph, entryPoints) {
|
|
18
|
-
const result = new graph_1.DataflowGraph(graph.idMap);
|
|
19
|
-
const toVisit = Array.from(entryPoints);
|
|
20
|
-
const visited = new Set();
|
|
21
|
-
while (toVisit.length > 0) {
|
|
22
|
-
const currentId = toVisit.pop();
|
|
23
|
-
if (visited.has(currentId)) {
|
|
24
|
-
continue;
|
|
25
|
-
}
|
|
26
|
-
visited.add(currentId);
|
|
27
|
-
const currentVtx = graph.getVertex(currentId);
|
|
28
|
-
if (!currentVtx) {
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
result.addVertex(currentVtx, undefined, true);
|
|
32
|
-
for (const [tar, e] of graph.outgoingEdges(currentId) ?? []) {
|
|
33
|
-
if (edge_1.DfEdge.includesType(e, edge_1.EdgeType.Calls)) {
|
|
34
|
-
result.addEdge(currentId, tar, edge_1.EdgeType.Calls);
|
|
35
|
-
toVisit.push(tar);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return result;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Determines whether there is a path from `from` to `to` in the given graph (via any edge type, only respecting direction)
|
|
43
|
-
*/
|
|
44
|
-
function reaches(from, to, graph, knownReachability = new defaultmap_1.DefaultMap(() => new Set())) {
|
|
45
|
-
const visited = new Set();
|
|
46
|
-
const toVisit = [from];
|
|
47
|
-
while (toVisit.length > 0) {
|
|
48
|
-
const currentId = toVisit.pop();
|
|
49
|
-
if (visited.has(currentId)) {
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
if (currentId === to) {
|
|
53
|
-
knownReachability.get(from).add(to);
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
else if (knownReachability.get(currentId).has(to)) {
|
|
57
|
-
knownReachability.get(from).add(to);
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
visited.add(currentId);
|
|
61
|
-
for (const [tar] of graph.outgoingEdges(currentId) ?? []) {
|
|
62
|
-
toVisit.push(tar);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Reduces the call graph by dropping all transitive edges.
|
|
69
|
-
*/
|
|
70
|
-
function dropTransitiveEdges(graph) {
|
|
71
|
-
const newCg = new graph_1.DataflowGraph(graph.idMap);
|
|
72
|
-
newCg.mergeVertices(graph);
|
|
73
|
-
const knownReachability = new defaultmap_1.DefaultMap(() => new Set());
|
|
74
|
-
// heuristically sort by dif in ids
|
|
75
|
-
const es = Array.from(graph.edges(), ([e, ts]) => ts.entries().map(([t, { types }]) => [e, t, types]).toArray()).flat()
|
|
76
|
-
.sort((a, b) => String(a[0]).localeCompare(String(a[1])) - String(b[0]).localeCompare(String(b[1])));
|
|
77
|
-
for (const [from, to, types] of es) {
|
|
78
|
-
if (!reaches(from, to, newCg, knownReachability)) {
|
|
79
|
-
newCg.addEdge(from, to, types);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return newCg;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Computes the call graph from the given dataflow graph.
|
|
86
|
-
* @see {@link CallGraph} - for details
|
|
87
|
-
* @see {@link getSubCallGraph} - to extract sub call graphs
|
|
88
|
-
* @see {@link dropTransitiveEdges} - to reduce the call graph by dropping transitive edges
|
|
89
|
-
*/
|
|
90
|
-
function computeCallGraph(graph) {
|
|
91
|
-
const result = new graph_1.DataflowGraph(graph.idMap);
|
|
92
|
-
const state = {
|
|
93
|
-
visited: new Set(),
|
|
94
|
-
potentials: []
|
|
95
|
-
};
|
|
96
|
-
for (const [, vert] of graph.vertices(false)) {
|
|
97
|
-
if (vert.tag === vertex_1.VertexType.FunctionCall) {
|
|
98
|
-
processCall(vert, undefined, graph, result, state);
|
|
99
|
-
}
|
|
100
|
-
else if (vert.tag === vertex_1.VertexType.FunctionDefinition) {
|
|
101
|
-
processFunctionDefinition(vert, undefined, graph, result, state);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
for (const [from, tos] of state.potentials) {
|
|
105
|
-
for (const to of tos) {
|
|
106
|
-
if (!result.hasVertex(to)) {
|
|
107
|
-
const v = graph.getVertex(to);
|
|
108
|
-
if (v) {
|
|
109
|
-
processUnknown(v, from, graph, result, state);
|
|
110
|
-
if (v.tag === vertex_1.VertexType.FunctionDefinition) {
|
|
111
|
-
processFunctionDefinition(v, from, graph, result, state);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
result.addEdge(from, to, edge_1.EdgeType.Calls);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return result;
|
|
121
|
-
}
|
|
11
|
+
const graph_helper_1 = require("./graph-helper");
|
|
122
12
|
function processCds(vtx, graph, result, state) {
|
|
123
13
|
for (const tar of vtx.cds ?? []) {
|
|
124
14
|
const targetVtx = graph.getVertex(tar.id);
|
|
@@ -213,7 +103,7 @@ function processCall(vtx, from, graph, result, state) {
|
|
|
213
103
|
tag: vertex_1.VertexType.FunctionCall,
|
|
214
104
|
name: name.lexeme,
|
|
215
105
|
onlyBuiltin: false,
|
|
216
|
-
origin: [
|
|
106
|
+
origin: [built_in_proc_name_1.BuiltInProcName.Function],
|
|
217
107
|
args: []
|
|
218
108
|
}, oriVtx.environment);
|
|
219
109
|
}
|
|
@@ -264,4 +154,95 @@ function processFunctionDefinition(vtx, from, graph, result, state) {
|
|
|
264
154
|
}
|
|
265
155
|
}
|
|
266
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Helper object for call-graphs, you can compute new call graphs based on {@link CallGraph.compute}.
|
|
159
|
+
* @see {@link Dataflow}
|
|
160
|
+
* @see {@link CallGraph}
|
|
161
|
+
*/
|
|
162
|
+
exports.CallGraph = {
|
|
163
|
+
name: 'CallGraph',
|
|
164
|
+
...graph_helper_1.GraphHelper,
|
|
165
|
+
/**
|
|
166
|
+
* Extracts the sub call graph from the given call graph, starting from the given entry points.
|
|
167
|
+
*/
|
|
168
|
+
computeSubCallGraph(graph, entryPoints) {
|
|
169
|
+
const result = new graph_1.DataflowGraph(graph.idMap);
|
|
170
|
+
const toVisit = Array.from(entryPoints);
|
|
171
|
+
const visited = new Set();
|
|
172
|
+
while (toVisit.length > 0) {
|
|
173
|
+
const currentId = toVisit.pop();
|
|
174
|
+
if (visited.has(currentId)) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
visited.add(currentId);
|
|
178
|
+
const currentVtx = graph.getVertex(currentId);
|
|
179
|
+
if (!currentVtx) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
result.addVertex(currentVtx, undefined, true);
|
|
183
|
+
for (const [tar, e] of graph.outgoingEdges(currentId) ?? []) {
|
|
184
|
+
if (edge_1.DfEdge.includesType(e, edge_1.EdgeType.Calls)) {
|
|
185
|
+
result.addEdge(currentId, tar, edge_1.EdgeType.Calls);
|
|
186
|
+
toVisit.push(tar);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return result;
|
|
191
|
+
},
|
|
192
|
+
/**
|
|
193
|
+
* Reduces the call graph by dropping all transitive edges.
|
|
194
|
+
*/
|
|
195
|
+
dropTransitiveEdges(graph) {
|
|
196
|
+
const newCg = new graph_1.DataflowGraph(graph.idMap);
|
|
197
|
+
newCg.mergeVertices(graph);
|
|
198
|
+
const knownReachability = new defaultmap_1.DefaultMap(() => new Set());
|
|
199
|
+
// heuristically sort by dif in ids
|
|
200
|
+
const es = Array.from(graph.edges(), ([e, ts]) => ts.entries().map(([t, { types }]) => [e, t, types]).toArray()).flat()
|
|
201
|
+
.sort((a, b) => String(a[0]).localeCompare(String(a[1])) - String(b[0]).localeCompare(String(b[1])));
|
|
202
|
+
for (const [from, to, types] of es) {
|
|
203
|
+
if (!exports.CallGraph.reaches(from, to, newCg, knownReachability)) {
|
|
204
|
+
newCg.addEdge(from, to, types);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return newCg;
|
|
208
|
+
},
|
|
209
|
+
/**
|
|
210
|
+
* Computes the call graph from the given dataflow graph.
|
|
211
|
+
* @see {@link CallGraph} - for details
|
|
212
|
+
* @see {@link CallGraph.computeSubCallGraph} - to extract sub call graphs
|
|
213
|
+
* @see {@link CallGraph.dropTransitiveEdges} - to reduce the call graph by dropping transitive edges
|
|
214
|
+
*/
|
|
215
|
+
compute(graph) {
|
|
216
|
+
const result = new graph_1.DataflowGraph(graph.idMap);
|
|
217
|
+
const state = {
|
|
218
|
+
visited: new Set(),
|
|
219
|
+
potentials: []
|
|
220
|
+
};
|
|
221
|
+
for (const [, vert] of graph.vertices(false)) {
|
|
222
|
+
if (vert.tag === vertex_1.VertexType.FunctionCall) {
|
|
223
|
+
processCall(vert, undefined, graph, result, state);
|
|
224
|
+
}
|
|
225
|
+
else if (vert.tag === vertex_1.VertexType.FunctionDefinition) {
|
|
226
|
+
processFunctionDefinition(vert, undefined, graph, result, state);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
for (const [from, tos] of state.potentials) {
|
|
230
|
+
for (const to of tos) {
|
|
231
|
+
if (!result.hasVertex(to)) {
|
|
232
|
+
const v = graph.getVertex(to);
|
|
233
|
+
if (v) {
|
|
234
|
+
processUnknown(v, from, graph, result, state);
|
|
235
|
+
if (v.tag === vertex_1.VertexType.FunctionDefinition) {
|
|
236
|
+
processFunctionDefinition(v, from, graph, result, state);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
result.addEdge(from, to, edge_1.EdgeType.Calls);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
267
248
|
//# sourceMappingURL=call-graph.js.map
|
|
@@ -12,7 +12,7 @@ import type { HookInformation } from '../hooks';
|
|
|
12
12
|
* Creates an empty dataflow graph.
|
|
13
13
|
* Should only be used in tests and documentation.
|
|
14
14
|
*/
|
|
15
|
-
export declare function emptyGraph(cleanEnv?: REnvironmentInformation, idMap?: AstIdMap): DataflowGraphBuilder<DataflowGraphVertexInfo>;
|
|
15
|
+
export declare function emptyGraph(this: void, cleanEnv?: REnvironmentInformation, idMap?: AstIdMap): DataflowGraphBuilder<DataflowGraphVertexInfo>;
|
|
16
16
|
export type DataflowGraphEdgeTarget = NodeId | (readonly NodeId[]);
|
|
17
17
|
/**
|
|
18
18
|
* This DataflowGraphBuilder extends {@link DataflowGraph} with builder methods to
|
|
@@ -8,12 +8,12 @@ const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id"
|
|
|
8
8
|
const graph_1 = require("./graph");
|
|
9
9
|
const vertex_1 = require("./vertex");
|
|
10
10
|
const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
11
|
-
const built_in_1 = require("../environments/built-in");
|
|
12
11
|
const edge_1 = require("./edge");
|
|
13
12
|
const default_builtin_config_1 = require("../environments/default-builtin-config");
|
|
14
13
|
const flowr_search_executor_1 = require("../../search/flowr-search-executor");
|
|
15
14
|
const assert_1 = require("../../util/assert");
|
|
16
15
|
const flowr_analyzer_context_1 = require("../../project/context/flowr-analyzer-context");
|
|
16
|
+
const built_in_proc_name_1 = require("../environments/built-in-proc-name");
|
|
17
17
|
/**
|
|
18
18
|
* Creates an empty dataflow graph.
|
|
19
19
|
* Should only be used in tests and documentation.
|
|
@@ -85,7 +85,7 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
|
|
|
85
85
|
environment: (info?.onlyBuiltIn || onlyBuiltInAuto) ? undefined : info?.environment ?? this.defaultEnvironment,
|
|
86
86
|
cds: info?.cds?.map(c => ({ ...c, id: node_id_1.NodeId.normalize(c.id) })),
|
|
87
87
|
onlyBuiltin: info?.onlyBuiltIn ?? onlyBuiltInAuto ?? false,
|
|
88
|
-
origin: info?.origin ?? [(0, default_builtin_config_1.getDefaultProcessor)(name) ??
|
|
88
|
+
origin: info?.origin ?? [(0, default_builtin_config_1.getDefaultProcessor)(name) ?? built_in_proc_name_1.BuiltInProcName.Function],
|
|
89
89
|
link: info?.link
|
|
90
90
|
}, asRoot);
|
|
91
91
|
if (!info?.omitArgs) {
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { DataflowGraph } from './graph';
|
|
2
|
+
import { EdgeType } from './edge';
|
|
3
|
+
import { emptyGraph } from './dataflowgraph-builder';
|
|
4
|
+
import { getOriginInDfg } from '../origin/dfg-get-origin';
|
|
5
|
+
import { CallGraph } from './call-graph';
|
|
6
|
+
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
7
|
+
import type { REnvironmentInformation } from '../environments/environment';
|
|
8
|
+
/**
|
|
9
|
+
* This is the root helper object to work with the {@link DataflowGraph}.
|
|
10
|
+
*
|
|
11
|
+
* - {@link Dataflow.visualize} - for visualization helpers (e.g., rendering the DFG as a mermaid graph),
|
|
12
|
+
* - {@link Dataflow.views} - for working with specific views of the dataflow graph (e.g., the call graph),
|
|
13
|
+
* - {@link Dataflow.edge} - for working with the edges in the dataflow graph,
|
|
14
|
+
*/
|
|
15
|
+
export declare const Dataflow: {
|
|
16
|
+
/**
|
|
17
|
+
* Maps to flowR's dataflow edge helper to work with the edges in the dataflow graph
|
|
18
|
+
*/
|
|
19
|
+
readonly edge: {
|
|
20
|
+
readonly name: "DfEdge";
|
|
21
|
+
readonly typesToNames: (this: void, { types }: {
|
|
22
|
+
types: number;
|
|
23
|
+
}) => Set<import("./edge").EdgeTypeName>;
|
|
24
|
+
readonly splitTypes: (this: void, { types }: {
|
|
25
|
+
types: number;
|
|
26
|
+
}) => EdgeType[];
|
|
27
|
+
readonly typeToName: (this: void, type: EdgeType) => string;
|
|
28
|
+
readonly includesType: (this: void, { types }: {
|
|
29
|
+
types: number;
|
|
30
|
+
}, typesToInclude: EdgeType) => boolean;
|
|
31
|
+
readonly doesNotIncludeType: (this: void, { types }: {
|
|
32
|
+
types: number;
|
|
33
|
+
}, any: EdgeType) => boolean;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Dispatches to helper objects that relate to (sub-) views of the dataflow graph, e.g. the call graph.
|
|
37
|
+
*/
|
|
38
|
+
readonly views: {
|
|
39
|
+
/**
|
|
40
|
+
* Maps to flowR's helper object for the call-graph
|
|
41
|
+
*/
|
|
42
|
+
readonly callGraph: {
|
|
43
|
+
readonly computeSubCallGraph: (this: void, graph: CallGraph, entryPoints: Set<NodeId>) => CallGraph;
|
|
44
|
+
readonly dropTransitiveEdges: (this: void, graph: CallGraph) => CallGraph;
|
|
45
|
+
readonly compute: (this: void, graph: DataflowGraph) => CallGraph;
|
|
46
|
+
readonly visualize: {
|
|
47
|
+
readonly mermaid: {
|
|
48
|
+
readonly name: "DataflowMermaid";
|
|
49
|
+
readonly convert: (this: void, config: import("../../util/mermaid/dfg").MermaidGraphConfiguration) => {
|
|
50
|
+
string: string;
|
|
51
|
+
mermaid: import("../../util/mermaid/dfg").MermaidGraph;
|
|
52
|
+
};
|
|
53
|
+
readonly raw: (this: void, graph: DataflowGraph | import("../info").DataflowInformation, includeEnvironments?: boolean, mark?: ReadonlySet<NodeId>, simplified?: boolean) => string;
|
|
54
|
+
readonly url: (this: void, graph: DataflowGraph | import("../info").DataflowInformation, includeEnvironments?: boolean, mark?: ReadonlySet<NodeId>, simplified?: boolean) => string;
|
|
55
|
+
};
|
|
56
|
+
readonly quads: {
|
|
57
|
+
readonly convert: typeof import("./quads").df2quads;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
readonly diffGraphs: <G extends DataflowGraph>(this: void, left: import("../../util/diff-graph").NamedGraph<G>, right: import("../../util/diff-graph").NamedGraph<G>, config?: Partial<import("../../util/diff").GenericDiffConfiguration>) => import("../../util/diff-graph").GraphDifferenceReport;
|
|
61
|
+
readonly invertGraph: <G extends DataflowGraph>(this: void, graph: G, cleanEnv: REnvironmentInformation) => G;
|
|
62
|
+
readonly resolveGraphCriteria: <G extends DataflowGraph>(graph: G, ctx: import("../../project/context/flowr-analyzer-context").ReadOnlyFlowrAnalyzerContext, idMap?: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").AstIdMap) => G;
|
|
63
|
+
readonly reaches: <G extends DataflowGraph>(this: void, from: NodeId, to: NodeId, graph: G, knownReachability?: import("../../util/collections/defaultmap").DefaultMap<NodeId, Set<NodeId>>) => boolean;
|
|
64
|
+
readonly name: "CallGraph";
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Dispatches to helper functions to create new dataflow graphs, e.g. from a pipeline or an empty graph.
|
|
69
|
+
*/
|
|
70
|
+
readonly create: {
|
|
71
|
+
/**
|
|
72
|
+
* Creates an empty dataflow graph with the given id map (or a new one if not provided).
|
|
73
|
+
* @see {@link emptyGraph}
|
|
74
|
+
*/
|
|
75
|
+
readonly empty: typeof emptyGraph;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Returns the origin of a vertex in the dataflow graph
|
|
79
|
+
* @see {@link getOriginInDfg} - for the underlying function
|
|
80
|
+
*/
|
|
81
|
+
readonly origin: typeof getOriginInDfg;
|
|
82
|
+
/**
|
|
83
|
+
* Only returns the sub-part of the graph that is determined by the given selection.
|
|
84
|
+
* In other words, this will return a graph with only vertices that are part of the selected ids,
|
|
85
|
+
* and edges that are between such selected vertices.
|
|
86
|
+
* @param graph - the dataflow graph to slice for
|
|
87
|
+
* @param select - the ids to select in the reduced graph
|
|
88
|
+
* @param includeMissingTargets - if set to true, this will include edges which target vertices that are not selected!
|
|
89
|
+
*/
|
|
90
|
+
readonly reduceGraph: <G extends DataflowGraph>(this: void, graph: G, select: ReadonlySet<NodeId>, includeMissingTargets?: boolean) => G;
|
|
91
|
+
/**
|
|
92
|
+
* Given the id of a vertex (usually a variable use),
|
|
93
|
+
* this returns a reachable provenance set by calculating a non-interprocedural and non-context sensitive backward slice, but stopping at the given ids!
|
|
94
|
+
* You can obtain the corresponding graph using {@link Dataflow.reduceGraph}.
|
|
95
|
+
* @param id - The id to use as a seed for provenance calculation
|
|
96
|
+
* @param graph - The graph to perform the provenance calculation on
|
|
97
|
+
* @param consider - The ids to restrict the calculation too (e.g., the ids contained within a function definition to restrict the analysis to)
|
|
98
|
+
* @see {@link Dataflow.provenanceGraph} - for a convenience wrapper to directly obtain the graph of the provenance.
|
|
99
|
+
*/
|
|
100
|
+
readonly provenance: (this: void, id: NodeId, graph: DataflowGraph, consider?: ReadonlySet<NodeId>) => Set<NodeId>;
|
|
101
|
+
/**
|
|
102
|
+
* A convenience wrapper for {@link Dataflow.reduceGraph|reducing} the {@link Dataflow.provenance|provenance} of a graph.
|
|
103
|
+
* @param id - The id to use as a seed for provenance calculation
|
|
104
|
+
* @param graph - The graph to perform the provenance calculation on
|
|
105
|
+
* @param consider - The ids to restrict the calculation too (e.g., the ids contained within a function definition to restrict the analysis to)
|
|
106
|
+
* @see {@link Dataflow.provenance}
|
|
107
|
+
*/
|
|
108
|
+
readonly provenanceGraph: (this: void, id: NodeId, graph: DataflowGraph, consider?: ReadonlySet<NodeId>) => DataflowGraph;
|
|
109
|
+
readonly visualize: {
|
|
110
|
+
readonly mermaid: {
|
|
111
|
+
readonly name: "DataflowMermaid";
|
|
112
|
+
readonly convert: (this: void, config: import("../../util/mermaid/dfg").MermaidGraphConfiguration) => {
|
|
113
|
+
string: string;
|
|
114
|
+
mermaid: import("../../util/mermaid/dfg").MermaidGraph;
|
|
115
|
+
};
|
|
116
|
+
readonly raw: (this: void, graph: DataflowGraph | import("../info").DataflowInformation, includeEnvironments?: boolean, mark?: ReadonlySet<NodeId>, simplified?: boolean) => string;
|
|
117
|
+
readonly url: (this: void, graph: DataflowGraph | import("../info").DataflowInformation, includeEnvironments?: boolean, mark?: ReadonlySet<NodeId>, simplified?: boolean) => string;
|
|
118
|
+
};
|
|
119
|
+
readonly quads: {
|
|
120
|
+
readonly convert: typeof import("./quads").df2quads;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
readonly diffGraphs: <G extends DataflowGraph>(this: void, left: import("../../util/diff-graph").NamedGraph<G>, right: import("../../util/diff-graph").NamedGraph<G>, config?: Partial<import("../../util/diff").GenericDiffConfiguration>) => import("../../util/diff-graph").GraphDifferenceReport;
|
|
124
|
+
readonly invertGraph: <G extends DataflowGraph>(this: void, graph: G, cleanEnv: REnvironmentInformation) => G;
|
|
125
|
+
readonly resolveGraphCriteria: <G extends DataflowGraph>(graph: G, ctx: import("../../project/context/flowr-analyzer-context").ReadOnlyFlowrAnalyzerContext, idMap?: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").AstIdMap) => G;
|
|
126
|
+
readonly reaches: <G extends DataflowGraph>(this: void, from: NodeId, to: NodeId, graph: G, knownReachability?: import("../../util/collections/defaultmap").DefaultMap<NodeId, Set<NodeId>>) => boolean;
|
|
127
|
+
readonly name: "Dataflow";
|
|
128
|
+
/**
|
|
129
|
+
* Maps to flowR's main graph object to store and manipulate the dataflow graph
|
|
130
|
+
* @see {@link DataflowGraph}
|
|
131
|
+
*/
|
|
132
|
+
readonly graph: typeof DataflowGraph;
|
|
133
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Dataflow = void 0;
|
|
4
|
+
const graph_1 = require("./graph");
|
|
5
|
+
const edge_1 = require("./edge");
|
|
6
|
+
const dataflowgraph_builder_1 = require("./dataflowgraph-builder");
|
|
7
|
+
const dfg_get_origin_1 = require("../origin/dfg-get-origin");
|
|
8
|
+
const graph_helper_1 = require("./graph-helper");
|
|
9
|
+
const call_graph_1 = require("./call-graph");
|
|
10
|
+
/**
|
|
11
|
+
* This is the root helper object to work with the {@link DataflowGraph}.
|
|
12
|
+
*
|
|
13
|
+
* - {@link Dataflow.visualize} - for visualization helpers (e.g., rendering the DFG as a mermaid graph),
|
|
14
|
+
* - {@link Dataflow.views} - for working with specific views of the dataflow graph (e.g., the call graph),
|
|
15
|
+
* - {@link Dataflow.edge} - for working with the edges in the dataflow graph,
|
|
16
|
+
*/
|
|
17
|
+
exports.Dataflow = {
|
|
18
|
+
name: 'Dataflow',
|
|
19
|
+
/**
|
|
20
|
+
* Maps to flowR's main graph object to store and manipulate the dataflow graph
|
|
21
|
+
* @see {@link DataflowGraph}
|
|
22
|
+
*/
|
|
23
|
+
graph: graph_1.DataflowGraph,
|
|
24
|
+
...graph_helper_1.GraphHelper,
|
|
25
|
+
/**
|
|
26
|
+
* Maps to flowR's dataflow edge helper to work with the edges in the dataflow graph
|
|
27
|
+
*/
|
|
28
|
+
edge: edge_1.DfEdge,
|
|
29
|
+
/**
|
|
30
|
+
* Dispatches to helper objects that relate to (sub-) views of the dataflow graph, e.g. the call graph.
|
|
31
|
+
*/
|
|
32
|
+
views: {
|
|
33
|
+
/**
|
|
34
|
+
* Maps to flowR's helper object for the call-graph
|
|
35
|
+
*/
|
|
36
|
+
callGraph: call_graph_1.CallGraph,
|
|
37
|
+
},
|
|
38
|
+
/**
|
|
39
|
+
* Dispatches to helper functions to create new dataflow graphs, e.g. from a pipeline or an empty graph.
|
|
40
|
+
*/
|
|
41
|
+
create: {
|
|
42
|
+
/**
|
|
43
|
+
* Creates an empty dataflow graph with the given id map (or a new one if not provided).
|
|
44
|
+
* @see {@link emptyGraph}
|
|
45
|
+
*/
|
|
46
|
+
empty: dataflowgraph_builder_1.emptyGraph
|
|
47
|
+
},
|
|
48
|
+
/**
|
|
49
|
+
* Returns the origin of a vertex in the dataflow graph
|
|
50
|
+
* @see {@link getOriginInDfg} - for the underlying function
|
|
51
|
+
*/
|
|
52
|
+
origin: dfg_get_origin_1.getOriginInDfg,
|
|
53
|
+
/**
|
|
54
|
+
* Only returns the sub-part of the graph that is determined by the given selection.
|
|
55
|
+
* In other words, this will return a graph with only vertices that are part of the selected ids,
|
|
56
|
+
* and edges that are between such selected vertices.
|
|
57
|
+
* @param graph - the dataflow graph to slice for
|
|
58
|
+
* @param select - the ids to select in the reduced graph
|
|
59
|
+
* @param includeMissingTargets - if set to true, this will include edges which target vertices that are not selected!
|
|
60
|
+
*/
|
|
61
|
+
reduceGraph(graph, select, includeMissingTargets = false) {
|
|
62
|
+
const df = new graph_1.DataflowGraph(graph.idMap);
|
|
63
|
+
const roots = graph.rootIds();
|
|
64
|
+
// if the graph has no root ids all selected vertices are non-root in this case we just break the fdef selection and promote all to root!
|
|
65
|
+
const selectedRoots = roots.intersection(select);
|
|
66
|
+
const forceRoot = selectedRoots.size === 0;
|
|
67
|
+
for (const [id, vtx] of graph.vertices(true)) {
|
|
68
|
+
if (select.has(id)) {
|
|
69
|
+
df.addVertex(vtx, vtx.environment, forceRoot || roots.has(id));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
for (const [from, targets] of graph.edges()) {
|
|
73
|
+
if (!select.has(from)) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
for (const [tar, { types }] of targets.entries()) {
|
|
77
|
+
if (!includeMissingTargets && !select.has(tar)) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
df.addEdge(from, tar, types);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (const u of graph.unknownSideEffects) {
|
|
84
|
+
if (typeof u === 'object' && select.has(u.id)) {
|
|
85
|
+
df.markIdForUnknownSideEffects(u.id, u.linkTo);
|
|
86
|
+
}
|
|
87
|
+
else if (select.has(u)) {
|
|
88
|
+
df.markIdForUnknownSideEffects(u);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return df;
|
|
92
|
+
},
|
|
93
|
+
/**
|
|
94
|
+
* Given the id of a vertex (usually a variable use),
|
|
95
|
+
* this returns a reachable provenance set by calculating a non-interprocedural and non-context sensitive backward slice, but stopping at the given ids!
|
|
96
|
+
* You can obtain the corresponding graph using {@link Dataflow.reduceGraph}.
|
|
97
|
+
* @param id - The id to use as a seed for provenance calculation
|
|
98
|
+
* @param graph - The graph to perform the provenance calculation on
|
|
99
|
+
* @param consider - The ids to restrict the calculation too (e.g., the ids contained within a function definition to restrict the analysis to)
|
|
100
|
+
* @see {@link Dataflow.provenanceGraph} - for a convenience wrapper to directly obtain the graph of the provenance.
|
|
101
|
+
*/
|
|
102
|
+
provenance(id, graph, consider) {
|
|
103
|
+
const queue = [id];
|
|
104
|
+
const visited = new Set();
|
|
105
|
+
const followEdges = edge_1.EdgeType.Calls | edge_1.EdgeType.Reads | edge_1.EdgeType.Returns | edge_1.EdgeType.Argument | edge_1.EdgeType.DefinedBy | edge_1.EdgeType.DefinedByOnCall;
|
|
106
|
+
while (queue.length > 0) {
|
|
107
|
+
const nodeId = queue.pop();
|
|
108
|
+
if (nodeId === undefined || visited.has(nodeId) || (consider && !consider.has(nodeId))) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
visited.add(nodeId);
|
|
112
|
+
const vtx = graph.get(nodeId);
|
|
113
|
+
if (vtx === undefined) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
for (const [to, types] of vtx[1]) {
|
|
117
|
+
if (edge_1.DfEdge.includesType(types, followEdges)) {
|
|
118
|
+
queue.push(to);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
for (const cd of vtx[0].cds ?? []) {
|
|
122
|
+
queue.push(cd.id);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return visited;
|
|
126
|
+
},
|
|
127
|
+
/**
|
|
128
|
+
* A convenience wrapper for {@link Dataflow.reduceGraph|reducing} the {@link Dataflow.provenance|provenance} of a graph.
|
|
129
|
+
* @param id - The id to use as a seed for provenance calculation
|
|
130
|
+
* @param graph - The graph to perform the provenance calculation on
|
|
131
|
+
* @param consider - The ids to restrict the calculation too (e.g., the ids contained within a function definition to restrict the analysis to)
|
|
132
|
+
* @see {@link Dataflow.provenance}
|
|
133
|
+
*/
|
|
134
|
+
provenanceGraph(id, graph, consider) {
|
|
135
|
+
return exports.Dataflow.reduceGraph(graph, exports.Dataflow.provenance(id, graph, consider));
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
//# sourceMappingURL=df-helper.js.map
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import { FunctionArgument, type OutgoingEdges } from './graph';
|
|
2
|
-
import { type
|
|
2
|
+
import { type GenericDifferenceInformation } from '../../util/diff';
|
|
3
3
|
import { type NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
4
|
-
import
|
|
4
|
+
import type { GraphDifferenceReport, GraphDiffContext } from '../../util/diff-graph';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* @see {@link diffOfControlFlowGraphs} - for control flow graphs
|
|
6
|
+
* This is the underlying function to calculate the difference based on a given context.
|
|
7
|
+
* Use {@link Dataflow.diff} to calculate the diff of two graphs.
|
|
9
8
|
*/
|
|
10
|
-
export declare function
|
|
11
|
-
/**
|
|
12
|
-
* Checks whether two function argument lists are equal.
|
|
13
|
-
*/
|
|
14
|
-
export declare function equalFunctionArguments(fn: NodeId, a: false | readonly FunctionArgument[], b: false | readonly FunctionArgument[]): boolean;
|
|
9
|
+
export declare function diffDataflowGraph(ctx: GraphDiffContext): void;
|
|
15
10
|
/**
|
|
16
11
|
* Compares two function argument lists and reports differences.
|
|
17
12
|
*/
|