@eagleoutice/flowr 2.0.1 → 2.0.3
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/benchmark/slicer.d.ts +1 -0
- package/benchmark/slicer.js +69 -8
- package/benchmark/stats/print.d.ts +1 -0
- package/benchmark/stats/print.js +94 -31
- package/benchmark/stats/size-of.d.ts +3 -0
- package/benchmark/stats/size-of.js +68 -0
- package/benchmark/stats/stats.d.ts +23 -0
- package/benchmark/summarizer/data.d.ts +24 -1
- package/benchmark/summarizer/first-phase/input.d.ts +2 -2
- package/benchmark/summarizer/first-phase/input.js +21 -21
- package/benchmark/summarizer/first-phase/process.d.ts +4 -2
- package/benchmark/summarizer/first-phase/process.js +120 -33
- package/benchmark/summarizer/second-phase/graph.js +7 -0
- package/benchmark/summarizer/second-phase/process.js +65 -27
- package/benchmark/summarizer/summarizer.d.ts +1 -0
- package/benchmark/summarizer/summarizer.js +23 -10
- package/cli/repl/commands/commands.js +19 -1
- package/cli/slicer-app.js +1 -1
- package/dataflow/environments/append.js +1 -2
- package/dataflow/environments/built-in.js +2 -1
- package/dataflow/environments/clone.js +1 -1
- package/dataflow/environments/diff.d.ts +1 -1
- package/dataflow/environments/diff.js +16 -18
- package/dataflow/environments/environment.d.ts +6 -8
- package/dataflow/environments/environment.js +5 -8
- package/dataflow/environments/identifier.d.ts +2 -1
- package/dataflow/environments/overwrite.js +1 -2
- package/dataflow/environments/scoping.js +1 -1
- package/dataflow/graph/diff.js +11 -6
- package/dataflow/graph/edge.d.ts +2 -3
- package/dataflow/graph/edge.js +2 -2
- package/dataflow/graph/graph.d.ts +6 -2
- package/dataflow/graph/graph.js +16 -9
- package/dataflow/graph/vertex.d.ts +2 -1
- package/dataflow/info.d.ts +10 -1
- package/dataflow/info.js +54 -2
- package/dataflow/internal/linker.d.ts +1 -1
- package/dataflow/internal/linker.js +1 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +21 -25
- package/dataflow/internal/process/functions/call/built-in/built-in-get.js +6 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +10 -8
- package/dataflow/internal/process/functions/call/built-in/built-in-logical-bin-op.d.ts +1 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-logical-bin-op.js +1 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +1 -1
- package/dataflow/internal/process/functions/call/default-call-handling.js +1 -1
- package/dataflow/internal/process/functions/call/unnamed-call-handling.js +1 -1
- package/dataflow/internal/process/process-value.js +0 -1
- package/dataflow/processor.d.ts +2 -3
- package/package.json +5 -2
- package/r-bridge/data/data.d.ts +1 -1
- package/r-bridge/data/data.js +1 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/operators.js +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/decorate.js +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/stateful-fold.js +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/visitor.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/functions/normalize-call.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/operators/normalize-binary.js +1 -1
- package/r-bridge/retriever.d.ts +1 -1
- package/r-bridge/retriever.js +3 -2
- package/r-bridge/shell.js +2 -1
- package/reconstruct/reconstruct.d.ts +3 -3
- package/reconstruct/reconstruct.js +40 -41
- package/slicing/criterion/filters/all-variables.js +1 -1
- package/slicing/static/static-slicer.js +2 -2
- package/statistics/features/common-syntax-probability.js +1 -1
- package/statistics/features/supported/control-flow/control-flow.js +1 -1
- package/statistics/features/supported/defined-functions/defined-functions.js +1 -1
- package/statistics/features/supported/loops/loops.js +1 -1
- package/statistics/features/supported/used-functions/used-functions.js +1 -1
- package/util/assert.d.ts +1 -1
- package/util/mermaid/ast.js +4 -0
- package/util/mermaid/dfg.d.ts +0 -1
- package/util/mermaid/dfg.js +16 -13
- package/util/mermaid/mermaid.js +21 -1
- package/util/version.js +1 -1
package/cli/slicer-app.js
CHANGED
|
@@ -40,7 +40,7 @@ async function getSlice() {
|
|
|
40
40
|
reconstruct = reconstructedCode;
|
|
41
41
|
if (options.output) {
|
|
42
42
|
console.log('Written reconstructed code to', options.output);
|
|
43
|
-
console.log(`Automatically selected ${reconstructedCode.
|
|
43
|
+
console.log(`Automatically selected ${reconstructedCode.linesWithAutoSelected} lines`);
|
|
44
44
|
fs_1.default.writeFileSync(options.output, reconstructedCode.code);
|
|
45
45
|
}
|
|
46
46
|
else if (!options.api && !options.diff) {
|
|
@@ -15,7 +15,6 @@ function uniqueMergeValues(old, value) {
|
|
|
15
15
|
}
|
|
16
16
|
function appendIEnvironmentWith(base, next) {
|
|
17
17
|
(0, assert_1.guard)(base !== undefined && next !== undefined, 'can not append environments with undefined');
|
|
18
|
-
(0, assert_1.guard)(base.name === next.name, 'cannot overwrite environments with different names');
|
|
19
18
|
const map = new Map(base.memory);
|
|
20
19
|
for (const [key, value] of next.memory) {
|
|
21
20
|
const old = map.get(key);
|
|
@@ -27,7 +26,7 @@ function appendIEnvironmentWith(base, next) {
|
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
const parent = base.parent === environment_1.BuiltInEnvironment ? environment_1.BuiltInEnvironment : appendIEnvironmentWith(base.parent, next.parent);
|
|
30
|
-
const out = new environment_1.Environment(
|
|
29
|
+
const out = new environment_1.Environment(parent);
|
|
31
30
|
out.memory = map;
|
|
32
31
|
return out;
|
|
33
32
|
}
|
|
@@ -111,7 +111,8 @@ registerBuiltInFunctions(['delayedAssign'], built_in_assignment_1.processAssignm
|
|
|
111
111
|
registerBuiltInFunctions(['<<-'], built_in_assignment_1.processAssignment, { superAssignment: true, canBeReplacement: true });
|
|
112
112
|
registerBuiltInFunctions(['->'], built_in_assignment_1.processAssignment, { swapSourceAndTarget: true, canBeReplacement: true });
|
|
113
113
|
registerBuiltInFunctions(['->>'], built_in_assignment_1.processAssignment, { superAssignment: true, swapSourceAndTarget: true, canBeReplacement: true });
|
|
114
|
-
registerBuiltInFunctions(['&&', '
|
|
114
|
+
registerBuiltInFunctions(['&&', '&'], built_in_logical_bin_op_1.processSpecialBinOp, { lazy: true, evalRhsWhen: true });
|
|
115
|
+
registerBuiltInFunctions(['||', '|'], built_in_logical_bin_op_1.processSpecialBinOp, { lazy: true, evalRhsWhen: false });
|
|
115
116
|
registerBuiltInFunctions(['|>', '%>%'], built_in_pipe_1.processPipe, {});
|
|
116
117
|
registerBuiltInFunctions(['function', '\\'], built_in_function_definition_1.processFunctionDefinition, {});
|
|
117
118
|
registerBuiltInFunctions(['quote', 'substitute', 'bquote'], built_in_quote_1.processQuote, { quoteArgumentsWithIndex: 0 });
|
|
@@ -9,7 +9,7 @@ function cloneEnvironment(environment, recurseParents) {
|
|
|
9
9
|
else if (environment.id === environment_1.BuiltInEnvironment.id) {
|
|
10
10
|
return environment_1.BuiltInEnvironment;
|
|
11
11
|
}
|
|
12
|
-
const clone = new environment_1.Environment(
|
|
12
|
+
const clone = new environment_1.Environment(recurseParents ? cloneEnvironment(environment.parent, recurseParents) : environment.parent);
|
|
13
13
|
clone.memory = new Map(JSON.parse(JSON.stringify([...environment.memory])));
|
|
14
14
|
return clone;
|
|
15
15
|
}
|
|
@@ -2,5 +2,5 @@ import type { GenericDifferenceInformation, WriteableDifferenceReport } from '..
|
|
|
2
2
|
import type { IEnvironment, REnvironmentInformation } from './environment';
|
|
3
3
|
import type { IdentifierReference } from './identifier';
|
|
4
4
|
export declare function diffIdentifierReferences<Report extends WriteableDifferenceReport>(a: IdentifierReference | undefined, b: IdentifierReference | undefined, info: GenericDifferenceInformation<Report>): void;
|
|
5
|
-
export declare function diffEnvironment<Report extends WriteableDifferenceReport>(a: IEnvironment | undefined, b: IEnvironment | undefined, info: GenericDifferenceInformation<Report
|
|
5
|
+
export declare function diffEnvironment<Report extends WriteableDifferenceReport>(a: IEnvironment | undefined, b: IEnvironment | undefined, info: GenericDifferenceInformation<Report>, depth: number): void;
|
|
6
6
|
export declare function diffEnvironmentInformation<Report extends WriteableDifferenceReport>(a: REnvironmentInformation | undefined, b: REnvironmentInformation | undefined, info: GenericDifferenceInformation<Report>): void;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.diffEnvironmentInformation = exports.diffEnvironment = exports.diffIdentifierReferences = void 0;
|
|
4
4
|
const diff_1 = require("../../util/diff");
|
|
5
5
|
const json_1 = require("../../util/json");
|
|
6
|
-
const
|
|
6
|
+
const info_1 = require("../info");
|
|
7
7
|
function diffIdentifierReferences(a, b, info) {
|
|
8
8
|
if (a === undefined || b === undefined) {
|
|
9
9
|
if (a !== b) {
|
|
@@ -17,9 +17,7 @@ function diffIdentifierReferences(a, b, info) {
|
|
|
17
17
|
if (a.nodeId !== b.nodeId) {
|
|
18
18
|
info.report.addComment(`${info.position}Different nodeIds: ${info.leftname}: ${a.nodeId} vs. ${info.rightname}: ${b.nodeId}`);
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
info.report.addComment(`${info.position}Different control dependency: ${info.leftname}: ${JSON.stringify(a.controlDependencies)} vs. ${info.rightname}: ${JSON.stringify(b.controlDependencies)}`);
|
|
22
|
-
}
|
|
20
|
+
(0, info_1.diffControlDependencies)(a.controlDependencies, b.controlDependencies, info);
|
|
23
21
|
}
|
|
24
22
|
exports.diffIdentifierReferences = diffIdentifierReferences;
|
|
25
23
|
function diffMemory(a, b, info) {
|
|
@@ -41,9 +39,7 @@ function diffMemory(a, b, info) {
|
|
|
41
39
|
if (aVal.nodeId !== bVal.nodeId) {
|
|
42
40
|
info.report.addComment(`${info.position}Different ids for ${key}. ${info.leftname}: ${aVal.nodeId} vs. ${info.rightname}: ${bVal.nodeId}`);
|
|
43
41
|
}
|
|
44
|
-
|
|
45
|
-
info.report.addComment(`${info.position}Different controlDependency for ${key} (${aVal.nodeId}). ${info.leftname}: ${JSON.stringify(aVal.controlDependencies)} vs. ${info.rightname}: ${JSON.stringify(bVal.controlDependencies)}`);
|
|
46
|
-
}
|
|
42
|
+
(0, info_1.diffControlDependencies)(aVal.controlDependencies, bVal.controlDependencies, { ...info, position: `${info.position} For ${key}. ` });
|
|
47
43
|
if (aVal.definedAt !== bVal.definedAt) {
|
|
48
44
|
info.report.addComment(`${info.position}Different definition ids (definedAt) for ${key} (${aVal.nodeId}). ${info.leftname}: ${aVal.definedAt} vs. ${info.rightname}: ${bVal.definedAt}`);
|
|
49
45
|
}
|
|
@@ -53,33 +49,35 @@ function diffMemory(a, b, info) {
|
|
|
53
49
|
}
|
|
54
50
|
}
|
|
55
51
|
}
|
|
56
|
-
function diffEnvironment(a, b, info) {
|
|
52
|
+
function diffEnvironment(a, b, info, depth) {
|
|
57
53
|
if (a === undefined || b === undefined) {
|
|
58
54
|
if (a !== b) {
|
|
59
|
-
info.report.addComment(`${info.position}Different environments. ${info.leftname}: ${a !== undefined ? 'present' : 'undefined'} vs. ${info.rightname}: ${b !== undefined ? 'present' : 'undefined'}`);
|
|
55
|
+
info.report.addComment(`${info.position}[at level: ${depth}] Different environments. ${info.leftname}: ${a !== undefined ? 'present' : 'undefined'} vs. ${info.rightname}: ${b !== undefined ? 'present' : 'undefined'}`);
|
|
60
56
|
}
|
|
61
57
|
return;
|
|
62
58
|
}
|
|
63
|
-
if (a.name !== b.name) {
|
|
64
|
-
info.report.addComment(`${info.position}Different environment names. ${info.leftname}: ${a.name} vs. ${info.rightname}: ${b.name}`);
|
|
65
|
-
}
|
|
66
59
|
if (a.memory.size !== b.memory.size) {
|
|
67
|
-
info.report.addComment(`${info.position}Different environment
|
|
60
|
+
info.report.addComment(`${info.position}[at level: ${depth}] Different number of definitions in environment. ${info.leftname}: ${a.memory.size} vs. ${info.rightname}: ${b.memory.size}`);
|
|
68
61
|
(0, diff_1.setDifference)(new Set([...a.memory.keys()]), new Set([...b.memory.keys()]), {
|
|
69
62
|
...info,
|
|
70
|
-
position: `${info.position}Key comparison. `
|
|
63
|
+
position: `${info.position}[at level: ${depth}] Key comparison. `
|
|
71
64
|
});
|
|
72
65
|
}
|
|
73
|
-
diffMemory(a, b, info);
|
|
74
|
-
diffEnvironment(a.parent, b.parent, { ...info, position: `${info.position}Parents of ${a.id} & ${b.id}. ` });
|
|
66
|
+
diffMemory(a, b, { ...info, position: `${info.position}[at level: ${depth}] ` });
|
|
67
|
+
diffEnvironment(a.parent, b.parent, { ...info, position: `${info.position}Parents of ${a.id} & ${b.id}. ` }, depth--);
|
|
75
68
|
}
|
|
76
69
|
exports.diffEnvironment = diffEnvironment;
|
|
77
70
|
function diffEnvironmentInformation(a, b, info) {
|
|
78
71
|
if (a === undefined || b === undefined) {
|
|
79
|
-
|
|
72
|
+
if (a !== b) {
|
|
73
|
+
info.report.addComment(`${info.position}Different environments: ${JSON.stringify(a, json_1.jsonReplacer)} vs. ${JSON.stringify(b, json_1.jsonReplacer)}`);
|
|
74
|
+
}
|
|
80
75
|
return;
|
|
81
76
|
}
|
|
82
|
-
|
|
77
|
+
if (a.level !== b.level) {
|
|
78
|
+
info.report.addComment(`${info.position}Different environment levels: ${info.leftname}: ${a.level} vs. ${info.rightname}: ${b.level}. Using max to report level for further errors.`);
|
|
79
|
+
}
|
|
80
|
+
diffEnvironment(a.current, b.current, info, Math.max(a.level, b.level));
|
|
83
81
|
}
|
|
84
82
|
exports.diffEnvironmentInformation = diffEnvironmentInformation;
|
|
85
83
|
//# sourceMappingURL=diff.js.map
|
|
@@ -6,26 +6,25 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { Identifier, IdentifierDefinition, IdentifierReference } from './identifier';
|
|
8
8
|
import type { DataflowGraph } from '../graph/graph';
|
|
9
|
-
import type {
|
|
10
|
-
export declare function makeReferenceMaybe(ref: IdentifierReference, graph: DataflowGraph, environments: REnvironmentInformation, includeDefs: boolean, defaultCd?:
|
|
11
|
-
export declare function makeAllMaybe(references: readonly IdentifierReference[] | undefined, graph: DataflowGraph, environments: REnvironmentInformation, includeDefs: boolean, defaultCd?:
|
|
9
|
+
import type { ControlDependency } from '../info';
|
|
10
|
+
export declare function makeReferenceMaybe(ref: IdentifierReference, graph: DataflowGraph, environments: REnvironmentInformation, includeDefs: boolean, defaultCd?: ControlDependency | undefined): IdentifierReference;
|
|
11
|
+
export declare function makeAllMaybe(references: readonly IdentifierReference[] | undefined, graph: DataflowGraph, environments: REnvironmentInformation, includeDefs: boolean, defaultCd?: ControlDependency | undefined): IdentifierReference[];
|
|
12
|
+
export type EnvironmentMemory = Map<Identifier, IdentifierDefinition[]>;
|
|
12
13
|
export interface IEnvironment {
|
|
13
14
|
/** unique and internally generated identifier -- will not be used for comparison but assists debugging for tracking identities */
|
|
14
15
|
readonly id: string;
|
|
15
|
-
readonly name: string;
|
|
16
16
|
/** Lexical parent of the environment, if any (can be manipulated by R code) */
|
|
17
17
|
parent: IEnvironment;
|
|
18
18
|
/**
|
|
19
19
|
* Maps to exactly one definition of an identifier if the source is known, otherwise to a list of all possible definitions
|
|
20
20
|
*/
|
|
21
|
-
memory:
|
|
21
|
+
memory: EnvironmentMemory;
|
|
22
22
|
}
|
|
23
23
|
export declare class Environment implements IEnvironment {
|
|
24
|
-
readonly name: string;
|
|
25
24
|
readonly id: string;
|
|
26
25
|
parent: IEnvironment;
|
|
27
26
|
memory: Map<Identifier, IdentifierDefinition[]>;
|
|
28
|
-
constructor(
|
|
27
|
+
constructor(parent: IEnvironment);
|
|
29
28
|
}
|
|
30
29
|
/**
|
|
31
30
|
* First of all, yes, R stores its environments differently, potentially even with a different differentiation between
|
|
@@ -41,5 +40,4 @@ export interface REnvironmentInformation {
|
|
|
41
40
|
readonly level: number;
|
|
42
41
|
}
|
|
43
42
|
export declare const BuiltInEnvironment: Environment;
|
|
44
|
-
export declare const GLOBAL_ENV_NAME = "global";
|
|
45
43
|
export declare function initializeCleanEnvironments(): REnvironmentInformation;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.initializeCleanEnvironments = exports.
|
|
3
|
+
exports.initializeCleanEnvironments = exports.BuiltInEnvironment = exports.Environment = exports.makeAllMaybe = exports.makeReferenceMaybe = void 0;
|
|
4
4
|
const built_in_1 = require("./built-in");
|
|
5
5
|
const resolve_by_name_1 = require("./resolve-by-name");
|
|
6
6
|
function makeReferenceMaybe(ref, graph, environments, includeDefs, defaultCd = undefined) {
|
|
@@ -9,7 +9,7 @@ function makeReferenceMaybe(ref, graph, environments, includeDefs, defaultCd = u
|
|
|
9
9
|
const definitions = ref.name ? (0, resolve_by_name_1.resolveByName)(ref.name, environments) : undefined;
|
|
10
10
|
for (const definition of definitions ?? []) {
|
|
11
11
|
if (definition.kind !== 'built-in-function' && definition.kind !== 'built-in-value') {
|
|
12
|
-
if (definition.controlDependencies && defaultCd && !definition.controlDependencies.
|
|
12
|
+
if (definition.controlDependencies && defaultCd && !definition.controlDependencies.find(c => c.id === defaultCd.id)) {
|
|
13
13
|
definition.controlDependencies.push(defaultCd);
|
|
14
14
|
}
|
|
15
15
|
else {
|
|
@@ -38,24 +38,21 @@ function makeAllMaybe(references, graph, environments, includeDefs, defaultCd =
|
|
|
38
38
|
exports.makeAllMaybe = makeAllMaybe;
|
|
39
39
|
let environmentIdCounter = 0;
|
|
40
40
|
class Environment {
|
|
41
|
-
name;
|
|
42
41
|
id = `${environmentIdCounter++}`;
|
|
43
42
|
parent;
|
|
44
43
|
memory;
|
|
45
|
-
constructor(
|
|
46
|
-
this.name = name;
|
|
44
|
+
constructor(parent) {
|
|
47
45
|
this.parent = parent;
|
|
48
46
|
this.memory = new Map();
|
|
49
47
|
}
|
|
50
48
|
}
|
|
51
49
|
exports.Environment = Environment;
|
|
52
50
|
/* the built-in environment is the root of all environments */
|
|
53
|
-
exports.BuiltInEnvironment = new Environment(
|
|
51
|
+
exports.BuiltInEnvironment = new Environment(undefined);
|
|
54
52
|
exports.BuiltInEnvironment.memory = built_in_1.BuiltInMemory;
|
|
55
|
-
exports.GLOBAL_ENV_NAME = 'global';
|
|
56
53
|
function initializeCleanEnvironments() {
|
|
57
54
|
return {
|
|
58
|
-
current: new Environment(exports.
|
|
55
|
+
current: new Environment(exports.BuiltInEnvironment),
|
|
59
56
|
level: 0
|
|
60
57
|
};
|
|
61
58
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { BuiltInIdentifierConstant, BuiltInIdentifierDefinition } from './built-in';
|
|
2
2
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
3
|
+
import type { ControlDependency } from '../info';
|
|
3
4
|
export type Identifier = string & {
|
|
4
5
|
__brand?: 'identifier';
|
|
5
6
|
};
|
|
@@ -26,6 +27,6 @@ export interface IdentifierReference {
|
|
|
26
27
|
* If the reference is only effective if, e.g. an if-then-else condition is true, this references the root of the `if`.
|
|
27
28
|
* As a hackey intermediate solution (until we have pointer-analysis), an empty array may indicate a `maybe` which is due to pointer access (e.g., in `a[x] <- 3`).
|
|
28
29
|
*/
|
|
29
|
-
controlDependencies:
|
|
30
|
+
controlDependencies: ControlDependency[] | undefined;
|
|
30
31
|
}
|
|
31
32
|
export {};
|
|
@@ -16,7 +16,6 @@ function anyIsMaybeOrEmpty(values) {
|
|
|
16
16
|
}
|
|
17
17
|
function overwriteIEnvironmentWith(base, next, includeParent = true) {
|
|
18
18
|
(0, assert_1.guard)(base !== undefined && next !== undefined, 'can not overwrite environments with undefined');
|
|
19
|
-
(0, assert_1.guard)(base.name === next.name, 'cannot overwrite environments with different names');
|
|
20
19
|
const map = new Map(base.memory);
|
|
21
20
|
for (const [key, values] of next.memory) {
|
|
22
21
|
const hasMaybe = anyIsMaybeOrEmpty(values);
|
|
@@ -43,7 +42,7 @@ function overwriteIEnvironmentWith(base, next, includeParent = true) {
|
|
|
43
42
|
else {
|
|
44
43
|
parent = base.parent;
|
|
45
44
|
}
|
|
46
|
-
const out = new environment_1.Environment(
|
|
45
|
+
const out = new environment_1.Environment(parent);
|
|
47
46
|
out.memory = map;
|
|
48
47
|
return out;
|
|
49
48
|
}
|
|
@@ -6,7 +6,7 @@ const assert_1 = require("../../util/assert");
|
|
|
6
6
|
/** Add a new local environment scope to the stack, returns the modified variant - sharing the original environments in the stack (no deep-clone) */
|
|
7
7
|
function pushLocalEnvironment(base) {
|
|
8
8
|
return {
|
|
9
|
-
current: new environment_1.Environment(
|
|
9
|
+
current: new environment_1.Environment(base.current),
|
|
10
10
|
level: base.level + 1
|
|
11
11
|
};
|
|
12
12
|
}
|
package/dataflow/graph/diff.js
CHANGED
|
@@ -9,6 +9,7 @@ const edge_1 = require("./edge");
|
|
|
9
9
|
const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
|
|
10
10
|
const diff_2 = require("../environments/diff");
|
|
11
11
|
const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
12
|
+
const info_1 = require("../info");
|
|
12
13
|
class DataflowDifferenceReport {
|
|
13
14
|
_comments = undefined;
|
|
14
15
|
_problematic = undefined;
|
|
@@ -62,10 +63,18 @@ function diffOutgoingEdges(ctx) {
|
|
|
62
63
|
ctx.report.addComment(`Detected different number of edges! ${ctx.leftname} has ${lEdges.size} (${JSON.stringify(lEdges, json_1.jsonReplacer)}). ${ctx.rightname} has ${rEdges.size} ${JSON.stringify(rEdges, json_1.jsonReplacer)}`);
|
|
63
64
|
}
|
|
64
65
|
for (const [id, edge] of lEdges) {
|
|
66
|
+
if (!ctx.left.hasVertex(id)) {
|
|
67
|
+
ctx.report.addComment(`The source ${id} of edges ${JSON.stringify(edge, json_1.jsonReplacer)} is not present in ${ctx.leftname}. This means that the graph contains an edge but not the corresponding vertex.`);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
65
70
|
diffEdges(ctx, id, edge, rEdges.get(id));
|
|
66
71
|
}
|
|
67
72
|
// just to make it both ways in case the length differs
|
|
68
73
|
for (const [id, edge] of rEdges) {
|
|
74
|
+
if (!ctx.right.hasVertex(id)) {
|
|
75
|
+
ctx.report.addComment(`The source ${id} of edges ${JSON.stringify(edge, json_1.jsonReplacer)} is not present in ${ctx.rightname}. This means that the graph contains an edge but not the corresponding vertex.`);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
69
78
|
if (!lEdges.has(id)) {
|
|
70
79
|
diffEdges(ctx, id, undefined, edge);
|
|
71
80
|
}
|
|
@@ -137,9 +146,7 @@ function diffFunctionArguments(fn, a, b, ctx) {
|
|
|
137
146
|
if (aArg.name !== bArg.name) {
|
|
138
147
|
ctx.report.addComment(`${ctx.position}In argument #${i} (of ${ctx.leftname}, unnamed) the name differs: ${aArg.name} vs ${bArg.name}.`);
|
|
139
148
|
}
|
|
140
|
-
|
|
141
|
-
ctx.report.addComment(`${ctx.position}In argument #${i} (of ${ctx.leftname}, unnamed) the control dependency differs: ${JSON.stringify(aArg.controlDependencies)} vs ${JSON.stringify(bArg.controlDependencies)}.`, { tag: 'vertex', id: fn });
|
|
142
|
-
}
|
|
149
|
+
(0, info_1.diffControlDependencies)(aArg.controlDependencies, bArg.controlDependencies, { ...ctx, position: `${ctx.position}In argument #${i} (of ${ctx.leftname}, unnamed) the control dependency differs: ${JSON.stringify(aArg.controlDependencies)} vs ${JSON.stringify(bArg.controlDependencies)}.` });
|
|
143
150
|
}
|
|
144
151
|
}
|
|
145
152
|
}
|
|
@@ -173,9 +180,7 @@ function diffVertices(ctx) {
|
|
|
173
180
|
});
|
|
174
181
|
}
|
|
175
182
|
}
|
|
176
|
-
|
|
177
|
-
ctx.report.addComment(`Vertex ${id} differs in controlDependency. ${ctx.leftname}: ${JSON.stringify(lInfo.controlDependencies)} vs ${ctx.rightname}: ${JSON.stringify(rInfo.controlDependencies)}`, { tag: 'vertex', id });
|
|
178
|
-
}
|
|
183
|
+
(0, info_1.diffControlDependencies)(lInfo.controlDependencies, rInfo.controlDependencies, { ...ctx, position: `Vertex ${id} differs in controlDependencies. ` });
|
|
179
184
|
(0, diff_2.diffEnvironmentInformation)(lInfo.environment, rInfo.environment, { ...ctx, position: `${ctx.position}Vertex ${id} differs in environment. ` });
|
|
180
185
|
if (lInfo.tag === "function-call" /* VertexType.FunctionCall */) {
|
|
181
186
|
if (rInfo.tag !== "function-call" /* VertexType.FunctionCall */) {
|
package/dataflow/graph/edge.d.ts
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* An edge consist of:
|
|
3
3
|
* - the target node (i.e., the variable or processing node),
|
|
4
4
|
* - a type (if it is read or used in the context), and
|
|
5
|
-
* - an attribute (if this edge exists for every program execution or if it is only one possible execution path).
|
|
6
5
|
*/
|
|
7
6
|
export interface DataflowGraphEdge {
|
|
8
7
|
types: EdgeTypeBits;
|
|
@@ -40,8 +39,8 @@ export declare const enum EdgeTypeName {
|
|
|
40
39
|
DefinedBy = "defined-by",
|
|
41
40
|
Calls = "calls",
|
|
42
41
|
Returns = "returns",
|
|
43
|
-
DefinesOnCall = "
|
|
44
|
-
DefinedByOnCall = "
|
|
42
|
+
DefinesOnCall = "defines-on-call",
|
|
43
|
+
DefinedByOnCall = "defined-by-on-call",
|
|
45
44
|
Argument = "argument",
|
|
46
45
|
SideEffectOnCall = "side-effect-on-call",
|
|
47
46
|
NonStandardEvaluation = "non-standard-evaluation"
|
package/dataflow/graph/edge.js
CHANGED
|
@@ -6,8 +6,8 @@ const edgeTypeToHumanReadableName = new Map([
|
|
|
6
6
|
[2 /* EdgeType.DefinedBy */, "defined-by" /* EdgeTypeName.DefinedBy */],
|
|
7
7
|
[4 /* EdgeType.Calls */, "calls" /* EdgeTypeName.Calls */],
|
|
8
8
|
[8 /* EdgeType.Returns */, "returns" /* EdgeTypeName.Returns */],
|
|
9
|
-
[16 /* EdgeType.DefinesOnCall */, "
|
|
10
|
-
[32 /* EdgeType.DefinedByOnCall */, "
|
|
9
|
+
[16 /* EdgeType.DefinesOnCall */, "defines-on-call" /* EdgeTypeName.DefinesOnCall */],
|
|
10
|
+
[32 /* EdgeType.DefinedByOnCall */, "defined-by-on-call" /* EdgeTypeName.DefinedByOnCall */],
|
|
11
11
|
[64 /* EdgeType.Argument */, "argument" /* EdgeTypeName.Argument */],
|
|
12
12
|
[128 /* EdgeType.SideEffectOnCall */, "side-effect-on-call" /* EdgeTypeName.SideEffectOnCall */],
|
|
13
13
|
[256 /* EdgeType.NonStandardEvaluation */, "non-standard-evaluation" /* EdgeTypeName.NonStandardEvaluation */]
|
|
@@ -46,7 +46,7 @@ type EdgeData<Edge extends DataflowGraphEdge> = Omit<Edge, 'from' | 'to' | 'type
|
|
|
46
46
|
*/
|
|
47
47
|
export declare class DataflowGraph<Vertex extends DataflowGraphVertexInfo = DataflowGraphVertexInfo, Edge extends DataflowGraphEdge = DataflowGraphEdge> {
|
|
48
48
|
private static DEFAULT_ENVIRONMENT;
|
|
49
|
-
|
|
49
|
+
private _idMap;
|
|
50
50
|
constructor(idMap: AstIdMap | undefined);
|
|
51
51
|
/** Contains the vertices of the root level graph (i.e., included those vertices from the complete graph, that are nested within function definitions) */
|
|
52
52
|
private rootVertices;
|
|
@@ -76,6 +76,10 @@ export declare class DataflowGraph<Vertex extends DataflowGraphVertexInfo = Data
|
|
|
76
76
|
getVertex(id: NodeId, includeDefinedFunctions?: boolean): Vertex | undefined;
|
|
77
77
|
outgoingEdges(id: NodeId): OutgoingEdges | undefined;
|
|
78
78
|
ingoingEdges(id: NodeId): IngoingEdges | undefined;
|
|
79
|
+
/** Retrieves the id-map to the normalized AST attached to the dataflow graph */
|
|
80
|
+
get idMap(): AstIdMap | undefined;
|
|
81
|
+
/** Allows setting the id-map explicitly (which should only be used when, e.g., you plan to compare two dataflow graphs on the same AST-basis) */
|
|
82
|
+
setIdMap(idMap: AstIdMap): void;
|
|
79
83
|
/**
|
|
80
84
|
* @param includeDefinedFunctions - If true this will iterate over function definitions as well and not just the toplevel
|
|
81
85
|
* @returns the ids of all toplevel vertices in the graph together with their vertex information
|
|
@@ -95,7 +99,7 @@ export declare class DataflowGraph<Vertex extends DataflowGraphVertexInfo = Data
|
|
|
95
99
|
* @param id - The id to check for
|
|
96
100
|
* @param includeDefinedFunctions - If true this will check function definitions as well and not just the toplevel
|
|
97
101
|
*/
|
|
98
|
-
hasVertex(id: NodeId, includeDefinedFunctions
|
|
102
|
+
hasVertex(id: NodeId, includeDefinedFunctions?: boolean): boolean;
|
|
99
103
|
/**
|
|
100
104
|
* Returns true if the root level of the graph contains a node with the given id.
|
|
101
105
|
*/
|
package/dataflow/graph/graph.js
CHANGED
|
@@ -7,6 +7,7 @@ const arrays_1 = require("../../util/arrays");
|
|
|
7
7
|
const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
8
8
|
const environment_1 = require("../environments/environment");
|
|
9
9
|
const clone_1 = require("../environments/clone");
|
|
10
|
+
const built_in_1 = require("../environments/built-in");
|
|
10
11
|
function isPositionalArgument(arg) {
|
|
11
12
|
return arg !== r_function_call_1.EmptyArgument && arg.name === undefined;
|
|
12
13
|
}
|
|
@@ -40,10 +41,10 @@ function extractEdgeIds(from, to) {
|
|
|
40
41
|
*/
|
|
41
42
|
class DataflowGraph {
|
|
42
43
|
static DEFAULT_ENVIRONMENT = undefined;
|
|
43
|
-
|
|
44
|
+
_idMap;
|
|
44
45
|
constructor(idMap) {
|
|
45
46
|
DataflowGraph.DEFAULT_ENVIRONMENT ??= (0, environment_1.initializeCleanEnvironments)();
|
|
46
|
-
this.
|
|
47
|
+
this._idMap = idMap;
|
|
47
48
|
}
|
|
48
49
|
/** Contains the vertices of the root level graph (i.e., included those vertices from the complete graph, that are nested within function definitions) */
|
|
49
50
|
rootVertices = new Set();
|
|
@@ -89,6 +90,14 @@ class DataflowGraph {
|
|
|
89
90
|
}
|
|
90
91
|
return edges;
|
|
91
92
|
}
|
|
93
|
+
/** Retrieves the id-map to the normalized AST attached to the dataflow graph */
|
|
94
|
+
get idMap() {
|
|
95
|
+
return this._idMap;
|
|
96
|
+
}
|
|
97
|
+
/** Allows setting the id-map explicitly (which should only be used when, e.g., you plan to compare two dataflow graphs on the same AST-basis) */
|
|
98
|
+
setIdMap(idMap) {
|
|
99
|
+
this._idMap = idMap;
|
|
100
|
+
}
|
|
92
101
|
/**
|
|
93
102
|
* @param includeDefinedFunctions - If true this will iterate over function definitions as well and not just the toplevel
|
|
94
103
|
* @returns the ids of all toplevel vertices in the graph together with their vertex information
|
|
@@ -119,7 +128,7 @@ class DataflowGraph {
|
|
|
119
128
|
* @param id - The id to check for
|
|
120
129
|
* @param includeDefinedFunctions - If true this will check function definitions as well and not just the toplevel
|
|
121
130
|
*/
|
|
122
|
-
hasVertex(id, includeDefinedFunctions) {
|
|
131
|
+
hasVertex(id, includeDefinedFunctions = true) {
|
|
123
132
|
return includeDefinedFunctions ? this.vertexInformation.has(id) : this.rootVertices.has(id);
|
|
124
133
|
}
|
|
125
134
|
/**
|
|
@@ -146,11 +155,11 @@ class DataflowGraph {
|
|
|
146
155
|
if (oldVertex !== undefined) {
|
|
147
156
|
return this;
|
|
148
157
|
}
|
|
158
|
+
const fallback = vertex.tag === "variable-definition" /* VertexType.VariableDefinition */ || vertex.tag === "use" /* VertexType.Use */ || vertex.tag === "value" /* VertexType.Value */ ? undefined : DataflowGraph.DEFAULT_ENVIRONMENT;
|
|
149
159
|
// keep a clone of the original environment
|
|
150
|
-
const environment = vertex.environment === undefined ?
|
|
160
|
+
const environment = vertex.environment === undefined ? fallback : (0, clone_1.cloneEnvironmentInformation)(vertex.environment);
|
|
151
161
|
this.vertexInformation.set(vertex.id, {
|
|
152
162
|
...vertex,
|
|
153
|
-
when: vertex.controlDependencies ?? 'always',
|
|
154
163
|
environment
|
|
155
164
|
});
|
|
156
165
|
if (asRoot) {
|
|
@@ -162,11 +171,12 @@ class DataflowGraph {
|
|
|
162
171
|
* Will insert a new edge into the graph,
|
|
163
172
|
* if the direction of the edge is of no importance (`same-read-read` or `same-def-def`), source
|
|
164
173
|
* and target will be sorted so that `from` has the lower, and `to` the higher id (default ordering).
|
|
174
|
+
* Please note, that this will never make edges to {@link BuiltIn} as they are not part of the graph.
|
|
165
175
|
*/
|
|
166
176
|
addEdge(from, to, edgeInfo) {
|
|
167
177
|
const { fromId, toId } = extractEdgeIds(from, to);
|
|
168
178
|
const { type, ...rest } = edgeInfo;
|
|
169
|
-
if (fromId === toId) {
|
|
179
|
+
if (fromId === toId || toId === built_in_1.BuiltIn) {
|
|
170
180
|
return this;
|
|
171
181
|
}
|
|
172
182
|
/* we now that we pass all required arguments */
|
|
@@ -263,9 +273,6 @@ class DataflowGraph {
|
|
|
263
273
|
const vertex = this.getVertex(reference.nodeId, true);
|
|
264
274
|
(0, assert_1.guard)(vertex !== undefined, () => `node must be defined for ${JSON.stringify(reference)} to set reference`);
|
|
265
275
|
if (vertex.tag === "function-definition" /* VertexType.FunctionDefinition */ || vertex.tag === "variable-definition" /* VertexType.VariableDefinition */) {
|
|
266
|
-
(0, assert_1.guard)(vertex.controlDependencies !== undefined
|
|
267
|
-
|| reference.controlDependencies !== undefined
|
|
268
|
-
|| (0, arrays_1.arrayEqual)(vertex.controlDependencies, reference.controlDependencies), () => `node ${JSON.stringify(vertex)} must not be previously defined at position or have same scope for ${JSON.stringify(reference)}`);
|
|
269
276
|
vertex.controlDependencies = reference.controlDependencies;
|
|
270
277
|
}
|
|
271
278
|
else {
|
|
@@ -2,6 +2,7 @@ import type { MergeableRecord } from '../../util/objects';
|
|
|
2
2
|
import type { DataflowFunctionFlowInformation, FunctionArgument } from './graph';
|
|
3
3
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
4
4
|
import type { REnvironmentInformation } from '../environments/environment';
|
|
5
|
+
import type { ControlDependency } from '../info';
|
|
5
6
|
export type DataflowGraphVertices<Vertex extends DataflowGraphVertexInfo = DataflowGraphVertexInfo> = Map<NodeId, Vertex>;
|
|
6
7
|
export declare const enum VertexType {
|
|
7
8
|
Value = "value",
|
|
@@ -33,7 +34,7 @@ interface DataflowGraphVertexBase extends MergeableRecord {
|
|
|
33
34
|
/**
|
|
34
35
|
* See {@link IdentifierReference}
|
|
35
36
|
*/
|
|
36
|
-
controlDependencies:
|
|
37
|
+
controlDependencies: ControlDependency[] | undefined;
|
|
37
38
|
}
|
|
38
39
|
export interface DataflowGraphValue extends DataflowGraphVertexBase {
|
|
39
40
|
readonly tag: VertexType.Value;
|
package/dataflow/info.d.ts
CHANGED
|
@@ -3,16 +3,22 @@ import type { NodeId } from '../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
|
3
3
|
import type { IdentifierReference } from './environments/identifier';
|
|
4
4
|
import type { REnvironmentInformation } from './environments/environment';
|
|
5
5
|
import { DataflowGraph } from './graph/graph';
|
|
6
|
+
import type { GenericDifferenceInformation, WriteableDifferenceReport } from '../util/diff';
|
|
6
7
|
export declare const enum ExitPointType {
|
|
7
8
|
Default = 0,
|
|
8
9
|
Return = 1,
|
|
9
10
|
Break = 2,
|
|
10
11
|
Next = 3
|
|
11
12
|
}
|
|
13
|
+
export interface ControlDependency {
|
|
14
|
+
readonly id: NodeId;
|
|
15
|
+
/** when does this control dependency trigger (if the condition is true or false)? */
|
|
16
|
+
readonly when?: boolean;
|
|
17
|
+
}
|
|
12
18
|
export interface ExitPoint {
|
|
13
19
|
readonly type: ExitPointType;
|
|
14
20
|
readonly nodeId: NodeId;
|
|
15
|
-
readonly controlDependencies:
|
|
21
|
+
readonly controlDependencies: ControlDependency[] | undefined;
|
|
16
22
|
}
|
|
17
23
|
export declare function addNonDefaultExitPoints(existing: ExitPoint[], add: readonly ExitPoint[]): void;
|
|
18
24
|
/**
|
|
@@ -45,5 +51,8 @@ export interface DataflowInformation extends DataflowCfgInformation {
|
|
|
45
51
|
graph: DataflowGraph;
|
|
46
52
|
}
|
|
47
53
|
export declare function initializeCleanDataflowInformation<T>(entryPoint: NodeId, data: Pick<DataflowProcessorInformation<T>, 'environment' | 'completeAst'>): DataflowInformation;
|
|
54
|
+
export declare function happensInEveryBranch(controlDependencies: ControlDependency[] | undefined): boolean;
|
|
48
55
|
export declare function alwaysExits(data: DataflowInformation): boolean;
|
|
49
56
|
export declare function filterOutLoopExitPoints(exitPoints: readonly ExitPoint[]): readonly ExitPoint[];
|
|
57
|
+
export declare function diffControlDependency<Report extends WriteableDifferenceReport>(a: ControlDependency | undefined, b: ControlDependency | undefined, info: GenericDifferenceInformation<Report>): void;
|
|
58
|
+
export declare function diffControlDependencies<Report extends WriteableDifferenceReport>(a: ControlDependency[] | undefined, b: ControlDependency[] | undefined, info: GenericDifferenceInformation<Report>): void;
|
package/dataflow/info.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.filterOutLoopExitPoints = exports.alwaysExits = exports.initializeCleanDataflowInformation = exports.addNonDefaultExitPoints = void 0;
|
|
3
|
+
exports.diffControlDependencies = exports.diffControlDependency = exports.filterOutLoopExitPoints = exports.alwaysExits = exports.happensInEveryBranch = exports.initializeCleanDataflowInformation = exports.addNonDefaultExitPoints = void 0;
|
|
4
4
|
const graph_1 = require("./graph/graph");
|
|
5
5
|
function addNonDefaultExitPoints(existing, add) {
|
|
6
6
|
existing.push(...add.filter(({ type }) => type !== 0 /* ExitPointType.Default */));
|
|
@@ -18,12 +18,64 @@ function initializeCleanDataflowInformation(entryPoint, data) {
|
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
20
|
exports.initializeCleanDataflowInformation = initializeCleanDataflowInformation;
|
|
21
|
+
function happensInEveryBranch(controlDependencies) {
|
|
22
|
+
if (controlDependencies === undefined) {
|
|
23
|
+
/* the cds are unconstrained */
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
else if (controlDependencies.length === 0) {
|
|
27
|
+
/* this happens only when we have no idea and require more analysis */
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
const trues = [];
|
|
31
|
+
const falseSet = new Set();
|
|
32
|
+
for (const { id, when } of controlDependencies) {
|
|
33
|
+
if (when) {
|
|
34
|
+
trues.push(id);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
falseSet.add(id);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return trues.every(id => falseSet.has(id));
|
|
41
|
+
}
|
|
42
|
+
exports.happensInEveryBranch = happensInEveryBranch;
|
|
21
43
|
function alwaysExits(data) {
|
|
22
|
-
return data.exitPoints?.some(e => e.type !== 0 /* ExitPointType.Default */ && e.controlDependencies
|
|
44
|
+
return data.exitPoints?.some(e => e.type !== 0 /* ExitPointType.Default */ && happensInEveryBranch(e.controlDependencies)) ?? false;
|
|
23
45
|
}
|
|
24
46
|
exports.alwaysExits = alwaysExits;
|
|
25
47
|
function filterOutLoopExitPoints(exitPoints) {
|
|
26
48
|
return exitPoints.filter(({ type }) => type === 1 /* ExitPointType.Return */ || type === 0 /* ExitPointType.Default */);
|
|
27
49
|
}
|
|
28
50
|
exports.filterOutLoopExitPoints = filterOutLoopExitPoints;
|
|
51
|
+
function diffControlDependency(a, b, info) {
|
|
52
|
+
if (a === undefined || b === undefined) {
|
|
53
|
+
if (a !== b) {
|
|
54
|
+
info.report.addComment(`${info.position}Different control dependencies. ${info.leftname}: ${JSON.stringify(a)} vs. ${info.rightname}: ${JSON.stringify(b)}`);
|
|
55
|
+
}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (a.id !== b.id) {
|
|
59
|
+
info.report.addComment(`${info.position}Different control dependency ids. ${info.leftname}: ${a.id} vs. ${info.rightname}: ${b.id}`);
|
|
60
|
+
}
|
|
61
|
+
if (a.when !== b.when) {
|
|
62
|
+
info.report.addComment(`${info.position}Different control dependency when. ${info.leftname}: ${a.when} vs. ${info.rightname}: ${b.when}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.diffControlDependency = diffControlDependency;
|
|
66
|
+
function diffControlDependencies(a, b, info) {
|
|
67
|
+
if (a === undefined || b === undefined) {
|
|
68
|
+
if (a !== b) {
|
|
69
|
+
info.report.addComment(`${info.position}Different control dependencies: ${JSON.stringify(a)} vs. ${JSON.stringify(b)}`);
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (a.length !== b.length) {
|
|
74
|
+
info.report.addComment(`${info.position}Different control dependency lengths: ${a.length} vs. ${b.length}`);
|
|
75
|
+
}
|
|
76
|
+
for (let i = 0; i < a.length; ++i) {
|
|
77
|
+
diffControlDependency(a[i], b[i], { ...info, position: `${info.position}Control dependency at index: ${i}: ` });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.diffControlDependencies = diffControlDependencies;
|
|
29
81
|
//# sourceMappingURL=info.js.map
|
|
@@ -17,7 +17,7 @@ export declare function linkFunctionCalls(graph: DataflowGraph, idMap: AstIdMap,
|
|
|
17
17
|
functionCall: NodeId;
|
|
18
18
|
called: readonly DataflowGraphVertexInfo[];
|
|
19
19
|
}[];
|
|
20
|
-
export declare function getAllLinkedFunctionDefinitions(functionDefinitionReadIds:
|
|
20
|
+
export declare function getAllLinkedFunctionDefinitions(functionDefinitionReadIds: ReadonlySet<NodeId>, dataflowGraph: DataflowGraph): Map<NodeId, DataflowGraphVertexInfo>;
|
|
21
21
|
/**
|
|
22
22
|
* This method links a set of read variables to definitions in an environment.
|
|
23
23
|
*
|
|
@@ -136,9 +136,8 @@ function getAllLinkedFunctionDefinitions(functionDefinitionReadIds, dataflowGrap
|
|
|
136
136
|
const result = new Map();
|
|
137
137
|
while (potential.length > 0) {
|
|
138
138
|
const currentId = potential.pop();
|
|
139
|
+
// do not traverse builtins
|
|
139
140
|
if (currentId === built_in_1.BuiltIn) {
|
|
140
|
-
// do not traverse builtins
|
|
141
|
-
static_slicer_1.slicerLogger.trace('skipping builtin function definition during collection');
|
|
142
141
|
continue;
|
|
143
142
|
}
|
|
144
143
|
const currentInfo = dataflowGraph.get(currentId, true);
|