@eagleoutice/flowr 2.2.11 → 2.2.12
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 +4 -4
- package/benchmark/slicer.d.ts +49 -22
- package/benchmark/slicer.js +88 -28
- package/benchmark/stats/print.js +16 -10
- package/benchmark/stats/size-of.js +18 -1
- package/benchmark/stats/stats.d.ts +3 -0
- package/benchmark/summarizer/second-phase/process.js +8 -2
- package/cli/benchmark-app.d.ts +5 -0
- package/cli/benchmark-app.js +49 -6
- package/cli/benchmark-helper-app.d.ts +4 -0
- package/cli/benchmark-helper-app.js +20 -4
- package/cli/common/options.js +13 -4
- package/cli/repl/commands/repl-commands.js +2 -0
- package/cli/repl/commands/repl-dataflow.d.ts +2 -0
- package/cli/repl/commands/repl-dataflow.js +35 -1
- package/config.d.ts +18 -2
- package/config.js +24 -4
- package/dataflow/environments/built-in-config.d.ts +5 -2
- package/dataflow/environments/built-in-config.js +8 -2
- package/dataflow/environments/built-in.d.ts +8 -1
- package/dataflow/environments/built-in.js +8 -1
- package/dataflow/environments/clone.d.ts +5 -0
- package/dataflow/environments/clone.js +5 -0
- package/dataflow/environments/default-builtin-config.js +93 -9
- package/dataflow/environments/define.d.ts +5 -1
- package/dataflow/environments/define.js +36 -10
- package/dataflow/environments/overwrite.js +4 -0
- package/dataflow/environments/remove.d.ts +6 -0
- package/dataflow/environments/remove.js +24 -0
- package/dataflow/environments/resolve-by-name.js +1 -1
- package/dataflow/graph/dataflowgraph-builder.d.ts +76 -6
- package/dataflow/graph/dataflowgraph-builder.js +102 -6
- package/dataflow/graph/graph.d.ts +6 -1
- package/dataflow/graph/graph.js +24 -0
- package/dataflow/graph/vertex.d.ts +42 -2
- package/dataflow/graph/vertex.js +32 -0
- package/dataflow/internal/linker.js +3 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +1 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +55 -45
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +6 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +27 -8
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +37 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +10 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +140 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-list.js +51 -17
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +3 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +83 -29
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.d.ts +7 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +41 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +17 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.d.ts +15 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +75 -0
- package/dataflow/internal/process/functions/call/common.d.ts +1 -1
- package/dataflow/internal/process/functions/call/common.js +4 -2
- package/dataflow/internal/process/functions/call/named-call-handling.d.ts +2 -0
- package/dataflow/internal/process/functions/call/named-call-handling.js +9 -5
- package/dataflow/internal/process/process-named-call.d.ts +3 -0
- package/dataflow/internal/process/process-named-call.js +3 -0
- package/documentation/doc-util/doc-cfg.d.ts +11 -2
- package/documentation/doc-util/doc-cfg.js +35 -6
- package/documentation/doc-util/doc-code.js +10 -2
- package/documentation/print-capabilities-markdown.js +1 -1
- package/documentation/print-cfg-wiki.d.ts +1 -0
- package/documentation/print-cfg-wiki.js +84 -0
- package/documentation/print-core-wiki.js +2 -2
- package/documentation/print-interface-wiki.js +1 -0
- package/documentation/print-query-wiki.js +2 -2
- package/package.json +2 -1
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +13 -5
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -25
- package/queries/catalog/dependencies-query/dependencies-query-format.js +2 -145
- package/queries/catalog/dependencies-query/function-info/function-info.d.ts +24 -0
- package/queries/catalog/dependencies-query/function-info/function-info.js +10 -0
- package/queries/catalog/dependencies-query/function-info/library-functions.d.ts +2 -0
- package/queries/catalog/dependencies-query/function-info/library-functions.js +18 -0
- package/queries/catalog/dependencies-query/function-info/read-functions.d.ts +2 -0
- package/queries/catalog/dependencies-query/function-info/read-functions.js +101 -0
- package/queries/catalog/dependencies-query/function-info/source-functions.d.ts +2 -0
- package/queries/catalog/dependencies-query/function-info/source-functions.js +11 -0
- package/queries/catalog/dependencies-query/function-info/write-functions.d.ts +2 -0
- package/queries/catalog/dependencies-query/function-info/write-functions.js +87 -0
- package/r-bridge/data/data.d.ts +2 -2
- package/r-bridge/data/data.js +2 -2
- package/util/arrays.d.ts +23 -0
- package/util/arrays.js +41 -0
- package/util/cfg/visitor.d.ts +1 -1
- package/util/cfg/visitor.js +2 -2
- package/util/{list-access.d.ts → containers.d.ts} +24 -4
- package/util/{list-access.js → containers.js} +42 -12
- package/util/mermaid/ast.js +12 -1
- package/util/mermaid/cfg.js +2 -2
- package/util/parallel.d.ts +2 -1
- package/util/parallel.js +11 -2
- package/util/prefix.d.ts +13 -0
- package/util/prefix.js +34 -0
- package/util/version.js +1 -1
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.dataflowStarCommand = exports.dataflowCommand = void 0;
|
|
36
|
+
exports.dataflowSimpleStarCommand = exports.dataflowSimplifiedCommand = exports.dataflowStarCommand = exports.dataflowCommand = void 0;
|
|
37
37
|
const default_pipelines_1 = require("../../../core/steps/pipeline/default-pipelines");
|
|
38
38
|
const retriever_1 = require("../../../r-bridge/retriever");
|
|
39
39
|
const dfg_1 = require("../../../util/mermaid/dfg");
|
|
@@ -86,4 +86,38 @@ exports.dataflowStarCommand = {
|
|
|
86
86
|
catch { /* do nothing this is a service thing */ }
|
|
87
87
|
}
|
|
88
88
|
};
|
|
89
|
+
exports.dataflowSimplifiedCommand = {
|
|
90
|
+
description: `Get simplified mermaid code for the dataflow graph of R code, start with '${retriever_1.fileProtocol}' to indicate a file`,
|
|
91
|
+
usageExample: ':dataflowsimple',
|
|
92
|
+
aliases: ['ds', 'dfs'],
|
|
93
|
+
script: false,
|
|
94
|
+
fn: async (output, shell, remainingLine) => {
|
|
95
|
+
const result = await replGetDataflow(shell, handleString(remainingLine));
|
|
96
|
+
const mermaid = (0, dfg_1.graphToMermaid)({ graph: result.dataflow.graph, includeEnvironments: false, simplified: true }).string;
|
|
97
|
+
output.stdout(mermaid);
|
|
98
|
+
try {
|
|
99
|
+
const clipboard = await Promise.resolve().then(() => __importStar(require('clipboardy')));
|
|
100
|
+
clipboard.default.writeSync(mermaid);
|
|
101
|
+
output.stdout(formatInfo(output, 'mermaid code', result.dataflow['.meta'].timing));
|
|
102
|
+
}
|
|
103
|
+
catch { /* do nothing this is a service thing */ }
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
exports.dataflowSimpleStarCommand = {
|
|
107
|
+
description: 'Returns the URL to mermaid.live',
|
|
108
|
+
usageExample: ':dataflowsimple*',
|
|
109
|
+
aliases: ['ds*', 'dfs*'],
|
|
110
|
+
script: false,
|
|
111
|
+
fn: async (output, shell, remainingLine) => {
|
|
112
|
+
const result = await replGetDataflow(shell, handleString(remainingLine));
|
|
113
|
+
const mermaid = (0, dfg_1.graphToMermaidUrl)(result.dataflow.graph, false, undefined, true);
|
|
114
|
+
output.stdout(mermaid);
|
|
115
|
+
try {
|
|
116
|
+
const clipboard = await Promise.resolve().then(() => __importStar(require('clipboardy')));
|
|
117
|
+
clipboard.default.writeSync(mermaid);
|
|
118
|
+
output.stdout(formatInfo(output, 'mermaid url', result.dataflow['.meta'].timing));
|
|
119
|
+
}
|
|
120
|
+
catch { /* do nothing this is a service thing */ }
|
|
121
|
+
}
|
|
122
|
+
};
|
|
89
123
|
//# sourceMappingURL=repl-dataflow.js.map
|
package/config.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { MergeableRecord } from './util/objects';
|
|
|
2
2
|
import Joi from 'joi';
|
|
3
3
|
import type { BuiltInDefinitions } from './dataflow/environments/built-in-config';
|
|
4
4
|
import type { KnownParser } from './r-bridge/parser';
|
|
5
|
+
import type { DeepPartial } from 'ts-essentials';
|
|
5
6
|
export declare enum VariableResolve {
|
|
6
7
|
/** Don't resolve constants at all */
|
|
7
8
|
Disabled = "disabled",
|
|
@@ -67,12 +68,21 @@ export interface FlowrConfigOptions extends MergeableRecord {
|
|
|
67
68
|
* How to resolve variables and their values
|
|
68
69
|
*/
|
|
69
70
|
readonly variables: VariableResolve;
|
|
71
|
+
/**
|
|
72
|
+
* Should we include eval(parse(text="...")) calls in the dataflow graph?
|
|
73
|
+
*/
|
|
74
|
+
readonly evalStrings: boolean;
|
|
70
75
|
/**
|
|
71
76
|
* Whether to track pointers in the dataflow graph,
|
|
72
77
|
* if not, the graph will be over-approximated wrt.
|
|
73
78
|
* containers and accesses
|
|
74
79
|
*/
|
|
75
|
-
readonly pointerTracking: boolean
|
|
80
|
+
readonly pointerTracking: boolean | {
|
|
81
|
+
/**
|
|
82
|
+
* The maximum number of indices tracked per obj with the pointer analysis (currently this focuses on initialization)
|
|
83
|
+
*/
|
|
84
|
+
readonly maxIndexCount: number;
|
|
85
|
+
};
|
|
76
86
|
/**
|
|
77
87
|
* If lax source calls are active, flowR searches for sourced files much more freely,
|
|
78
88
|
* based on the configurations you give it.
|
|
@@ -96,6 +106,11 @@ export interface FlowrConfigOptions extends MergeableRecord {
|
|
|
96
106
|
* if it is relative.
|
|
97
107
|
*/
|
|
98
108
|
readonly dropPaths: DropPathsOption;
|
|
109
|
+
/**
|
|
110
|
+
* How often the same file can be sourced within a single run?
|
|
111
|
+
* Please be aware: in case of cyclic sources this may not reach a fixpoint so give this a sensible limit.
|
|
112
|
+
*/
|
|
113
|
+
readonly repeatedSourceLimit?: number;
|
|
99
114
|
};
|
|
100
115
|
/**
|
|
101
116
|
* The configuration for flowR's slicer
|
|
@@ -139,8 +154,9 @@ export declare const flowrConfigFileSchema: Joi.ObjectSchema<any>;
|
|
|
139
154
|
export declare function setConfigFile(file: string | undefined, workingDirectory?: string, forceLoad?: boolean): void;
|
|
140
155
|
export declare function parseConfig(jsonString: string): FlowrConfigOptions | undefined;
|
|
141
156
|
export declare function setConfig(config: FlowrConfigOptions): void;
|
|
142
|
-
export declare function amendConfig(amendment:
|
|
157
|
+
export declare function amendConfig(amendment: DeepPartial<FlowrConfigOptions>): void;
|
|
143
158
|
export declare function getConfig(): FlowrConfigOptions;
|
|
144
159
|
export declare function getEngineConfig<T extends EngineConfig['type']>(engine: T): EngineConfig & {
|
|
145
160
|
type: T;
|
|
146
161
|
} | undefined;
|
|
162
|
+
export declare function isOverPointerAnalysisThreshold(count: number): boolean;
|
package/config.js
CHANGED
|
@@ -10,6 +10,7 @@ exports.setConfig = setConfig;
|
|
|
10
10
|
exports.amendConfig = amendConfig;
|
|
11
11
|
exports.getConfig = getConfig;
|
|
12
12
|
exports.getEngineConfig = getEngineConfig;
|
|
13
|
+
exports.isOverPointerAnalysisThreshold = isOverPointerAnalysisThreshold;
|
|
13
14
|
const objects_1 = require("./util/objects");
|
|
14
15
|
const path_1 = __importDefault(require("path"));
|
|
15
16
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -70,12 +71,14 @@ exports.defaultConfigOptions = {
|
|
|
70
71
|
defaultEngine: 'r-shell',
|
|
71
72
|
solver: {
|
|
72
73
|
variables: VariableResolve.Alias,
|
|
73
|
-
|
|
74
|
+
evalStrings: true,
|
|
75
|
+
pointerTracking: true,
|
|
74
76
|
resolveSource: {
|
|
75
77
|
dropPaths: DropPathsOption.No,
|
|
76
78
|
ignoreCapitalization: true,
|
|
77
79
|
inferWorkingDirectory: InferWorkingDirectory.ActiveScript,
|
|
78
|
-
searchPath: []
|
|
80
|
+
searchPath: [],
|
|
81
|
+
repeatedSourceLimit: 2
|
|
79
82
|
},
|
|
80
83
|
slicer: {
|
|
81
84
|
threshold: 50
|
|
@@ -104,12 +107,16 @@ exports.flowrConfigFileSchema = joi_1.default.object({
|
|
|
104
107
|
defaultEngine: joi_1.default.string().optional().valid('tree-sitter', 'r-shell').description('The default engine to use for interacting with R code. If this is undefined, an arbitrary engine from the specified list will be used.'),
|
|
105
108
|
solver: joi_1.default.object({
|
|
106
109
|
variables: joi_1.default.string().valid(...Object.values(VariableResolve)).description('How to resolve variables and their values.'),
|
|
107
|
-
|
|
110
|
+
evalStrings: joi_1.default.boolean().description('Should we include eval(parse(text="...")) calls in the dataflow graph?'),
|
|
111
|
+
pointerTracking: joi_1.default.alternatives(joi_1.default.boolean(), joi_1.default.object({
|
|
112
|
+
maxIndexCount: joi_1.default.number().required().description('The maximum number of indices tracked per object with the pointer analysis.')
|
|
113
|
+
})).description('Whether to track pointers in the dataflow graph, if not, the graph will be over-approximated wrt. containers and accesses.'),
|
|
108
114
|
resolveSource: joi_1.default.object({
|
|
109
115
|
dropPaths: joi_1.default.string().valid(...Object.values(DropPathsOption)).description('Allow to drop the first or all parts of the sourced path, if it is relative.'),
|
|
110
116
|
ignoreCapitalization: joi_1.default.boolean().description('Search for filenames matching in the lowercase.'),
|
|
111
117
|
inferWorkingDirectory: joi_1.default.string().valid(...Object.values(InferWorkingDirectory)).description('Try to infer the working directory from the main or any script to analyze.'),
|
|
112
|
-
searchPath: joi_1.default.array().items(joi_1.default.string()).description('Additionally search in these paths.')
|
|
118
|
+
searchPath: joi_1.default.array().items(joi_1.default.string()).description('Additionally search in these paths.'),
|
|
119
|
+
repeatedSourceLimit: joi_1.default.number().optional().description('How often the same file can be sourced within a single run? Please be aware: in case of cyclic sources this may not reach a fixpoint so give this a sensible limit.')
|
|
113
120
|
}).optional().description('If lax source calls are active, flowR searches for sourced files much more freely, based on the configurations you give it. This option is only in effect if `ignoreSourceCalls` is set to false.'),
|
|
114
121
|
slicer: joi_1.default.object({
|
|
115
122
|
threshold: joi_1.default.number().optional().description('The maximum number of iterations to perform on a single function call during slicing.')
|
|
@@ -175,6 +182,19 @@ function getEngineConfig(engine) {
|
|
|
175
182
|
return config.find(e => e.type == engine);
|
|
176
183
|
}
|
|
177
184
|
}
|
|
185
|
+
function getPointerAnalysisThreshold() {
|
|
186
|
+
const config = getConfig().solver.pointerTracking;
|
|
187
|
+
if (typeof config === 'object') {
|
|
188
|
+
return config.maxIndexCount;
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
return config ? 'unlimited' : 'disabled';
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function isOverPointerAnalysisThreshold(count) {
|
|
195
|
+
const threshold = getPointerAnalysisThreshold();
|
|
196
|
+
return threshold !== 'unlimited' && (threshold === 'disabled' || count > threshold);
|
|
197
|
+
}
|
|
178
198
|
function loadConfigFromFile(configFile, workingDirectory) {
|
|
179
199
|
if (configFile !== undefined) {
|
|
180
200
|
if (path_1.default.isAbsolute(configFile) && fs_1.default.existsSync(configFile)) {
|
|
@@ -26,7 +26,7 @@ export interface BuiltInConstantDefinition<Value> extends BaseBuiltInDefinition
|
|
|
26
26
|
export interface BuiltInFunctionDefinition<BuiltInProcessor extends BuiltInMappingName> extends BaseBuiltInDefinition {
|
|
27
27
|
readonly type: 'function';
|
|
28
28
|
readonly processor: BuiltInProcessor;
|
|
29
|
-
readonly config
|
|
29
|
+
readonly config?: ConfigOfBuiltInMappingName<BuiltInProcessor>;
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
32
|
* Define a built-in replacement (like `[` or `$`) and the processor to use.
|
|
@@ -35,6 +35,9 @@ export interface BuiltInFunctionDefinition<BuiltInProcessor extends BuiltInMappi
|
|
|
35
35
|
export interface BuiltInReplacementDefinition extends BaseBuiltInDefinition {
|
|
36
36
|
readonly type: 'replacement';
|
|
37
37
|
readonly suffixes: readonly ('<<-' | '<-')[];
|
|
38
|
+
readonly config: {
|
|
39
|
+
readIndices: boolean;
|
|
40
|
+
};
|
|
38
41
|
}
|
|
39
42
|
export type BuiltInDefinition = BuiltInConstantDefinition<any> | BuiltInFunctionDefinition<any> | BuiltInReplacementDefinition;
|
|
40
43
|
/**
|
|
@@ -42,6 +45,6 @@ export type BuiltInDefinition = BuiltInConstantDefinition<any> | BuiltInFunction
|
|
|
42
45
|
*/
|
|
43
46
|
export type BuiltInDefinitions = readonly BuiltInDefinition[];
|
|
44
47
|
export declare function registerBuiltInFunctions<BuiltInProcessor extends BuiltInMappingName>({ names, processor, config, assumePrimitive }: BuiltInFunctionDefinition<BuiltInProcessor>): void;
|
|
45
|
-
export declare function registerReplacementFunctions({ names, suffixes, assumePrimitive }: BuiltInReplacementDefinition): void;
|
|
48
|
+
export declare function registerReplacementFunctions({ names, suffixes, assumePrimitive, config }: BuiltInReplacementDefinition): void;
|
|
46
49
|
export declare function registerBuiltInDefinition(definition: BuiltInDefinition): void;
|
|
47
50
|
export declare function registerBuiltInDefinitions(definitions: BuiltInDefinitions): void;
|
|
@@ -34,6 +34,7 @@ function registerBuiltInFunctions({ names, processor, config, assumePrimitive })
|
|
|
34
34
|
controlDependencies: undefined,
|
|
35
35
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-argument */
|
|
36
36
|
processor: (name, args, rootId, data) => mappedProcessor(name, args, rootId, data, config),
|
|
37
|
+
config,
|
|
37
38
|
name,
|
|
38
39
|
nodeId: built_in_1.BuiltIn
|
|
39
40
|
}];
|
|
@@ -44,7 +45,7 @@ function registerBuiltInFunctions({ names, processor, config, assumePrimitive })
|
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
/* registers all combinations of replacements */
|
|
47
|
-
function registerReplacementFunctions({ names, suffixes, assumePrimitive }) {
|
|
48
|
+
function registerReplacementFunctions({ names, suffixes, assumePrimitive, config }) {
|
|
48
49
|
const replacer = built_in_1.BuiltInProcessorMapper['builtin:replacement'];
|
|
49
50
|
(0, assert_1.guard)(replacer !== undefined, () => 'Processor for builtin:replacement is undefined!');
|
|
50
51
|
for (const assignment of names) {
|
|
@@ -53,7 +54,12 @@ function registerReplacementFunctions({ names, suffixes, assumePrimitive }) {
|
|
|
53
54
|
const d = [{
|
|
54
55
|
type: identifier_1.ReferenceType.BuiltInFunction,
|
|
55
56
|
definedAt: built_in_1.BuiltIn,
|
|
56
|
-
processor: (name, args, rootId, data) => replacer(name, args, rootId, data, { makeMaybe: true, assignmentOperator: suffix }),
|
|
57
|
+
processor: (name, args, rootId, data) => replacer(name, args, rootId, data, { makeMaybe: true, assignmentOperator: suffix, readIndices: config.readIndices }),
|
|
58
|
+
config: {
|
|
59
|
+
...config,
|
|
60
|
+
assignmentOperator: suffix,
|
|
61
|
+
makeMaybe: true
|
|
62
|
+
},
|
|
57
63
|
name: effectiveName,
|
|
58
64
|
controlDependencies: undefined,
|
|
59
65
|
nodeId: built_in_1.BuiltIn
|
|
@@ -25,6 +25,9 @@ import type { ForceArguments } from '../internal/process/functions/call/common';
|
|
|
25
25
|
import { processApply } from '../internal/process/functions/call/built-in/built-in-apply';
|
|
26
26
|
import type { LinkTo } from '../../queries/catalog/call-context-query/call-context-query-format';
|
|
27
27
|
import { processList } from '../internal/process/functions/call/built-in/built-in-list';
|
|
28
|
+
import { processVector } from '../internal/process/functions/call/built-in/built-in-vector';
|
|
29
|
+
import { processRm } from '../internal/process/functions/call/built-in/built-in-rm';
|
|
30
|
+
import { processEvalCall } from '../internal/process/functions/call/built-in/built-in-eval';
|
|
28
31
|
export declare const BuiltIn = "built-in";
|
|
29
32
|
export type BuiltInIdentifierProcessor = <OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>) => DataflowInformation;
|
|
30
33
|
export type BuiltInIdentifierProcessorWithConfig<Config> = <OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: Config) => DataflowInformation;
|
|
@@ -32,6 +35,7 @@ export interface BuiltInIdentifierDefinition extends IdentifierReference {
|
|
|
32
35
|
type: ReferenceType.BuiltInFunction;
|
|
33
36
|
definedAt: typeof BuiltIn;
|
|
34
37
|
processor: BuiltInIdentifierProcessor;
|
|
38
|
+
config?: object;
|
|
35
39
|
}
|
|
36
40
|
export interface BuiltInIdentifierConstant<T = unknown> extends IdentifierReference {
|
|
37
41
|
type: ReferenceType.BuiltInConstant;
|
|
@@ -45,15 +49,17 @@ export interface DefaultBuiltInProcessorConfiguration extends ForceArguments {
|
|
|
45
49
|
readonly hasUnknownSideEffects?: boolean | LinkTo<RegExp | string>;
|
|
46
50
|
}
|
|
47
51
|
declare function defaultBuiltInProcessor<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: DefaultBuiltInProcessorConfiguration): DataflowInformation;
|
|
48
|
-
export declare function registerBuiltInFunctions<Config, Proc extends BuiltInIdentifierProcessorWithConfig<Config>>(both: boolean, names: readonly Identifier[], processor: Proc, config: Config): void;
|
|
52
|
+
export declare function registerBuiltInFunctions<Config extends object, Proc extends BuiltInIdentifierProcessorWithConfig<Config>>(both: boolean, names: readonly Identifier[], processor: Proc, config: Config): void;
|
|
49
53
|
export declare const BuiltInProcessorMapper: {
|
|
50
54
|
readonly 'builtin:default': typeof defaultBuiltInProcessor;
|
|
55
|
+
readonly 'builtin:eval': typeof processEvalCall;
|
|
51
56
|
readonly 'builtin:apply': typeof processApply;
|
|
52
57
|
readonly 'builtin:expression-list': typeof processExpressionList;
|
|
53
58
|
readonly 'builtin:source': typeof processSourceCall;
|
|
54
59
|
readonly 'builtin:access': typeof processAccess;
|
|
55
60
|
readonly 'builtin:if-then-else': typeof processIfThenElse;
|
|
56
61
|
readonly 'builtin:get': typeof processGet;
|
|
62
|
+
readonly 'builtin:rm': typeof processRm;
|
|
57
63
|
readonly 'builtin:library': typeof processLibrary;
|
|
58
64
|
readonly 'builtin:assignment': typeof processAssignment;
|
|
59
65
|
readonly 'builtin:special-bin-op': typeof processSpecialBinOp;
|
|
@@ -65,6 +71,7 @@ export declare const BuiltInProcessorMapper: {
|
|
|
65
71
|
readonly 'builtin:while-loop': typeof processWhileLoop;
|
|
66
72
|
readonly 'builtin:replacement': typeof processReplacementFunction;
|
|
67
73
|
readonly 'builtin:list': typeof processList;
|
|
74
|
+
readonly 'builtin:vector': typeof processVector;
|
|
68
75
|
};
|
|
69
76
|
export type BuiltInMappingName = keyof typeof BuiltInProcessorMapper;
|
|
70
77
|
export type ConfigOfBuiltInMappingName<N extends BuiltInMappingName> = Parameters<typeof BuiltInProcessorMapper[N]>[4];
|
|
@@ -25,6 +25,9 @@ const built_in_apply_1 = require("../internal/process/functions/call/built-in/bu
|
|
|
25
25
|
const built_in_config_1 = require("./built-in-config");
|
|
26
26
|
const default_builtin_config_1 = require("./default-builtin-config");
|
|
27
27
|
const built_in_list_1 = require("../internal/process/functions/call/built-in/built-in-list");
|
|
28
|
+
const built_in_vector_1 = require("../internal/process/functions/call/built-in/built-in-vector");
|
|
29
|
+
const built_in_rm_1 = require("../internal/process/functions/call/built-in/built-in-rm");
|
|
30
|
+
const built_in_eval_1 = require("../internal/process/functions/call/built-in/built-in-eval");
|
|
28
31
|
exports.BuiltIn = 'built-in';
|
|
29
32
|
function defaultBuiltInProcessor(name, args, rootId, data, config) {
|
|
30
33
|
const { information: res, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs });
|
|
@@ -62,6 +65,7 @@ function registerBuiltInFunctions(both, names, processor, config) {
|
|
|
62
65
|
definedAt: exports.BuiltIn,
|
|
63
66
|
controlDependencies: undefined,
|
|
64
67
|
processor: (name, args, rootId, data) => processor(name, args, rootId, data, config),
|
|
68
|
+
config,
|
|
65
69
|
name,
|
|
66
70
|
nodeId: exports.BuiltIn
|
|
67
71
|
}];
|
|
@@ -73,12 +77,14 @@ function registerBuiltInFunctions(both, names, processor, config) {
|
|
|
73
77
|
}
|
|
74
78
|
exports.BuiltInProcessorMapper = {
|
|
75
79
|
'builtin:default': defaultBuiltInProcessor,
|
|
80
|
+
'builtin:eval': built_in_eval_1.processEvalCall,
|
|
76
81
|
'builtin:apply': built_in_apply_1.processApply,
|
|
77
82
|
'builtin:expression-list': built_in_expression_list_1.processExpressionList,
|
|
78
83
|
'builtin:source': built_in_source_1.processSourceCall,
|
|
79
84
|
'builtin:access': built_in_access_1.processAccess,
|
|
80
85
|
'builtin:if-then-else': built_in_if_then_else_1.processIfThenElse,
|
|
81
86
|
'builtin:get': built_in_get_1.processGet,
|
|
87
|
+
'builtin:rm': built_in_rm_1.processRm,
|
|
82
88
|
'builtin:library': built_in_library_1.processLibrary,
|
|
83
89
|
'builtin:assignment': built_in_assignment_1.processAssignment,
|
|
84
90
|
'builtin:special-bin-op': built_in_special_bin_op_1.processSpecialBinOp,
|
|
@@ -89,7 +95,8 @@ exports.BuiltInProcessorMapper = {
|
|
|
89
95
|
'builtin:repeat-loop': built_in_repeat_loop_1.processRepeatLoop,
|
|
90
96
|
'builtin:while-loop': built_in_while_loop_1.processWhileLoop,
|
|
91
97
|
'builtin:replacement': built_in_replacement_1.processReplacementFunction,
|
|
92
|
-
'builtin:list': built_in_list_1.processList
|
|
98
|
+
'builtin:list': built_in_list_1.processList,
|
|
99
|
+
'builtin:vector': built_in_vector_1.processVector,
|
|
93
100
|
};
|
|
94
101
|
exports.BuiltInMemory = new Map();
|
|
95
102
|
exports.EmptyBuiltInMemory = new Map();
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import type { REnvironmentInformation } from './environment';
|
|
2
|
+
/**
|
|
3
|
+
* Produce a clone of the given environment information.
|
|
4
|
+
* @param environment - The environment information to clone.
|
|
5
|
+
* @param recurseParents - Whether to clone the parent environments as well.
|
|
6
|
+
*/
|
|
2
7
|
export declare function cloneEnvironmentInformation(environment: REnvironmentInformation, recurseParents?: boolean): REnvironmentInformation;
|
|
@@ -14,6 +14,11 @@ function cloneEnvironment(environment, recurseParents) {
|
|
|
14
14
|
clone.memory = new Map(JSON.parse(JSON.stringify([...environment.memory])));
|
|
15
15
|
return clone;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Produce a clone of the given environment information.
|
|
19
|
+
* @param environment - The environment information to clone.
|
|
20
|
+
* @param recurseParents - Whether to clone the parent environments as well.
|
|
21
|
+
*/
|
|
17
22
|
function cloneEnvironmentInformation(environment, recurseParents = true) {
|
|
18
23
|
return {
|
|
19
24
|
current: cloneEnvironment(environment.current, recurseParents),
|
|
@@ -4,6 +4,37 @@ exports.DefaultBuiltinConfig = void 0;
|
|
|
4
4
|
const identify_link_to_last_call_relation_1 = require("../../queries/catalog/call-context-query/identify-link-to-last-call-relation");
|
|
5
5
|
const type_1 = require("../../r-bridge/lang-4.x/ast/model/type");
|
|
6
6
|
const cascade_action_1 = require("../../queries/catalog/call-context-query/cascade-action");
|
|
7
|
+
const GgPlotCreate = [
|
|
8
|
+
'ggplot', 'ggplotly'
|
|
9
|
+
];
|
|
10
|
+
const TinyPlotCrate = [
|
|
11
|
+
'tinyplot', 'plt'
|
|
12
|
+
];
|
|
13
|
+
const PlotCreate = [
|
|
14
|
+
'plot', 'plot.new', 'xspline', 'map', 'curve', 'image', 'boxplot', 'dotchart', 'sunflowerplot', 'barplot', 'matplot', 'hist', 'stem',
|
|
15
|
+
'density', 'smoothScatter', 'contour', 'persp', 'XYPlot', 'xyplot', 'stripplot', 'bwplot', 'dotPlot', 'dotplot', 'histPlot', 'densityPlot', 'qPlot', 'qqPlot', 'boxPlot',
|
|
16
|
+
'bxp', 'assocplot', 'mosaicplot', 'stripchart', 'fourfoldplot', 'mosaicplot', 'plot.xy', 'plot.formula', 'plot.default', 'plot.design', 'stars',
|
|
17
|
+
'spineplot', 'Plotranges', 'regressogram', 'bootcurve', 'meanplot', 'vioplot', 'pairs', 'copolot', 'histogram', 'splom', 'leaflet', 'tm_shape', 'plot_ly',
|
|
18
|
+
...TinyPlotCrate,
|
|
19
|
+
...GgPlotCreate
|
|
20
|
+
];
|
|
21
|
+
const GraphicDeviceOpen = [
|
|
22
|
+
'pdf', 'jpeg', 'png', 'windows', 'postscript', 'xfig', 'bitmap', 'pictex', 'cairo_pdf', 'svg', 'bmp', 'tiff', 'X11', 'quartz', 'image_graph',
|
|
23
|
+
'image_draw', 'dev.new', 'trellis.device', 'raster_pdf', 'agg_pdf'
|
|
24
|
+
];
|
|
25
|
+
const TinyPlotAddons = [
|
|
26
|
+
'tinyplot_add', 'plt_add'
|
|
27
|
+
];
|
|
28
|
+
const PlotAddons = [
|
|
29
|
+
'points', 'abline', 'map', 'mtext', 'lines', 'text', 'legend', 'title', 'axis', 'polygon', 'polypath', 'pie', 'rect', 'segments', 'arrows', 'symbols',
|
|
30
|
+
'tiplabels', 'rug', 'grid', 'box', 'clip'
|
|
31
|
+
];
|
|
32
|
+
const GgPlotAddons = [
|
|
33
|
+
'ggdraw', 'last_plot'
|
|
34
|
+
];
|
|
35
|
+
function toRegex(n) {
|
|
36
|
+
return new RegExp(`^(${[...new Set(n)].map(s => s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')).filter(s => s.length > 0).join('|')})$`);
|
|
37
|
+
}
|
|
7
38
|
/**
|
|
8
39
|
* Contains the built-in definitions recognized by flowR
|
|
9
40
|
*/
|
|
@@ -20,7 +51,8 @@ exports.DefaultBuiltinConfig = [
|
|
|
20
51
|
'unique', 'paste', 'paste0', 'read.csv', 'stop', 'is.null', 'numeric', 'as.character', 'as.integer', 'as.logical', 'as.numeric', 'as.matrix',
|
|
21
52
|
'rbind', 'nrow', 'ncol', 'tryCatch', 'expression', 'factor',
|
|
22
53
|
'missing', 'as.data.frame', 'data.frame', 'na.omit', 'rownames', 'names', 'order', 'length', 'any', 'dim', 'matrix', 'cbind', 'nchar',
|
|
23
|
-
'pdf', 'jpeg', 'png', 'windows', 'postscript', 'xfig', 'bitmap', 'pictex', 'cairo_pdf', 'svg', 'bmp', 'tiff', 'X11', 'quartz'
|
|
54
|
+
'pdf', 'jpeg', 'png', 'windows', 'postscript', 'xfig', 'bitmap', 'pictex', 'cairo_pdf', 'svg', 'bmp', 'tiff', 'X11', 'quartz',
|
|
55
|
+
'jitter'
|
|
24
56
|
],
|
|
25
57
|
processor: 'builtin:default',
|
|
26
58
|
config: { readAllArguments: true },
|
|
@@ -29,12 +61,13 @@ exports.DefaultBuiltinConfig = [
|
|
|
29
61
|
{
|
|
30
62
|
type: 'function',
|
|
31
63
|
names: [
|
|
32
|
-
'
|
|
64
|
+
't', 'aperm' /* transpose function, permutation generation */
|
|
33
65
|
],
|
|
34
66
|
processor: 'builtin:default',
|
|
35
67
|
config: { readAllArguments: true },
|
|
36
68
|
assumePrimitive: false
|
|
37
69
|
},
|
|
70
|
+
{ type: 'function', names: ['rm'], processor: 'builtin:rm', config: {}, assumePrimitive: true },
|
|
38
71
|
{ type: 'function', names: ['options'], processor: 'builtin:default', config: { hasUnknownSideEffects: true, forceArgs: 'all' }, assumePrimitive: false },
|
|
39
72
|
{ type: 'function', names: ['mapply', 'Mapply'], processor: 'builtin:apply', config: { indexOfFunction: 0, nameOfFunctionArgument: 'FUN' }, assumePrimitive: false },
|
|
40
73
|
{ type: 'function', names: ['lapply', 'sapply', 'vapply'], processor: 'builtin:apply', config: { indexOfFunction: 1, nameOfFunctionArgument: 'FUN' }, assumePrimitive: false },
|
|
@@ -42,7 +75,7 @@ exports.DefaultBuiltinConfig = [
|
|
|
42
75
|
{ type: 'function', names: ['apply', 'tapply', 'Tapply'], processor: 'builtin:apply', config: { indexOfFunction: 2, nameOfFunctionArgument: 'FUN' }, assumePrimitive: false },
|
|
43
76
|
{ type: 'function', names: ['print', 'message', 'warning'], processor: 'builtin:default', config: { returnsNthArgument: 0, forceArgs: 'all', hasUnknownSideEffects: { type: 'link-to-last-call', callName: /^sink$/ } }, assumePrimitive: false },
|
|
44
77
|
// graphics base
|
|
45
|
-
{ type: 'function', names:
|
|
78
|
+
{ type: 'function', names: PlotCreate,
|
|
46
79
|
processor: 'builtin:default',
|
|
47
80
|
config: {
|
|
48
81
|
forceArgs: 'all',
|
|
@@ -55,16 +88,16 @@ exports.DefaultBuiltinConfig = [
|
|
|
55
88
|
name: 'add'
|
|
56
89
|
}, [type_1.RType.Logical])?.content === true);
|
|
57
90
|
},
|
|
58
|
-
callName:
|
|
91
|
+
callName: toRegex(GraphicDeviceOpen)
|
|
59
92
|
}
|
|
60
93
|
}, assumePrimitive: true },
|
|
61
94
|
// graphics addons
|
|
62
|
-
{ type: 'function', names:
|
|
95
|
+
{ type: 'function', names: PlotAddons,
|
|
63
96
|
processor: 'builtin:default', config: {
|
|
64
97
|
forceArgs: 'all',
|
|
65
98
|
hasUnknownSideEffects: {
|
|
66
99
|
type: 'link-to-last-call',
|
|
67
|
-
callName:
|
|
100
|
+
callName: toRegex(PlotCreate),
|
|
68
101
|
ignoreIf: (source, graph) => {
|
|
69
102
|
const sourceVertex = graph.getVertex(source);
|
|
70
103
|
/* map with add = true appends to an existing plot */
|
|
@@ -82,9 +115,47 @@ exports.DefaultBuiltinConfig = [
|
|
|
82
115
|
}
|
|
83
116
|
}
|
|
84
117
|
}, assumePrimitive: true },
|
|
118
|
+
// plot tags
|
|
119
|
+
{
|
|
120
|
+
type: 'function',
|
|
121
|
+
names: GgPlotAddons,
|
|
122
|
+
processor: 'builtin:default',
|
|
123
|
+
config: {
|
|
124
|
+
forceArgs: 'all',
|
|
125
|
+
hasUnknownSideEffects: {
|
|
126
|
+
type: 'link-to-last-call',
|
|
127
|
+
callName: toRegex(GgPlotCreate)
|
|
128
|
+
}
|
|
129
|
+
}, assumePrimitive: true
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
type: 'function',
|
|
133
|
+
names: TinyPlotAddons,
|
|
134
|
+
processor: 'builtin:default',
|
|
135
|
+
config: {
|
|
136
|
+
forceArgs: 'all',
|
|
137
|
+
hasUnknownSideEffects: {
|
|
138
|
+
type: 'link-to-last-call',
|
|
139
|
+
callName: toRegex(TinyPlotCrate)
|
|
140
|
+
}
|
|
141
|
+
}, assumePrimitive: true
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
type: 'function',
|
|
145
|
+
names: ['image_write', 'image_capture', 'dev.capture', 'dev.off'],
|
|
146
|
+
processor: 'builtin:default',
|
|
147
|
+
config: {
|
|
148
|
+
forceArgs: 'all',
|
|
149
|
+
hasUnknownSideEffects: {
|
|
150
|
+
type: 'link-to-last-call',
|
|
151
|
+
callName: toRegex([...GraphicDeviceOpen, ...PlotCreate, ...PlotAddons, ...GgPlotAddons, ...TinyPlotAddons])
|
|
152
|
+
}
|
|
153
|
+
}, assumePrimitive: true
|
|
154
|
+
},
|
|
85
155
|
{ type: 'function', names: ['('], processor: 'builtin:default', config: { returnsNthArgument: 0 }, assumePrimitive: true },
|
|
86
156
|
{ type: 'function', names: ['load', 'load_all', 'setwd', 'set.seed'], processor: 'builtin:default', config: { hasUnknownSideEffects: true, forceArgs: [true] }, assumePrimitive: false },
|
|
87
|
-
{ type: 'function', names: ['
|
|
157
|
+
{ type: 'function', names: ['body', 'formals', 'environment'], processor: 'builtin:default', config: { hasUnknownSideEffects: true, forceArgs: [true] }, assumePrimitive: true },
|
|
158
|
+
{ type: 'function', names: ['eval'], processor: 'builtin:eval', config: { includeFunctionCall: true }, assumePrimitive: true },
|
|
88
159
|
{ type: 'function', names: ['cat'], processor: 'builtin:default', config: { forceArgs: 'all', hasUnknownSideEffects: { type: 'link-to-last-call', callName: /^sink$/ } }, assumePrimitive: false },
|
|
89
160
|
{ type: 'function', names: ['switch'], processor: 'builtin:default', config: { forceArgs: [true] }, assumePrimitive: false },
|
|
90
161
|
{ type: 'function', names: ['return'], processor: 'builtin:default', config: { returnsNthArgument: 0, cfg: 1 /* ExitPointType.Return */ }, assumePrimitive: false },
|
|
@@ -113,7 +184,9 @@ exports.DefaultBuiltinConfig = [
|
|
|
113
184
|
{ type: 'function', names: ['repeat'], processor: 'builtin:repeat-loop', config: {}, assumePrimitive: true },
|
|
114
185
|
{ type: 'function', names: ['while'], processor: 'builtin:while-loop', config: {}, assumePrimitive: true },
|
|
115
186
|
{ type: 'function', names: ['do.call'], processor: 'builtin:apply', config: { indexOfFunction: 0, unquoteFunction: true }, assumePrimitive: true },
|
|
187
|
+
{ type: 'function', names: ['.Primitive', '.Internal'], processor: 'builtin:apply', config: { indexOfFunction: 0, unquoteFunction: true, resolveInEnvironment: 'global' }, assumePrimitive: true },
|
|
116
188
|
{ type: 'function', names: ['list'], processor: 'builtin:list', config: {}, assumePrimitive: true },
|
|
189
|
+
{ type: 'function', names: ['c'], processor: 'builtin:vector', config: {}, assumePrimitive: true },
|
|
117
190
|
{
|
|
118
191
|
type: 'function',
|
|
119
192
|
names: ['setnames', 'setNames', 'setkey', 'setkeyv', 'setindex', 'setindexv', 'setattr'],
|
|
@@ -128,7 +201,7 @@ exports.DefaultBuiltinConfig = [
|
|
|
128
201
|
{
|
|
129
202
|
type: 'function',
|
|
130
203
|
names: [
|
|
131
|
-
'on.exit', 'sys.on.exit', 'par', 'sink',
|
|
204
|
+
'on.exit', 'sys.on.exit', 'par', 'tpar', 'sink', 'tinytheme',
|
|
132
205
|
/* library and require is handled above */
|
|
133
206
|
'requireNamespace', 'loadNamespace', 'attachNamespace', 'asNamespace',
|
|
134
207
|
/* downloader and installer functions (R, devtools, BiocManager) */
|
|
@@ -146,7 +219,18 @@ exports.DefaultBuiltinConfig = [
|
|
|
146
219
|
{
|
|
147
220
|
type: 'replacement',
|
|
148
221
|
suffixes: ['<-', '<<-'],
|
|
149
|
-
names: ['[', '[[', '
|
|
222
|
+
names: ['[', '[[', 'names', 'dimnames', 'attributes', 'attr', 'class', 'levels', 'rownames', 'colnames', 'body', 'environment', 'formals'],
|
|
223
|
+
config: {
|
|
224
|
+
readIndices: true
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
type: 'replacement',
|
|
229
|
+
suffixes: ['<-', '<<-'],
|
|
230
|
+
names: ['$', '@'],
|
|
231
|
+
config: {
|
|
232
|
+
readIndices: false
|
|
233
|
+
}
|
|
150
234
|
}
|
|
151
235
|
];
|
|
152
236
|
//# sourceMappingURL=default-builtin-config.js.map
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { REnvironmentInformation } from './environment';
|
|
2
|
-
import type { IdentifierDefinition } from './identifier';
|
|
2
|
+
import type { IdentifierDefinition, InGraphIdentifierDefinition } from './identifier';
|
|
3
|
+
/**
|
|
4
|
+
* assumes: existing is not undefined, the overwrite has indices
|
|
5
|
+
*/
|
|
6
|
+
export declare function mergeDefinitions(existing: readonly IdentifierDefinition[], definition: InGraphIdentifierDefinition): InGraphIdentifierDefinition[];
|
|
3
7
|
/**
|
|
4
8
|
* Insert the given `definition` --- defined within the given scope --- into the passed along `environments` will take care of propagation.
|
|
5
9
|
* Does not modify the passed along `environments` in-place! It returns the new reference.
|
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mergeDefinitions = mergeDefinitions;
|
|
3
4
|
exports.define = define;
|
|
4
5
|
const assert_1 = require("../../util/assert");
|
|
5
6
|
const environment_1 = require("./environment");
|
|
6
7
|
const clone_1 = require("./clone");
|
|
7
8
|
const vertex_1 = require("../graph/vertex");
|
|
9
|
+
const config_1 = require("../../config");
|
|
8
10
|
function defInEnv(newEnvironments, name, definition) {
|
|
9
11
|
const existing = newEnvironments.memory.get(name);
|
|
10
12
|
// When there are defined indices, merge the definitions
|
|
11
13
|
const inGraphDefinition = definition;
|
|
12
|
-
if (
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
if ((0, config_1.getConfig)().solver.pointerTracking &&
|
|
15
|
+
existing !== undefined &&
|
|
16
|
+
inGraphDefinition.controlDependencies === undefined) {
|
|
17
|
+
if (inGraphDefinition.indicesCollection !== undefined) {
|
|
18
|
+
newEnvironments.memory.set(name, mergeDefinitions(existing, inGraphDefinition));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
else if (existing?.flatMap(i => i.indicesCollection ?? []).length > 0) {
|
|
22
|
+
// When indices couldn't be resolved, but indices where defined before, just add the definition
|
|
23
|
+
existing.push(definition);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
15
26
|
}
|
|
16
27
|
// check if it is maybe or not
|
|
17
28
|
if (existing === undefined || definition.controlDependencies === undefined) {
|
|
@@ -21,28 +32,43 @@ function defInEnv(newEnvironments, name, definition) {
|
|
|
21
32
|
existing.push(definition);
|
|
22
33
|
}
|
|
23
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* assumes: existing is not undefined, the overwrite has indices
|
|
37
|
+
*/
|
|
24
38
|
function mergeDefinitions(existing, definition) {
|
|
25
39
|
// When new definition is not a single index, e.g., a list redefinition, then reset existing definition
|
|
26
40
|
if (definition.indicesCollection?.some(indices => indices.isContainer)) {
|
|
27
41
|
return [definition];
|
|
28
42
|
}
|
|
29
|
-
const existingDefs = existing.
|
|
43
|
+
const existingDefs = existing.filter(assert_1.isNotUndefined);
|
|
30
44
|
const overwriteIndices = definition.indicesCollection?.flatMap(indices => indices.indices) ?? [];
|
|
31
45
|
// Compare existing and new definitions,
|
|
32
46
|
// add new definitions and remove existing definitions that are overwritten by new definition
|
|
33
47
|
const newExistingDefs = [];
|
|
48
|
+
const hasCache = new Set();
|
|
34
49
|
for (const overwriteIndex of overwriteIndices) {
|
|
35
50
|
for (const existingDef of existingDefs) {
|
|
36
|
-
|
|
51
|
+
// empty or missing
|
|
52
|
+
if (existingDef.indicesCollection === undefined || existingDef.indicesCollection.length === 0) {
|
|
53
|
+
const existingDefPrint = JSON.stringify(existingDef);
|
|
54
|
+
if (!hasCache.has(existingDefPrint)) {
|
|
55
|
+
newExistingDefs.push(existingDef);
|
|
56
|
+
hasCache.add(existingDefPrint);
|
|
57
|
+
}
|
|
37
58
|
continue;
|
|
38
59
|
}
|
|
39
60
|
const newIndicesCollection = overwriteContainerIndices(existingDef.indicesCollection, overwriteIndex);
|
|
40
61
|
// if indices are now empty list, don't keep empty definition
|
|
41
62
|
if (newIndicesCollection.length > 0) {
|
|
42
|
-
|
|
63
|
+
const obj = {
|
|
43
64
|
...existingDef,
|
|
44
65
|
indicesCollection: newIndicesCollection,
|
|
45
|
-
}
|
|
66
|
+
};
|
|
67
|
+
const objHash = JSON.stringify(obj);
|
|
68
|
+
if (!hasCache.has(objHash)) {
|
|
69
|
+
newExistingDefs.push(obj);
|
|
70
|
+
hasCache.add(objHash);
|
|
71
|
+
}
|
|
46
72
|
}
|
|
47
73
|
}
|
|
48
74
|
}
|
|
@@ -57,7 +83,7 @@ function overwriteContainerIndices(existingIndices, overwriteIndex) {
|
|
|
57
83
|
if ((0, vertex_1.isParentContainerIndex)(overwriteIndex)) {
|
|
58
84
|
newIndices = [];
|
|
59
85
|
for (const index of indices.indices) {
|
|
60
|
-
if (index
|
|
86
|
+
if ((0, vertex_1.isSameIndex)(index, overwriteIndex) && (0, vertex_1.isParentContainerIndex)(index)) {
|
|
61
87
|
const overwriteSubIndices = overwriteIndex.subIndices.flatMap(a => a.indices);
|
|
62
88
|
let newSubIndices = index.subIndices;
|
|
63
89
|
for (const overwriteSubIndex of overwriteSubIndices) {
|
|
@@ -70,7 +96,7 @@ function overwriteContainerIndices(existingIndices, overwriteIndex) {
|
|
|
70
96
|
});
|
|
71
97
|
}
|
|
72
98
|
}
|
|
73
|
-
if (index
|
|
99
|
+
if (!(0, vertex_1.isSameIndex)(index, overwriteIndex) || !(0, vertex_1.isParentContainerIndex)(index)) {
|
|
74
100
|
newIndices.push(index);
|
|
75
101
|
}
|
|
76
102
|
}
|
|
@@ -81,7 +107,7 @@ function overwriteContainerIndices(existingIndices, overwriteIndex) {
|
|
|
81
107
|
}
|
|
82
108
|
else {
|
|
83
109
|
// Filter existing indices with the same name
|
|
84
|
-
newIndices = indices.indices.filter(def => def
|
|
110
|
+
newIndices = indices.indices.filter(def => !(0, vertex_1.isSameIndex)(def, overwriteIndex));
|
|
85
111
|
}
|
|
86
112
|
if (indices.isContainer || newIndices.length > 0) {
|
|
87
113
|
newIndicesCollection.push({
|