@eagleoutice/flowr 2.9.13 → 2.9.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -10
- 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/cli/repl/commands/repl-dataflow.js +5 -5
- package/cli/repl/parser/slice-query-parser.d.ts +1 -1
- 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 +8 -8
- 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 +1 -0
- package/dataflow/environments/identifier.js +1 -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 +49 -19
- package/dataflow/graph/call-graph.js +117 -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 +132 -0
- package/dataflow/graph/df-helper.js +131 -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 +55 -0
- package/dataflow/graph/graph-helper.js +105 -0
- package/dataflow/graph/graph.d.ts +6 -1
- package/dataflow/graph/graph.js +6 -1
- package/dataflow/graph/vertex.d.ts +1 -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 +4 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +7 -6
- 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 +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +4 -4
- 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/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/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-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 +1 -0
- package/documentation/wiki-normalized-ast.js +5 -4
- package/documentation/wiki-query.js +28 -3
- package/linter/linter-rules.d.ts +24 -1
- package/linter/linter-rules.js +3 -1
- 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 +1 -1
- 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/does-call-query/does-call-query-executor.js +2 -2
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -2
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +1 -1
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +1 -1
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -3
- package/queries/catalog/location-map-query/location-map-query-executor.js +2 -2
- package/queries/catalog/origin-query/origin-query-executor.d.ts +1 -1
- package/queries/catalog/origin-query/origin-query-executor.js +3 -3
- package/queries/catalog/provenance-query/provenance-query-executor.d.ts +9 -0
- package/queries/catalog/provenance-query/provenance-query-executor.js +37 -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 +9 -1
- package/queries/query.js +2 -0
- package/r-bridge/lang-4.x/ast/model/model.d.ts +6 -0
- package/r-bridge/lang-4.x/ast/model/model.js +7 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +8 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +13 -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 +40 -16
- package/slicing/criterion/parse.js +67 -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 +9 -12
- 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 +46 -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
|
@@ -2,30 +2,54 @@ import { 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
3
|
/** Either `line:column`, `line@variable-name`, or `$id` */
|
|
4
4
|
export type SingleSlicingCriterion = `${number}:${number}` | `${number}@${string}` | `$${NodeId | number}`;
|
|
5
|
-
export type SlicingCriteria = SingleSlicingCriterion[];
|
|
6
|
-
/**
|
|
7
|
-
* Thrown if the given slicing criteria can not be found
|
|
8
|
-
*/
|
|
9
|
-
export declare class CriteriaParseError extends Error {
|
|
10
|
-
constructor(message: string);
|
|
11
|
-
}
|
|
12
5
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
6
|
+
* The helper object associated with {@link SingleSlicingCriterion} which makes it easy
|
|
7
|
+
* to parse, validate and resolve slicing criteria.
|
|
15
8
|
*/
|
|
16
|
-
export declare
|
|
9
|
+
export declare const SingleSlicingCriterion: {
|
|
10
|
+
/**
|
|
11
|
+
* Takes a criterion in the form of `line:column` or `line@variable-name` and returns the corresponding node id
|
|
12
|
+
* @see {@link SingleSlicingCriterion.tryParse} for a version that does not throw an error
|
|
13
|
+
*/
|
|
14
|
+
readonly parse: (this: void, criterion: SingleSlicingCriterion, idMap: AstIdMap) => NodeId;
|
|
15
|
+
/**
|
|
16
|
+
* Tries to resolve a slicing criterion to an id, but does not throw an error if it fails.
|
|
17
|
+
* @see {@link SingleSlicingCriterion.parse} for the version that throws an error
|
|
18
|
+
*/
|
|
19
|
+
readonly tryParse: (this: void, criterion: SingleSlicingCriterion | NodeId, idMap: AstIdMap) => NodeId | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Converts a node id to a slicing criterion in the form of `$id`
|
|
22
|
+
*/
|
|
23
|
+
readonly fromId: (this: void, id: NodeId) => SingleSlicingCriterion;
|
|
24
|
+
};
|
|
17
25
|
/**
|
|
18
|
-
*
|
|
19
|
-
* @see {@link slicingCriterionToId} for the version that throws an error
|
|
26
|
+
* A slicing criterion is a list of single slicing criteria, which can be in the form of `line:column`, `line@variable-name`, or `$id`.
|
|
20
27
|
*/
|
|
21
|
-
export
|
|
28
|
+
export type SlicingCriteria = SingleSlicingCriterion[];
|
|
22
29
|
export interface DecodedCriterion {
|
|
23
30
|
criterion: SingleSlicingCriterion;
|
|
24
31
|
id: NodeId;
|
|
25
32
|
}
|
|
26
33
|
export type DecodedCriteria = ReadonlyArray<DecodedCriterion>;
|
|
27
34
|
/**
|
|
28
|
-
*
|
|
29
|
-
|
|
35
|
+
* The helper object associated with {@link SlicingCriteria} which makes it easy to parse, validate and resolve slicing criteria.
|
|
36
|
+
*/
|
|
37
|
+
export declare const SlicingCriteria: {
|
|
38
|
+
/**
|
|
39
|
+
* Decodes all slicing criteria to their corresponding node ids
|
|
40
|
+
* @throws CriteriaParseError if any of the criteria can not be resolved
|
|
41
|
+
* @see {@link SlicingCriteria.convertAll}
|
|
42
|
+
*/
|
|
43
|
+
readonly decodeAll: (this: void, criteria: SlicingCriteria, decorated: AstIdMap) => DecodedCriteria;
|
|
44
|
+
/**
|
|
45
|
+
* Converts all criteria to their id in the AST if possible, this keeps the original criterion if it can not be resolved.
|
|
46
|
+
* @see {@link SlicingCriteria.decodeAll}
|
|
47
|
+
*/
|
|
48
|
+
readonly convertAll: (this: void, criteria: SlicingCriteria, decorated: AstIdMap) => NodeId[];
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Thrown if the given slicing criteria can not be found
|
|
30
52
|
*/
|
|
31
|
-
export declare
|
|
53
|
+
export declare class CriteriaParseError extends Error {
|
|
54
|
+
constructor(message: string);
|
|
55
|
+
}
|
|
@@ -1,63 +1,83 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CriteriaParseError = void 0;
|
|
4
|
-
exports.slicingCriterionToId = slicingCriterionToId;
|
|
5
|
-
exports.tryResolveSliceCriterionToId = tryResolveSliceCriterionToId;
|
|
6
|
-
exports.convertAllSlicingCriteriaToIds = convertAllSlicingCriteriaToIds;
|
|
3
|
+
exports.CriteriaParseError = exports.SlicingCriteria = exports.SingleSlicingCriterion = void 0;
|
|
7
4
|
const log_1 = require("../../util/log");
|
|
8
5
|
const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
|
|
9
6
|
const static_slicer_1 = require("../static/static-slicer");
|
|
10
7
|
const type_1 = require("../../r-bridge/lang-4.x/ast/model/type");
|
|
11
8
|
/**
|
|
12
|
-
*
|
|
9
|
+
* The helper object associated with {@link SingleSlicingCriterion} which makes it easy
|
|
10
|
+
* to parse, validate and resolve slicing criteria.
|
|
13
11
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
exports.SingleSlicingCriterion = {
|
|
13
|
+
/**
|
|
14
|
+
* Takes a criterion in the form of `line:column` or `line@variable-name` and returns the corresponding node id
|
|
15
|
+
* @see {@link SingleSlicingCriterion.tryParse} for a version that does not throw an error
|
|
16
|
+
*/
|
|
17
|
+
parse(criterion, idMap) {
|
|
18
|
+
const resolved = exports.SingleSlicingCriterion.tryParse(criterion, idMap);
|
|
19
|
+
if (resolved === undefined) {
|
|
20
|
+
throw new CriteriaParseError(`invalid slicing criterion ${criterion}`);
|
|
21
|
+
}
|
|
22
|
+
return resolved;
|
|
23
|
+
},
|
|
24
|
+
/**
|
|
25
|
+
* Tries to resolve a slicing criterion to an id, but does not throw an error if it fails.
|
|
26
|
+
* @see {@link SingleSlicingCriterion.parse} for the version that throws an error
|
|
27
|
+
*/
|
|
28
|
+
tryParse(criterion, idMap) {
|
|
29
|
+
criterion = criterion.toString(); // in case it's a number
|
|
30
|
+
if (criterion.startsWith('$')) {
|
|
31
|
+
return node_id_1.NodeId.normalize(criterion.substring(1));
|
|
32
|
+
}
|
|
33
|
+
else if (criterion.includes('@')) {
|
|
34
|
+
const at = criterion.indexOf('@');
|
|
35
|
+
const line = parseInt(criterion.substring(0, at));
|
|
36
|
+
const name = criterion.substring(at + 1);
|
|
37
|
+
return conventionalCriteriaToId(line, name, idMap);
|
|
38
|
+
}
|
|
39
|
+
else if (criterion.includes(':')) {
|
|
40
|
+
const [line, column] = criterion.split(':').map(c => parseInt(c));
|
|
41
|
+
return locationToId([line, column], idMap);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
/**
|
|
45
|
+
* Converts a node id to a slicing criterion in the form of `$id`
|
|
46
|
+
*/
|
|
47
|
+
fromId(id) {
|
|
48
|
+
return `$${id}`;
|
|
18
49
|
}
|
|
19
|
-
}
|
|
20
|
-
exports.CriteriaParseError = CriteriaParseError;
|
|
50
|
+
};
|
|
21
51
|
/**
|
|
22
|
-
*
|
|
23
|
-
* @see {@link tryResolveSliceCriterionToId} for a version that does not throw an error
|
|
52
|
+
* The helper object associated with {@link SlicingCriteria} which makes it easy to parse, validate and resolve slicing criteria.
|
|
24
53
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
54
|
+
exports.SlicingCriteria = {
|
|
55
|
+
/**
|
|
56
|
+
* Decodes all slicing criteria to their corresponding node ids
|
|
57
|
+
* @throws CriteriaParseError if any of the criteria can not be resolved
|
|
58
|
+
* @see {@link SlicingCriteria.convertAll}
|
|
59
|
+
*/
|
|
60
|
+
decodeAll(criteria, decorated) {
|
|
61
|
+
return criteria.map(l => ({ criterion: l, id: exports.SingleSlicingCriterion.parse(l, decorated) }));
|
|
62
|
+
},
|
|
63
|
+
/**
|
|
64
|
+
* Converts all criteria to their id in the AST if possible, this keeps the original criterion if it can not be resolved.
|
|
65
|
+
* @see {@link SlicingCriteria.decodeAll}
|
|
66
|
+
*/
|
|
67
|
+
convertAll(criteria, decorated) {
|
|
68
|
+
return criteria.map(l => exports.SingleSlicingCriterion.tryParse(l, decorated) ?? l);
|
|
35
69
|
}
|
|
36
|
-
|
|
37
|
-
const [line, column] = criterion.split(':').map(c => parseInt(c));
|
|
38
|
-
resolved = locationToId([line, column], idMap);
|
|
39
|
-
}
|
|
40
|
-
if (resolved === undefined) {
|
|
41
|
-
throw new CriteriaParseError(`invalid slicing criterion ${criterion}`);
|
|
42
|
-
}
|
|
43
|
-
return resolved;
|
|
44
|
-
}
|
|
70
|
+
};
|
|
45
71
|
/**
|
|
46
|
-
*
|
|
47
|
-
* @see {@link slicingCriterionToId} for the version that throws an error
|
|
72
|
+
* Thrown if the given slicing criteria can not be found
|
|
48
73
|
*/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
catch (e) {
|
|
54
|
-
if (e instanceof CriteriaParseError) {
|
|
55
|
-
(0, log_1.expensiveTrace)(static_slicer_1.slicerLogger, () => `could not resolve slicing criterion ${criterion}: ${e.message}`);
|
|
56
|
-
return undefined;
|
|
57
|
-
}
|
|
58
|
-
throw e; // rethrow other errors
|
|
74
|
+
class CriteriaParseError extends Error {
|
|
75
|
+
constructor(message) {
|
|
76
|
+
super(message);
|
|
77
|
+
this.name = 'CriteriaParseError';
|
|
59
78
|
}
|
|
60
79
|
}
|
|
80
|
+
exports.CriteriaParseError = CriteriaParseError;
|
|
61
81
|
function locationToId(location, dataflowIdMap) {
|
|
62
82
|
let candidate;
|
|
63
83
|
for (const [id, nodeInfo] of dataflowIdMap.entries()) {
|
|
@@ -71,36 +91,20 @@ function locationToId(location, dataflowIdMap) {
|
|
|
71
91
|
}
|
|
72
92
|
candidate = nodeInfo;
|
|
73
93
|
}
|
|
74
|
-
|
|
75
|
-
if (id) {
|
|
76
|
-
(0, log_1.expensiveTrace)(static_slicer_1.slicerLogger, () => `resolve id ${id} (${JSON.stringify(candidate?.info)}) for location ${JSON.stringify(location)}`);
|
|
77
|
-
}
|
|
78
|
-
return id;
|
|
94
|
+
return candidate?.info.id;
|
|
79
95
|
}
|
|
80
96
|
function conventionalCriteriaToId(line, name, dataflowIdMap) {
|
|
81
97
|
let candidate;
|
|
82
|
-
for (const
|
|
98
|
+
for (const nodeInfo of dataflowIdMap.values()) {
|
|
83
99
|
if (nodeInfo.location === undefined || nodeInfo.location[0] !== line || nodeInfo.lexeme !== name) {
|
|
84
100
|
continue;
|
|
85
101
|
}
|
|
86
|
-
static_slicer_1.slicerLogger.trace(`can resolve id ${id} (${JSON.stringify(nodeInfo)}) for line ${line} and name ${name}`);
|
|
87
102
|
// function calls have the same location as the symbol they refer to, so we need to prefer the function call
|
|
88
103
|
if (candidate !== undefined && nodeInfo.type !== type_1.RType.FunctionCall || nodeInfo.type === type_1.RType.Argument || nodeInfo.type === type_1.RType.ExpressionList) {
|
|
89
104
|
continue;
|
|
90
105
|
}
|
|
91
106
|
candidate = nodeInfo;
|
|
92
107
|
}
|
|
93
|
-
|
|
94
|
-
if (id) {
|
|
95
|
-
static_slicer_1.slicerLogger.trace(`resolve id ${id} (${JSON.stringify(candidate?.info)}) for line ${line} and name ${name}`);
|
|
96
|
-
}
|
|
97
|
-
return id;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Converts all slicing criteria to their corresponding node ids
|
|
101
|
-
* @throws CriteriaParseError if any of the criteria can not be resolved
|
|
102
|
-
*/
|
|
103
|
-
function convertAllSlicingCriteriaToIds(criteria, decorated) {
|
|
104
|
-
return criteria.map(l => ({ criterion: l, id: slicingCriterionToId(l, decorated) }));
|
|
108
|
+
return candidate?.info.id;
|
|
105
109
|
}
|
|
106
110
|
//# sourceMappingURL=parse.js.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
2
2
|
import type { REnvironmentInformation } from '../../dataflow/environments/environment';
|
|
3
|
-
import type { DecodedCriteria } from '../criterion/parse';
|
|
4
3
|
/**
|
|
5
4
|
* Represents a node during the slicing process, together with the environment it is traversed in
|
|
6
5
|
* (modified by function calls) and whether it is only used for its side effects.
|
|
@@ -29,7 +28,7 @@ export interface SliceResult {
|
|
|
29
28
|
*/
|
|
30
29
|
readonly result: ReadonlySet<NodeId>;
|
|
31
30
|
/**
|
|
32
|
-
* The
|
|
31
|
+
* The ids of the nodes in the normalized ast that were used as seed ids for slicing. This is a subset of {@link result}.
|
|
33
32
|
*/
|
|
34
|
-
readonly
|
|
33
|
+
readonly slicedFor: readonly NodeId[];
|
|
35
34
|
}
|
|
@@ -2,12 +2,11 @@ import type { SliceResult } from './slicer-types';
|
|
|
2
2
|
import { type Fingerprint } from './fingerprint';
|
|
3
3
|
import { VisitingQueue } from './visiting-queue';
|
|
4
4
|
import type { NormalizedAst } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
5
|
-
import { type SlicingCriteria } from '../criterion/parse';
|
|
6
5
|
import { type REnvironmentInformation } from '../../dataflow/environments/environment';
|
|
7
6
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
8
|
-
import { SliceDirection } from '../../core/steps/all/static-slicing/00-slice';
|
|
9
7
|
import type { DataflowInformation } from '../../dataflow/info';
|
|
10
8
|
import type { ReadOnlyFlowrAnalyzerContext } from '../../project/context/flowr-analyzer-context';
|
|
9
|
+
import { SliceDirection } from '../../util/slice-direction';
|
|
11
10
|
export declare const slicerLogger: import("tslog").Logger<import("tslog").ILogObj>;
|
|
12
11
|
/**
|
|
13
12
|
* This returns the ids to include in the static slice of the given type, when slicing with the given seed id's (must be at least one).
|
|
@@ -16,12 +15,12 @@ export declare const slicerLogger: import("tslog").Logger<import("tslog").ILogOb
|
|
|
16
15
|
* @param ctx - The analyzer context used for slicing.
|
|
17
16
|
* @param info - The dataflow information used for slicing.
|
|
18
17
|
* @param idMap - The mapping from node ids to their information in the AST.
|
|
19
|
-
* @param
|
|
18
|
+
* @param ids - The seed ids to slice with. Must be at least one.
|
|
20
19
|
* @param direction - The direction to slice in.
|
|
21
20
|
* @param threshold - The maximum number of nodes to visit in the graph. If the threshold is reached, the slice will side with inclusion and drop its minimal guarantee. The limit ensures that the algorithm halts.
|
|
22
21
|
* @param cache - A cache to store the results of the slice. If provided, the slice may use this cache to speed up the slicing process.
|
|
23
22
|
*/
|
|
24
|
-
export declare function staticSlice(ctx: ReadOnlyFlowrAnalyzerContext, info: DataflowInformation, { idMap }: NormalizedAst,
|
|
23
|
+
export declare function staticSlice(ctx: ReadOnlyFlowrAnalyzerContext, info: DataflowInformation, { idMap }: NormalizedAst, ids: readonly NodeId[], direction: SliceDirection, threshold?: number, cache?: Map<Fingerprint, Set<NodeId>>): Readonly<SliceResult>;
|
|
25
24
|
/**
|
|
26
25
|
* Updates the potential addition for the given target node in the visiting queue.
|
|
27
26
|
* This describes vertices that might be added *if* another path reaches them.
|
|
@@ -7,11 +7,10 @@ const assert_1 = require("../../util/assert");
|
|
|
7
7
|
const log_1 = require("../../util/log");
|
|
8
8
|
const visiting_queue_1 = require("./visiting-queue");
|
|
9
9
|
const slice_call_1 = require("./slice-call");
|
|
10
|
-
const parse_1 = require("../criterion/parse");
|
|
11
10
|
const vertex_1 = require("../../dataflow/graph/vertex");
|
|
12
11
|
const edge_1 = require("../../dataflow/graph/edge");
|
|
13
|
-
const
|
|
14
|
-
const
|
|
12
|
+
const df_helper_1 = require("../../dataflow/graph/df-helper");
|
|
13
|
+
const slice_direction_1 = require("../../util/slice-direction");
|
|
15
14
|
exports.slicerLogger = log_1.log.getSubLogger({ name: 'slicer' });
|
|
16
15
|
/**
|
|
17
16
|
* This returns the ids to include in the static slice of the given type, when slicing with the given seed id's (must be at least one).
|
|
@@ -20,18 +19,16 @@ exports.slicerLogger = log_1.log.getSubLogger({ name: 'slicer' });
|
|
|
20
19
|
* @param ctx - The analyzer context used for slicing.
|
|
21
20
|
* @param info - The dataflow information used for slicing.
|
|
22
21
|
* @param idMap - The mapping from node ids to their information in the AST.
|
|
23
|
-
* @param
|
|
22
|
+
* @param ids - The seed ids to slice with. Must be at least one.
|
|
24
23
|
* @param direction - The direction to slice in.
|
|
25
24
|
* @param threshold - The maximum number of nodes to visit in the graph. If the threshold is reached, the slice will side with inclusion and drop its minimal guarantee. The limit ensures that the algorithm halts.
|
|
26
25
|
* @param cache - A cache to store the results of the slice. If provided, the slice may use this cache to speed up the slicing process.
|
|
27
26
|
*/
|
|
28
|
-
function staticSlice(ctx, info, { idMap },
|
|
29
|
-
(0, assert_1.guard)(
|
|
30
|
-
const decodedCriteria = (0, parse_1.convertAllSlicingCriteriaToIds)(criteria, idMap);
|
|
31
|
-
(0, log_1.expensiveTrace)(exports.slicerLogger, () => `calculating ${direction} slice for ${decodedCriteria.length} seed criteria: ${decodedCriteria.map(s => JSON.stringify(s)).join(', ')}`);
|
|
27
|
+
function staticSlice(ctx, info, { idMap }, ids, direction, threshold = 75, cache) {
|
|
28
|
+
(0, assert_1.guard)(ids.length > 0, 'must have at least one seed id to calculate slice');
|
|
32
29
|
let { graph } = info;
|
|
33
|
-
if (direction ===
|
|
34
|
-
graph =
|
|
30
|
+
if (direction === slice_direction_1.SliceDirection.Forward) {
|
|
31
|
+
graph = df_helper_1.Dataflow.invertGraph(graph, ctx.env.makeCleanEnv());
|
|
35
32
|
}
|
|
36
33
|
const queue = new visiting_queue_1.VisitingQueue(threshold, cache);
|
|
37
34
|
let minNesting = Number.MAX_SAFE_INTEGER;
|
|
@@ -40,7 +37,7 @@ function staticSlice(ctx, info, { idMap }, criteria, direction, threshold = 75,
|
|
|
40
37
|
{
|
|
41
38
|
const emptyEnv = ctx.env.makeCleanEnv();
|
|
42
39
|
const basePrint = ctx.env.getCleanEnvFingerprint();
|
|
43
|
-
for (const
|
|
40
|
+
for (const startId of ids) {
|
|
44
41
|
queue.add(startId, emptyEnv, basePrint, false);
|
|
45
42
|
// retrieve the minimum nesting of all nodes to only add control dependencies if they are "part" of the current execution
|
|
46
43
|
minNesting = Math.min(minNesting, idMap.get(startId)?.info.nesting ?? minNesting);
|
|
@@ -102,7 +99,7 @@ function staticSlice(ctx, info, { idMap }, criteria, direction, threshold = 75,
|
|
|
102
99
|
}
|
|
103
100
|
}
|
|
104
101
|
}
|
|
105
|
-
return { ...queue.status(),
|
|
102
|
+
return { ...queue.status(), slicedFor: ids };
|
|
106
103
|
}
|
|
107
104
|
/**
|
|
108
105
|
* Updates the potential addition for the given target node in the visiting queue.
|
package/util/diff.d.ts
CHANGED
|
@@ -42,12 +42,12 @@ export interface GenericDifferenceInformation<Report extends WriteableDifference
|
|
|
42
42
|
}
|
|
43
43
|
export interface GenericDiffConfiguration {
|
|
44
44
|
/**
|
|
45
|
-
* The left graph may contain more vertices and or edges than the right graph.
|
|
45
|
+
* The left/first graph may contain more vertices and or edges than the right/second graph.
|
|
46
46
|
* However, those which are the same (based on their ids) have to be equal
|
|
47
47
|
*/
|
|
48
48
|
readonly rightIsSubgraph?: boolean;
|
|
49
49
|
/**
|
|
50
|
-
* Similar to {@link rightIsSubgraph}, but for the left graph.
|
|
50
|
+
* Similar to {@link rightIsSubgraph}, but for the left/first graph.
|
|
51
51
|
*/
|
|
52
52
|
readonly leftIsSubgraph?: boolean;
|
|
53
53
|
}
|
package/util/mermaid/ast.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.normalizedAstToMermaid = normalizedAstToMermaid;
|
|
4
4
|
exports.normalizedAstToMermaidUrl = normalizedAstToMermaidUrl;
|
|
5
|
-
const mermaid_1 = require("./mermaid");
|
|
6
5
|
const type_1 = require("../../r-bridge/lang-4.x/ast/model/type");
|
|
7
6
|
const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
8
7
|
const flowr_file_1 = require("../../project/context/flowr-file");
|
|
9
8
|
const info_1 = require("./info");
|
|
10
9
|
const model_1 = require("../../r-bridge/lang-4.x/ast/model/model");
|
|
10
|
+
const mermaid_1 = require("./mermaid");
|
|
11
11
|
function identifyMermaidDirection(prefix) {
|
|
12
12
|
const directionMatch = prefix.match(/flowchart (TD|LR|RL|BT)/);
|
|
13
13
|
if (directionMatch) {
|
|
@@ -25,7 +25,7 @@ function normalizedAstToMermaid(ast, { prefix = 'flowchart TD\n', markStyle = in
|
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
const name = `${n.type} (${n.info.id})\\n${n.lexeme ?? ' '}`;
|
|
28
|
-
output += ` n${n.info.id}(["${
|
|
28
|
+
output += ` n${n.info.id}(["${mermaid_1.Mermaid.escape(name)}"])\n`;
|
|
29
29
|
if (mark?.has(n.info.id)) {
|
|
30
30
|
output += ` style n${n.info.id} ${markStyle.vertex}\n`;
|
|
31
31
|
}
|
|
@@ -57,7 +57,7 @@ function normalizedAstToMermaid(ast, { prefix = 'flowchart TD\n', markStyle = in
|
|
|
57
57
|
// add a subgraph for each file
|
|
58
58
|
if (ast.files.length !== 1 || (f.filePath && f.filePath !== flowr_file_1.FlowrFile.INLINE_PATH)) {
|
|
59
59
|
const direction = identifyMermaidDirection(prefix);
|
|
60
|
-
output += ` subgraph "File: ${
|
|
60
|
+
output += ` subgraph "File: ${mermaid_1.Mermaid.escape(f.filePath ?? flowr_file_1.FlowrFile.INLINE_PATH)}" direction ${direction}\n`;
|
|
61
61
|
showAst(f.root);
|
|
62
62
|
output += ' end\n';
|
|
63
63
|
}
|
|
@@ -75,6 +75,6 @@ function normalizedAstToMermaid(ast, { prefix = 'flowchart TD\n', markStyle = in
|
|
|
75
75
|
* Use mermaid to visualize the normalized AST.
|
|
76
76
|
*/
|
|
77
77
|
function normalizedAstToMermaidUrl(ast, info) {
|
|
78
|
-
return
|
|
78
|
+
return mermaid_1.Mermaid.codeToUrl(normalizedAstToMermaid(ast, info ?? {}));
|
|
79
79
|
}
|
|
80
80
|
//# sourceMappingURL=ast.js.map
|
package/util/mermaid/cfg.js
CHANGED
|
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MermaidExitPointDefaultMarkStyle = exports.MermaidEntryPointDefaultMarkStyle = void 0;
|
|
4
4
|
exports.cfgToMermaid = cfgToMermaid;
|
|
5
5
|
exports.cfgToMermaidUrl = cfgToMermaidUrl;
|
|
6
|
-
const mermaid_1 = require("./mermaid");
|
|
7
6
|
const control_flow_graph_1 = require("../../control-flow/control-flow-graph");
|
|
8
7
|
const reconstruct_1 = require("../../reconstruct/reconstruct");
|
|
9
8
|
const auto_select_defaults_1 = require("../../reconstruct/auto-select/auto-select-defaults");
|
|
10
9
|
const info_1 = require("./info");
|
|
11
10
|
const model_1 = require("../../r-bridge/lang-4.x/ast/model/model");
|
|
11
|
+
const mermaid_1 = require("./mermaid");
|
|
12
12
|
exports.MermaidEntryPointDefaultMarkStyle = 'stroke:cyan,stroke-width:6.5px;';
|
|
13
13
|
exports.MermaidExitPointDefaultMarkStyle = 'stroke:green,stroke-width:6.5px;';
|
|
14
14
|
function getLexeme(n) {
|
|
@@ -18,7 +18,7 @@ function cfgOfNode(vert, normalizedVertex, id, content, output) {
|
|
|
18
18
|
if (normalizedVertex && content !== undefined) {
|
|
19
19
|
const start = control_flow_graph_1.CfgVertex.isExpression(vert) ? '([' : '[';
|
|
20
20
|
const end = control_flow_graph_1.CfgVertex.isExpression(vert) ? '])' : ']';
|
|
21
|
-
const name = `"\`${
|
|
21
|
+
const name = `"\`${mermaid_1.Mermaid.escape(normalizedVertex.type)} (${id})${content ? '\n' + mermaid_1.Mermaid.escape(JSON.stringify(content)) : ''}${control_flow_graph_1.CfgVertex.getCallTargets(vert) ? '\n calls:' + mermaid_1.Mermaid.escape(JSON.stringify([...control_flow_graph_1.CfgVertex.getCallTargets(vert)])) : ''}\`"`;
|
|
22
22
|
output += ` n${id}${start}${name}${end}\n`;
|
|
23
23
|
}
|
|
24
24
|
else {
|
|
@@ -83,7 +83,7 @@ function cfgToMermaid(cfg, normalizedAst, { prefix = 'flowchart BT\n', simplify
|
|
|
83
83
|
}
|
|
84
84
|
const ids = elems?.map(control_flow_graph_1.CfgVertex.getId) ?? [];
|
|
85
85
|
const reconstruct = limitTo((0, reconstruct_1.reconstructToCode)(normalizedAst, { nodes: new Set(ids) }, auto_select_defaults_1.doNotAutoSelect).code, basicBlockCharacterLimit);
|
|
86
|
-
const name = `"\`${includeBasicBlockLabel ? `Basic Block (${id})\n` : ''}${
|
|
86
|
+
const name = `"\`${includeBasicBlockLabel ? `Basic Block (${id})\n` : ''}${mermaid_1.Mermaid.escape(reconstruct)}\`"`;
|
|
87
87
|
output += ` n${id}[[${name}]]\n`;
|
|
88
88
|
diagramIncludedIds.add(control_flow_graph_1.CfgVertex.getId(vertex));
|
|
89
89
|
}
|
|
@@ -130,7 +130,7 @@ function cfgToMermaid(cfg, normalizedAst, { prefix = 'flowchart BT\n', simplify
|
|
|
130
130
|
const isCd = control_flow_graph_1.CfgEdge.isControlDependency(edge);
|
|
131
131
|
const edgeType = isCd ? '-->' : '-.->';
|
|
132
132
|
const edgeSuffix = isCd ? ` (${control_flow_graph_1.CfgEdge.unpackWhen(edge)})` : '';
|
|
133
|
-
output += ` n${from} ${edgeType}|"${
|
|
133
|
+
output += ` n${from} ${edgeType}|"${mermaid_1.Mermaid.escape(control_flow_graph_1.CfgEdge.typeToString(edge))}${edgeSuffix}"| n${to}\n`;
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
for (const entryPoint of cfg.entryPoints) {
|
|
@@ -156,7 +156,7 @@ function cfgToMermaid(cfg, normalizedAst, { prefix = 'flowchart BT\n', simplify
|
|
|
156
156
|
* Use mermaid to visualize the normalized AST.
|
|
157
157
|
*/
|
|
158
158
|
function cfgToMermaidUrl(cfg, normalizedAst, info) {
|
|
159
|
-
return
|
|
159
|
+
return mermaid_1.Mermaid.codeToUrl(cfgToMermaid(cfg, normalizedAst, info ?? {}));
|
|
160
160
|
}
|
|
161
161
|
/**
|
|
162
162
|
* Limits a string to n chars, after which the remainder will be replaced with ...
|
package/util/mermaid/dfg.d.ts
CHANGED
|
@@ -3,7 +3,11 @@ import { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
|
3
3
|
import { type IdentifierDefinition } from '../../dataflow/environments/identifier';
|
|
4
4
|
import { type DataflowGraphVertexInfo } from '../../dataflow/graph/vertex';
|
|
5
5
|
import { type MermaidMarkdownMark, type MermaidMarkStyle } from './info';
|
|
6
|
-
|
|
6
|
+
import { DataflowInformation } from '../../dataflow/info';
|
|
7
|
+
/**
|
|
8
|
+
* Internal representation of a mermaid graph in flowR
|
|
9
|
+
*/
|
|
10
|
+
export interface MermaidGraph {
|
|
7
11
|
nodeLines: string[];
|
|
8
12
|
edgeLines: string[];
|
|
9
13
|
includeEnvironments: boolean;
|
|
@@ -27,7 +31,7 @@ export declare function mermaidNodeBrackets(tag: DataflowGraphVertexInfo['tag'])
|
|
|
27
31
|
* Prints an identifier definition in a human-readable format.
|
|
28
32
|
*/
|
|
29
33
|
export declare function printIdentifier(id: IdentifierDefinition): string;
|
|
30
|
-
interface MermaidGraphConfiguration {
|
|
34
|
+
export interface MermaidGraphConfiguration {
|
|
31
35
|
graph: DataflowGraph;
|
|
32
36
|
prefix?: string | null;
|
|
33
37
|
idPrefix?: string;
|
|
@@ -39,21 +43,6 @@ interface MermaidGraphConfiguration {
|
|
|
39
43
|
simplified?: boolean;
|
|
40
44
|
includeOnlyIds?: ReadonlySet<NodeId>;
|
|
41
45
|
}
|
|
42
|
-
/**
|
|
43
|
-
* Converts a dataflow graph to mermaid graph code that visualizes the graph.
|
|
44
|
-
*/
|
|
45
|
-
export declare function graphToMermaid(config: MermaidGraphConfiguration): {
|
|
46
|
-
string: string;
|
|
47
|
-
mermaid: MermaidGraph;
|
|
48
|
-
};
|
|
49
|
-
/**
|
|
50
|
-
* Converts a dataflow graph to a mermaid url that visualizes the graph.
|
|
51
|
-
* @param graph - The graph to convert
|
|
52
|
-
* @param includeEnvironments - Whether to include the environments in the mermaid graph code
|
|
53
|
-
* @param mark - Special nodes to mark (e.g., those included in the slice)
|
|
54
|
-
* @param simplified - Whether to simplify the graph
|
|
55
|
-
*/
|
|
56
|
-
export declare function graphToMermaidUrl(graph: DataflowGraph, includeEnvironments?: boolean, mark?: ReadonlySet<NodeId>, simplified?: boolean): string;
|
|
57
46
|
export interface LabeledDiffGraph {
|
|
58
47
|
label: string;
|
|
59
48
|
graph: DataflowGraph;
|
|
@@ -65,4 +54,30 @@ export declare function diffGraphsToMermaid(left: LabeledDiffGraph, right: Label
|
|
|
65
54
|
* Converts two dataflow graphs to a mermaid url that visualizes their differences.
|
|
66
55
|
*/
|
|
67
56
|
export declare function diffGraphsToMermaidUrl(left: LabeledDiffGraph, right: LabeledDiffGraph, prefix: string): string;
|
|
68
|
-
|
|
57
|
+
/**
|
|
58
|
+
* The helper object for all things regarding the mermaid based visualization of dataflow graphs!
|
|
59
|
+
*/
|
|
60
|
+
export declare const DataflowMermaid: {
|
|
61
|
+
readonly name: "DataflowMermaid";
|
|
62
|
+
/**
|
|
63
|
+
* Converts a dataflow graph to mermaid graph code that visualizes the graph.
|
|
64
|
+
* @see {@link DataflowMermaid.url} - render the given graph to a url to mermaid.live
|
|
65
|
+
*/
|
|
66
|
+
readonly convert: (this: void, config: MermaidGraphConfiguration) => {
|
|
67
|
+
string: string;
|
|
68
|
+
mermaid: MermaidGraph;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* This is a simplified version of {@link DataflowMermaid.convertToMermaid}
|
|
72
|
+
*/
|
|
73
|
+
readonly raw: (this: void, graph: DataflowGraph | DataflowInformation, includeEnvironments?: boolean, mark?: ReadonlySet<NodeId>, simplified?: boolean) => string;
|
|
74
|
+
/**
|
|
75
|
+
* Converts a dataflow graph to a mermaid url that visualizes the graph.
|
|
76
|
+
* This is basically a combination of {@link DataflowMermaid.mermaidRaw} and {@link Mermaid.codeToUrl}.
|
|
77
|
+
* @param graph - the dataflow graph to render
|
|
78
|
+
* @param includeEnvironments - whether to include the environment content in the output
|
|
79
|
+
* @param mark - which vertices to highlight in the visualization
|
|
80
|
+
* @param simplified - whether to show a simplified use of the graph with fewer details on the vertices and edges
|
|
81
|
+
*/
|
|
82
|
+
readonly url: (this: void, graph: DataflowGraph | DataflowInformation, includeEnvironments?: boolean, mark?: ReadonlySet<NodeId>, simplified?: boolean) => string;
|
|
83
|
+
};
|