@eagleoutice/flowr 2.3.0 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -30
- package/abstract-interpretation/data-frame/absint-visitor.d.ts +2 -3
- package/abstract-interpretation/data-frame/absint-visitor.js +14 -16
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +3 -3
- package/abstract-interpretation/data-frame/semantics.d.ts +1 -1
- package/abstract-interpretation/data-frame/semantics.js +7 -10
- package/abstract-interpretation/data-frame/shape-inference.js +2 -8
- package/benchmark/slicer.js +7 -5
- package/benchmark/stats/size-of.js +3 -3
- package/benchmark/summarizer/second-phase/graph.js +1 -1
- package/benchmark/summarizer/second-phase/process.js +1 -1
- package/cli/benchmark-app.d.ts +1 -0
- package/cli/benchmark-app.js +1 -0
- package/cli/benchmark-helper-app.d.ts +1 -0
- package/cli/benchmark-helper-app.js +4 -3
- package/cli/common/options.js +2 -0
- package/cli/repl/commands/repl-query.js +1 -1
- package/cli/repl/server/connection.js +14 -5
- package/control-flow/basic-cfg-guided-visitor.d.ts +1 -2
- package/control-flow/basic-cfg-guided-visitor.js +0 -6
- package/control-flow/cfg-simplification.d.ts +6 -0
- package/control-flow/cfg-simplification.js +18 -9
- package/control-flow/control-flow-graph.d.ts +2 -8
- package/control-flow/control-flow-graph.js +1 -6
- package/control-flow/extract-cfg.d.ts +2 -2
- package/control-flow/extract-cfg.js +52 -63
- package/core/pipeline-executor.js +0 -8
- package/core/steps/all/static-slicing/00-slice.d.ts +7 -1
- package/core/steps/all/static-slicing/00-slice.js +9 -3
- package/core/steps/pipeline/default-pipelines.d.ts +74 -74
- package/dataflow/environments/append.js +1 -1
- package/dataflow/environments/built-in-config.d.ts +12 -4
- package/dataflow/environments/built-in-config.js +23 -82
- package/dataflow/environments/built-in.d.ts +40 -6
- package/dataflow/environments/built-in.js +119 -23
- package/dataflow/environments/clone.d.ts +3 -2
- package/dataflow/environments/clone.js +6 -5
- package/dataflow/environments/define.js +1 -2
- package/dataflow/environments/diff.js +1 -3
- package/dataflow/environments/environment.d.ts +18 -24
- package/dataflow/environments/environment.js +25 -37
- package/dataflow/environments/overwrite.d.ts +1 -1
- package/dataflow/environments/overwrite.js +1 -1
- package/dataflow/environments/remove.d.ts +2 -2
- package/dataflow/environments/remove.js +3 -4
- package/dataflow/environments/resolve-by-name.d.ts +3 -3
- package/dataflow/environments/resolve-by-name.js +4 -5
- package/dataflow/eval/resolve/alias-tracking.d.ts +12 -12
- package/dataflow/eval/resolve/alias-tracking.js +12 -12
- package/dataflow/eval/resolve/resolve.js +1 -1
- package/dataflow/extractor.js +6 -1
- package/dataflow/graph/dataflowgraph-builder.d.ts +3 -1
- package/dataflow/graph/dataflowgraph-builder.js +2 -2
- package/dataflow/graph/graph.d.ts +2 -1
- package/dataflow/graph/graph.js +6 -2
- package/dataflow/graph/invert-dfg.d.ts +2 -0
- package/dataflow/graph/invert-dfg.js +17 -0
- package/dataflow/info.d.ts +1 -1
- package/dataflow/internal/linker.js +9 -9
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +9 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +1 -1
- package/dataflow/processor.d.ts +5 -1
- package/documentation/doc-util/doc-env.js +1 -2
- package/documentation/doc-util/doc-query.js +1 -1
- package/documentation/doc-util/doc-search.js +2 -2
- package/documentation/print-cfg-wiki.js +3 -4
- package/documentation/print-core-wiki.js +2 -2
- package/documentation/print-dataflow-graph-wiki.js +7 -0
- package/documentation/print-faq-wiki.js +4 -0
- package/documentation/print-linter-wiki.js +32 -4
- package/documentation/print-linting-and-testing-wiki.js +13 -1
- package/documentation/print-onboarding-wiki.js +4 -0
- package/documentation/print-query-wiki.js +12 -3
- package/linter/linter-executor.js +1 -2
- package/linter/linter-format.d.ts +26 -4
- package/linter/linter-format.js +25 -6
- package/linter/linter-rules.d.ts +40 -12
- package/linter/linter-rules.js +3 -1
- package/linter/rules/absolute-path.d.ts +4 -7
- package/linter/rules/absolute-path.js +9 -6
- package/linter/rules/dataframe-access-validation.d.ts +3 -1
- package/linter/rules/dataframe-access-validation.js +3 -1
- package/linter/rules/dead-code.d.ts +43 -0
- package/linter/rules/dead-code.js +50 -0
- package/linter/rules/deprecated-functions.d.ts +3 -2
- package/linter/rules/deprecated-functions.js +3 -1
- package/linter/rules/file-path-validity.d.ts +4 -4
- package/linter/rules/file-path-validity.js +8 -6
- package/linter/rules/naming-convention.d.ts +4 -3
- package/linter/rules/naming-convention.js +3 -1
- package/linter/rules/seeded-randomness.d.ts +4 -3
- package/linter/rules/seeded-randomness.js +3 -1
- package/linter/rules/unused-definition.d.ts +2 -0
- package/linter/rules/unused-definition.js +3 -1
- package/package.json +1 -1
- package/queries/base-query-format.d.ts +2 -0
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +7 -7
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +24 -1
- package/queries/catalog/dependencies-query/function-info/function-info.d.ts +9 -5
- package/queries/catalog/dependencies-query/function-info/read-functions.js +5 -2
- package/queries/catalog/dependencies-query/function-info/write-functions.js +6 -0
- package/queries/catalog/linter-query/linter-query-format.js +1 -1
- package/queries/catalog/location-map-query/location-map-query-executor.js +7 -5
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +3 -0
- package/queries/catalog/location-map-query/location-map-query-format.js +1 -0
- package/queries/catalog/search-query/search-query-executor.js +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +3 -2
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +3 -0
- package/queries/catalog/static-slice-query/static-slice-query-format.js +3 -1
- package/queries/query-print.d.ts +1 -1
- package/queries/query-print.js +0 -1
- package/queries/query.d.ts +16 -5
- package/queries/query.js +24 -11
- package/search/flowr-search-builder.d.ts +6 -6
- package/search/flowr-search-executor.d.ts +2 -2
- package/search/flowr-search-executor.js +1 -1
- package/search/flowr-search.d.ts +13 -8
- package/search/flowr-search.js +21 -0
- package/search/search-executor/search-enrichers.d.ts +87 -20
- package/search/search-executor/search-enrichers.js +44 -5
- package/search/search-executor/search-generators.d.ts +4 -4
- package/search/search-executor/search-generators.js +12 -7
- package/search/search-executor/search-mappers.js +3 -2
- package/search/search-executor/search-transformer.d.ts +3 -3
- package/search/search-executor/search-transformer.js +2 -2
- package/slicing/static/fingerprint.js +1 -2
- package/slicing/static/slice-call.d.ts +2 -1
- package/slicing/static/slice-call.js +3 -3
- package/slicing/static/static-slicer.d.ts +6 -5
- package/slicing/static/static-slicer.js +13 -7
- package/util/collections/arrays.d.ts +2 -0
- package/util/collections/arrays.js +9 -0
- package/util/containers.d.ts +1 -0
- package/util/containers.js +1 -0
- package/util/json.js +1 -4
- package/util/mermaid/dfg.js +5 -4
- package/util/prefix.d.ts +1 -1
- package/util/range.d.ts +1 -0
- package/util/range.js +5 -1
- package/util/version.js +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.BuiltIns = exports.BuiltInEvalHandlerMapper = exports.BuiltInProcessorMapper = void 0;
|
|
4
4
|
exports.builtInId = builtInId;
|
|
5
5
|
exports.isBuiltIn = isBuiltIn;
|
|
6
6
|
exports.registerBuiltInFunctions = registerBuiltInFunctions;
|
|
@@ -25,8 +25,6 @@ const edge_1 = require("../graph/edge");
|
|
|
25
25
|
const built_in_library_1 = require("../internal/process/functions/call/built-in/built-in-library");
|
|
26
26
|
const built_in_source_1 = require("../internal/process/functions/call/built-in/built-in-source");
|
|
27
27
|
const built_in_apply_1 = require("../internal/process/functions/call/built-in/built-in-apply");
|
|
28
|
-
const built_in_config_1 = require("./built-in-config");
|
|
29
|
-
const default_builtin_config_1 = require("./default-builtin-config");
|
|
30
28
|
const built_in_list_1 = require("../internal/process/functions/call/built-in/built-in-list");
|
|
31
29
|
const built_in_vector_1 = require("../internal/process/functions/call/built-in/built-in-vector");
|
|
32
30
|
const built_in_rm_1 = require("../internal/process/functions/call/built-in/built-in-rm");
|
|
@@ -41,30 +39,31 @@ function builtInId(name) {
|
|
|
41
39
|
function isBuiltIn(name) {
|
|
42
40
|
return String(name).startsWith('built-in:');
|
|
43
41
|
}
|
|
44
|
-
function defaultBuiltInProcessor(name, args, rootId, data,
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
function defaultBuiltInProcessor(name, args, rootId, data, { returnsNthArgument, useAsProcessor, forceArgs, readAllArguments, cfg, hasUnknownSideEffects, treatAsFnCall }) {
|
|
43
|
+
const activeProcessor = useAsProcessor ?? 'builtin:default';
|
|
44
|
+
const { information: res, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs, origin: activeProcessor });
|
|
45
|
+
if (returnsNthArgument !== undefined) {
|
|
46
|
+
const arg = returnsNthArgument === 'last' ? processedArguments[args.length - 1] : processedArguments[returnsNthArgument];
|
|
48
47
|
if (arg !== undefined) {
|
|
49
48
|
res.graph.addEdge(rootId, arg.entryPoint, edge_1.EdgeType.Returns);
|
|
50
49
|
}
|
|
51
50
|
}
|
|
52
|
-
if (
|
|
51
|
+
if (readAllArguments) {
|
|
53
52
|
for (const arg of processedArguments) {
|
|
54
53
|
if (arg) {
|
|
55
54
|
res.graph.addEdge(rootId, arg.entryPoint, edge_1.EdgeType.Reads);
|
|
56
55
|
}
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
|
-
if (
|
|
60
|
-
if (typeof
|
|
61
|
-
(0, unknown_side_effect_1.handleUnknownSideEffect)(res.graph, res.environment, rootId,
|
|
58
|
+
if (hasUnknownSideEffects) {
|
|
59
|
+
if (typeof hasUnknownSideEffects !== 'boolean') {
|
|
60
|
+
(0, unknown_side_effect_1.handleUnknownSideEffect)(res.graph, res.environment, rootId, hasUnknownSideEffects);
|
|
62
61
|
}
|
|
63
62
|
else {
|
|
64
63
|
(0, unknown_side_effect_1.handleUnknownSideEffect)(res.graph, res.environment, rootId);
|
|
65
64
|
}
|
|
66
65
|
}
|
|
67
|
-
const fnCallNames =
|
|
66
|
+
const fnCallNames = treatAsFnCall?.[name.content];
|
|
68
67
|
if (fnCallNames) {
|
|
69
68
|
for (const arg of args) {
|
|
70
69
|
if (arg !== r_function_call_1.EmptyArgument && arg.value && fnCallNames.includes(arg.name?.content)) {
|
|
@@ -90,17 +89,17 @@ function defaultBuiltInProcessor(name, args, rootId, data, config) {
|
|
|
90
89
|
environment: data.environment,
|
|
91
90
|
onlyBuiltin: false,
|
|
92
91
|
cds: data.controlDependencies,
|
|
93
|
-
origin: [
|
|
92
|
+
origin: [activeProcessor]
|
|
94
93
|
});
|
|
95
94
|
}
|
|
96
95
|
}
|
|
97
96
|
}
|
|
98
|
-
if (
|
|
99
|
-
res.exitPoints
|
|
97
|
+
if (cfg !== undefined) {
|
|
98
|
+
res.exitPoints.push({ type: cfg, nodeId: rootId, controlDependencies: data.controlDependencies });
|
|
100
99
|
}
|
|
101
100
|
return res;
|
|
102
101
|
}
|
|
103
|
-
function registerBuiltInFunctions(both, names, processor, config) {
|
|
102
|
+
function registerBuiltInFunctions(both, names, processor, config, builtIns) {
|
|
104
103
|
for (const name of names) {
|
|
105
104
|
(0, assert_1.guard)(processor !== undefined, `Processor for ${name} is undefined, maybe you have an import loop? You may run 'npm run detect-circular-deps' - although by far not all are bad`);
|
|
106
105
|
const id = builtInId(name);
|
|
@@ -113,10 +112,7 @@ function registerBuiltInFunctions(both, names, processor, config) {
|
|
|
113
112
|
name,
|
|
114
113
|
nodeId: id
|
|
115
114
|
}];
|
|
116
|
-
|
|
117
|
-
if (both) {
|
|
118
|
-
exports.EmptyBuiltInMemory.set(name, d);
|
|
119
|
-
}
|
|
115
|
+
builtIns.set(name, d, both);
|
|
120
116
|
}
|
|
121
117
|
}
|
|
122
118
|
exports.BuiltInProcessorMapper = {
|
|
@@ -148,7 +144,107 @@ exports.BuiltInEvalHandlerMapper = {
|
|
|
148
144
|
'built-in:+': resolve_1.resolveAsPlus,
|
|
149
145
|
'built-in:-': resolve_1.resolveAsMinus
|
|
150
146
|
};
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
(
|
|
147
|
+
class BuiltIns {
|
|
148
|
+
/**
|
|
149
|
+
* Register a built-in constant (like `NULL` or `TRUE`) to the given {@link builtIns}
|
|
150
|
+
*/
|
|
151
|
+
registerBuiltInConstant({ names, value, assumePrimitive }) {
|
|
152
|
+
for (const name of names) {
|
|
153
|
+
const id = builtInId(name);
|
|
154
|
+
const d = [{
|
|
155
|
+
type: identifier_1.ReferenceType.BuiltInConstant,
|
|
156
|
+
definedAt: id,
|
|
157
|
+
controlDependencies: undefined,
|
|
158
|
+
value,
|
|
159
|
+
name,
|
|
160
|
+
nodeId: id
|
|
161
|
+
}];
|
|
162
|
+
this.set(name, d, assumePrimitive);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Register a built-in function (like `print` or `c`) to the given {@link builtIns}
|
|
167
|
+
*/
|
|
168
|
+
registerBuiltInFunctions({ names, processor, config, assumePrimitive }) {
|
|
169
|
+
const mappedProcessor = exports.BuiltInProcessorMapper[processor];
|
|
170
|
+
(0, assert_1.guard)(mappedProcessor !== undefined, () => `Processor for ${processor} is undefined! Please pass a valid builtin name ${JSON.stringify(Object.keys(exports.BuiltInProcessorMapper))}!`);
|
|
171
|
+
for (const name of names) {
|
|
172
|
+
(0, assert_1.guard)(processor !== undefined, `Processor for ${name} is undefined, maybe you have an import loop? You may run 'npm run detect-circular-deps' - although by far not all are bad`);
|
|
173
|
+
const id = builtInId(name);
|
|
174
|
+
const d = [{
|
|
175
|
+
type: identifier_1.ReferenceType.BuiltInFunction,
|
|
176
|
+
definedAt: id,
|
|
177
|
+
controlDependencies: undefined,
|
|
178
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-argument */
|
|
179
|
+
processor: (name, args, rootId, data) => mappedProcessor(name, args, rootId, data, config),
|
|
180
|
+
config,
|
|
181
|
+
name,
|
|
182
|
+
nodeId: id
|
|
183
|
+
}];
|
|
184
|
+
this.set(name, d, assumePrimitive);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Registers all combinations of replacements
|
|
189
|
+
*/
|
|
190
|
+
registerReplacementFunctions({ names, suffixes, assumePrimitive, config }) {
|
|
191
|
+
const replacer = exports.BuiltInProcessorMapper['builtin:replacement'];
|
|
192
|
+
(0, assert_1.guard)(replacer !== undefined, () => 'Processor for builtin:replacement is undefined!');
|
|
193
|
+
for (const assignment of names) {
|
|
194
|
+
for (const suffix of suffixes) {
|
|
195
|
+
const effectiveName = `${assignment}${suffix}`;
|
|
196
|
+
const id = builtInId(effectiveName);
|
|
197
|
+
const d = [{
|
|
198
|
+
type: identifier_1.ReferenceType.BuiltInFunction,
|
|
199
|
+
definedAt: id,
|
|
200
|
+
processor: (name, args, rootId, data) => replacer(name, args, rootId, data, { makeMaybe: true, assignmentOperator: suffix, readIndices: config.readIndices }),
|
|
201
|
+
config: {
|
|
202
|
+
...config,
|
|
203
|
+
assignmentOperator: suffix,
|
|
204
|
+
makeMaybe: true
|
|
205
|
+
},
|
|
206
|
+
name: effectiveName,
|
|
207
|
+
controlDependencies: undefined,
|
|
208
|
+
nodeId: id
|
|
209
|
+
}];
|
|
210
|
+
this.set(effectiveName, d, assumePrimitive);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Register a single {@link BuiltInDefinition} to the given memories in {@link builtIns}
|
|
216
|
+
*/
|
|
217
|
+
registerBuiltInDefinition(definition) {
|
|
218
|
+
switch (definition.type) {
|
|
219
|
+
case 'constant':
|
|
220
|
+
return this.registerBuiltInConstant(definition);
|
|
221
|
+
case 'function':
|
|
222
|
+
return this.registerBuiltInFunctions(definition);
|
|
223
|
+
case 'replacement':
|
|
224
|
+
return this.registerReplacementFunctions(definition);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* The built-in {@link REnvironmentInformation|environment} is the root of all environments.
|
|
229
|
+
*
|
|
230
|
+
* For its default content (when not overwritten by a flowR config),
|
|
231
|
+
* see the {@link DefaultBuiltinConfig}.
|
|
232
|
+
*/
|
|
233
|
+
builtInMemory = new Map();
|
|
234
|
+
/**
|
|
235
|
+
* The twin of the {@link builtInMemory} but with less built ins defined for
|
|
236
|
+
* cases in which we want some commonly overwritten variables to remain open.
|
|
237
|
+
* If you do not know if you need the empty environment, you do not need the empty environment (right now).
|
|
238
|
+
*
|
|
239
|
+
* @see {@link builtInMemory}
|
|
240
|
+
*/
|
|
241
|
+
emptyBuiltInMemory = new Map();
|
|
242
|
+
set(identifier, definition, includeInEmptyMemory) {
|
|
243
|
+
this.builtInMemory.set(identifier, definition);
|
|
244
|
+
if (includeInEmptyMemory) {
|
|
245
|
+
this.emptyBuiltInMemory.set(identifier, definition);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
exports.BuiltIns = BuiltIns;
|
|
154
250
|
//# sourceMappingURL=built-in.js.map
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { REnvironmentInformation } from './environment';
|
|
2
2
|
/**
|
|
3
3
|
* Produce a clone of the given environment information.
|
|
4
|
-
* @param environment
|
|
5
|
-
* @param
|
|
4
|
+
* @param environment - The environment information to clone.
|
|
5
|
+
* @param builtInEnvironment - The built-in environment
|
|
6
|
+
* @param recurseParents - Whether to clone the parent environments as well.
|
|
6
7
|
*/
|
|
7
8
|
export declare function cloneEnvironmentInformation(environment: REnvironmentInformation, recurseParents?: boolean): REnvironmentInformation;
|
|
@@ -6,18 +6,19 @@ function cloneEnvironment(environment, recurseParents) {
|
|
|
6
6
|
if (environment === undefined) {
|
|
7
7
|
return undefined;
|
|
8
8
|
}
|
|
9
|
-
else if (environment.
|
|
10
|
-
return
|
|
9
|
+
else if (environment.builtInEnv) {
|
|
10
|
+
return environment; // do not clone the built-in environment
|
|
11
11
|
}
|
|
12
12
|
/* make sure the clone has the same id */
|
|
13
|
-
const clone = new environment_1.Environment(recurseParents ? cloneEnvironment(environment.parent, recurseParents) : environment.parent);
|
|
13
|
+
const clone = new environment_1.Environment(recurseParents ? cloneEnvironment(environment.parent, recurseParents) : environment.parent, environment.builtInEnv);
|
|
14
14
|
clone.memory = new Map(JSON.parse(JSON.stringify([...environment.memory])));
|
|
15
15
|
return clone;
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* Produce a clone of the given environment information.
|
|
19
|
-
* @param environment
|
|
20
|
-
* @param
|
|
19
|
+
* @param environment - The environment information to clone.
|
|
20
|
+
* @param builtInEnvironment - The built-in environment
|
|
21
|
+
* @param recurseParents - Whether to clone the parent environments as well.
|
|
21
22
|
*/
|
|
22
23
|
function cloneEnvironmentInformation(environment, recurseParents = true) {
|
|
23
24
|
return {
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.mergeDefinitions = mergeDefinitions;
|
|
4
4
|
exports.define = define;
|
|
5
5
|
const assert_1 = require("../../util/assert");
|
|
6
|
-
const environment_1 = require("./environment");
|
|
7
6
|
const clone_1 = require("./clone");
|
|
8
7
|
const vertex_1 = require("../graph/vertex");
|
|
9
8
|
function defInEnv(newEnvironments, name, definition, config) {
|
|
@@ -138,7 +137,7 @@ function define(definition, superAssign, environment, config) {
|
|
|
138
137
|
}
|
|
139
138
|
last = current;
|
|
140
139
|
current = current.parent;
|
|
141
|
-
} while (current.
|
|
140
|
+
} while (!current.builtInEnv);
|
|
142
141
|
if (!found) {
|
|
143
142
|
(0, assert_1.guard)(last !== undefined, () => `Could not find global scope for ${name}`);
|
|
144
143
|
last.memory.set(name, [definition]);
|
|
@@ -7,7 +7,6 @@ const diff_1 = require("../../util/diff");
|
|
|
7
7
|
const environment_1 = require("./environment");
|
|
8
8
|
const json_1 = require("../../util/json");
|
|
9
9
|
const info_1 = require("../info");
|
|
10
|
-
const built_in_1 = require("./built-in");
|
|
11
10
|
function diffIdentifierReferences(a, b, info) {
|
|
12
11
|
if (a === undefined || b === undefined) {
|
|
13
12
|
if (a !== b) {
|
|
@@ -59,8 +58,7 @@ function diffEnvironment(a, b, info, depth) {
|
|
|
59
58
|
}
|
|
60
59
|
return;
|
|
61
60
|
}
|
|
62
|
-
if (
|
|
63
|
-
(b.memory === built_in_1.BuiltInMemory || b.memory === built_in_1.EmptyBuiltInMemory)) {
|
|
61
|
+
if (a.builtInEnv && b.builtInEnv) {
|
|
64
62
|
return;
|
|
65
63
|
}
|
|
66
64
|
if (a.memory.size !== b.memory.size) {
|
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
|
-
import type {
|
|
7
|
+
import type { IdentifierReference } from './identifier';
|
|
8
8
|
import type { DataflowGraph } from '../graph/graph';
|
|
9
9
|
import type { ControlDependency } from '../info';
|
|
10
|
+
import type { BuiltInMemory } from './built-in';
|
|
10
11
|
/**
|
|
11
12
|
* Marks the reference as maybe (i.e., as controlled by a set of {@link IdentifierReference#controlDependencies|control dependencies}).
|
|
12
13
|
*/
|
|
13
14
|
export declare function makeReferenceMaybe(ref: IdentifierReference, graph: DataflowGraph, environments: REnvironmentInformation, includeDefs: boolean, defaultCd?: ControlDependency | undefined): IdentifierReference;
|
|
14
15
|
export declare function makeAllMaybe(references: readonly IdentifierReference[] | undefined, graph: DataflowGraph, environments: REnvironmentInformation, includeDefs: boolean, defaultCd?: ControlDependency | undefined): IdentifierReference[];
|
|
15
|
-
export type EnvironmentMemory = Map<Identifier, IdentifierDefinition[]>;
|
|
16
16
|
/** A single entry/scope within an {@link REnvironmentInformation} */
|
|
17
17
|
export interface IEnvironment {
|
|
18
18
|
/** Unique and internally generated identifier -- will not be used for comparison but helps with debugging for tracking identities */
|
|
@@ -20,21 +20,31 @@ export interface IEnvironment {
|
|
|
20
20
|
/** Lexical parent of the environment, if any (can be manipulated by R code) */
|
|
21
21
|
parent: IEnvironment;
|
|
22
22
|
/** Maps to exactly one definition of an identifier if the source is known, otherwise to a list of all possible definitions */
|
|
23
|
-
memory:
|
|
23
|
+
memory: BuiltInMemory;
|
|
24
|
+
/**
|
|
25
|
+
* Is this a built-in environment that is not allowed to change? Please use this carefully and only for the top-most envs!
|
|
26
|
+
*/
|
|
27
|
+
builtInEnv?: true | undefined;
|
|
24
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Please use this function only if you do not know the object type.
|
|
31
|
+
* Otherwise, rely on {@link IEnvironment#builtInEnv}
|
|
32
|
+
*/
|
|
33
|
+
export declare function isDefaultBuiltInEnvironment(obj: unknown): boolean;
|
|
25
34
|
/** @see REnvironmentInformation */
|
|
26
35
|
export declare class Environment implements IEnvironment {
|
|
27
36
|
readonly id: number;
|
|
28
37
|
parent: IEnvironment;
|
|
29
|
-
memory:
|
|
30
|
-
|
|
38
|
+
memory: BuiltInMemory;
|
|
39
|
+
builtInEnv?: true;
|
|
40
|
+
constructor(parent: IEnvironment, isBuiltInDefault?: true | undefined);
|
|
31
41
|
}
|
|
32
42
|
export interface WorkingDirectoryReference {
|
|
33
43
|
readonly path: string;
|
|
34
44
|
readonly controlDependencies: ControlDependency[] | undefined;
|
|
35
45
|
}
|
|
36
46
|
/**
|
|
37
|
-
* An environment describes a ({@link IEnvironment#parent|scoped}) mapping of names to their definitions ({@link
|
|
47
|
+
* An environment describes a ({@link IEnvironment#parent|scoped}) mapping of names to their definitions ({@link BuiltIns}).
|
|
38
48
|
*
|
|
39
49
|
* First, yes, R stores its environments differently, potentially even with another differentiation between
|
|
40
50
|
* the `baseenv`, the `emptyenv`, and other default environments (see https://adv-r.hadley.nz/environments.html).
|
|
@@ -42,7 +52,7 @@ export interface WorkingDirectoryReference {
|
|
|
42
52
|
* and sometimes know less (to be honest, we do not want that,
|
|
43
53
|
* but statically determining all attached environments is theoretically impossible --- consider attachments by user input).
|
|
44
54
|
*
|
|
45
|
-
* One important environment is the {@link BuiltInEnvironment} which contains the default definitions for R's built-in functions and constants.
|
|
55
|
+
* One important environment is the {@link BuiltIns|BuiltInEnvironment} which contains the default definitions for R's built-in functions and constants.
|
|
46
56
|
* Please use {@link initializeCleanEnvironments} to initialize the environments (which includes the built-ins).
|
|
47
57
|
* During serialization, you may want to rely on the {@link builtInEnvJsonReplacer} to avoid the huge built-in environment.
|
|
48
58
|
*
|
|
@@ -61,26 +71,10 @@ export interface REnvironmentInformation {
|
|
|
61
71
|
/** nesting level of the environment, will be `0` for the global/root environment */
|
|
62
72
|
readonly level: number;
|
|
63
73
|
}
|
|
64
|
-
/**
|
|
65
|
-
* The built-in {@link REnvironmentInformation|environment} is the root of all environments.
|
|
66
|
-
*
|
|
67
|
-
* For its default content (when not overwritten by a flowR config),
|
|
68
|
-
* see the {@link DefaultBuiltinConfig}.
|
|
69
|
-
*/
|
|
70
|
-
export declare const BuiltInEnvironment: Environment;
|
|
71
|
-
/**
|
|
72
|
-
* The twin of the {@link BuiltInEnvironment} but with less built ins defined for
|
|
73
|
-
* cases in which we want some commonly overwritten variables to remain open.
|
|
74
|
-
* If you do not know if you need the empty environment, you do not need the empty environment (right now).
|
|
75
|
-
*
|
|
76
|
-
* @see {@link BuiltInEnvironment}
|
|
77
|
-
*/
|
|
78
|
-
export declare const EmptyBuiltInEnvironment: IEnvironment;
|
|
79
74
|
/**
|
|
80
75
|
* Initialize a new {@link REnvironmentInformation|environment} with the built-ins.
|
|
81
|
-
* See {@link EmptyBuiltInEnvironment} for the case `fullBuiltIns = false`.
|
|
82
76
|
*/
|
|
83
|
-
export declare function initializeCleanEnvironments(fullBuiltIns?: boolean): REnvironmentInformation;
|
|
77
|
+
export declare function initializeCleanEnvironments(memory?: BuiltInMemory, fullBuiltIns?: boolean): REnvironmentInformation;
|
|
84
78
|
/**
|
|
85
79
|
* Helps to serialize an environment, but replaces the built-in environment with a placeholder.
|
|
86
80
|
*/
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.Environment = void 0;
|
|
4
4
|
exports.makeReferenceMaybe = makeReferenceMaybe;
|
|
5
5
|
exports.makeAllMaybe = makeAllMaybe;
|
|
6
|
+
exports.isDefaultBuiltInEnvironment = isDefaultBuiltInEnvironment;
|
|
6
7
|
exports.initializeCleanEnvironments = initializeCleanEnvironments;
|
|
7
8
|
exports.builtInEnvJsonReplacer = builtInEnvJsonReplacer;
|
|
8
9
|
const identifier_1 = require("./identifier");
|
|
9
|
-
const built_in_1 = require("./built-in");
|
|
10
10
|
const resolve_by_name_1 = require("./resolve-by-name");
|
|
11
11
|
const json_1 = require("../../util/json");
|
|
12
|
+
const built_in_config_1 = require("./built-in-config");
|
|
12
13
|
/**
|
|
13
14
|
* Marks the reference as maybe (i.e., as controlled by a set of {@link IdentifierReference#controlDependencies|control dependencies}).
|
|
14
15
|
*/
|
|
15
16
|
function makeReferenceMaybe(ref, graph, environments, includeDefs, defaultCd = undefined) {
|
|
16
|
-
const node = graph.get(ref.nodeId, true);
|
|
17
17
|
if (includeDefs) {
|
|
18
18
|
const definitions = ref.name ? (0, resolve_by_name_1.resolveByName)(ref.name, environments, ref.type) : undefined;
|
|
19
19
|
for (const definition of definitions ?? []) {
|
|
@@ -27,6 +27,7 @@ function makeReferenceMaybe(ref, graph, environments, includeDefs, defaultCd = u
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
+
const node = graph.get(ref.nodeId, true);
|
|
30
31
|
if (node) {
|
|
31
32
|
const [fst] = node;
|
|
32
33
|
if (fst.cds && defaultCd && !fst.cds.includes(defaultCd)) {
|
|
@@ -44,49 +45,39 @@ function makeAllMaybe(references, graph, environments, includeDefs, defaultCd =
|
|
|
44
45
|
}
|
|
45
46
|
return references.map(ref => makeReferenceMaybe(ref, graph, environments, includeDefs, defaultCd));
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Please use this function only if you do not know the object type.
|
|
50
|
+
* Otherwise, rely on {@link IEnvironment#builtInEnv}
|
|
51
|
+
*/
|
|
52
|
+
function isDefaultBuiltInEnvironment(obj) {
|
|
53
|
+
return typeof obj === 'object' && obj !== null && (obj.builtInEnv === true);
|
|
54
|
+
}
|
|
55
|
+
let environmentIdCounter = 1; // Zero is reserved for built-in environment
|
|
48
56
|
/** @see REnvironmentInformation */
|
|
49
57
|
class Environment {
|
|
50
|
-
id
|
|
58
|
+
id;
|
|
51
59
|
parent;
|
|
52
60
|
memory;
|
|
53
|
-
|
|
61
|
+
builtInEnv;
|
|
62
|
+
constructor(parent, isBuiltInDefault = undefined) {
|
|
63
|
+
this.id = isBuiltInDefault ? 0 : environmentIdCounter++;
|
|
54
64
|
this.parent = parent;
|
|
55
65
|
this.memory = new Map();
|
|
66
|
+
// do not store if not needed!
|
|
67
|
+
if (isBuiltInDefault) {
|
|
68
|
+
this.builtInEnv = isBuiltInDefault;
|
|
69
|
+
}
|
|
56
70
|
}
|
|
57
71
|
}
|
|
58
72
|
exports.Environment = Environment;
|
|
59
|
-
/**
|
|
60
|
-
* The built-in {@link REnvironmentInformation|environment} is the root of all environments.
|
|
61
|
-
*
|
|
62
|
-
* For its default content (when not overwritten by a flowR config),
|
|
63
|
-
* see the {@link DefaultBuiltinConfig}.
|
|
64
|
-
*/
|
|
65
|
-
exports.BuiltInEnvironment = new Environment(undefined);
|
|
66
|
-
exports.BuiltInEnvironment.memory = undefined;
|
|
67
|
-
/**
|
|
68
|
-
* The twin of the {@link BuiltInEnvironment} but with less built ins defined for
|
|
69
|
-
* cases in which we want some commonly overwritten variables to remain open.
|
|
70
|
-
* If you do not know if you need the empty environment, you do not need the empty environment (right now).
|
|
71
|
-
*
|
|
72
|
-
* @see {@link BuiltInEnvironment}
|
|
73
|
-
*/
|
|
74
|
-
exports.EmptyBuiltInEnvironment = {
|
|
75
|
-
id: exports.BuiltInEnvironment.id,
|
|
76
|
-
memory: undefined,
|
|
77
|
-
parent: undefined
|
|
78
|
-
};
|
|
79
73
|
/**
|
|
80
74
|
* Initialize a new {@link REnvironmentInformation|environment} with the built-ins.
|
|
81
|
-
* See {@link EmptyBuiltInEnvironment} for the case `fullBuiltIns = false`.
|
|
82
75
|
*/
|
|
83
|
-
function initializeCleanEnvironments(fullBuiltIns = true) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
exports.EmptyBuiltInEnvironment.memory = built_in_1.EmptyBuiltInMemory;
|
|
87
|
-
}
|
|
76
|
+
function initializeCleanEnvironments(memory, fullBuiltIns = true) {
|
|
77
|
+
const builtInEnv = new Environment(undefined, true);
|
|
78
|
+
builtInEnv.memory = memory ?? (fullBuiltIns ? (0, built_in_config_1.getDefaultBuiltInDefinitions)().builtInMemory : (0, built_in_config_1.getDefaultBuiltInDefinitions)().emptyBuiltInMemory);
|
|
88
79
|
return {
|
|
89
|
-
current: new Environment(
|
|
80
|
+
current: new Environment(builtInEnv),
|
|
90
81
|
level: 0
|
|
91
82
|
};
|
|
92
83
|
}
|
|
@@ -94,12 +85,9 @@ function initializeCleanEnvironments(fullBuiltIns = true) {
|
|
|
94
85
|
* Helps to serialize an environment, but replaces the built-in environment with a placeholder.
|
|
95
86
|
*/
|
|
96
87
|
function builtInEnvJsonReplacer(k, v) {
|
|
97
|
-
if (v
|
|
88
|
+
if (isDefaultBuiltInEnvironment(v)) {
|
|
98
89
|
return '<BuiltInEnvironment>';
|
|
99
90
|
}
|
|
100
|
-
else if (v === exports.EmptyBuiltInEnvironment) {
|
|
101
|
-
return '<EmptyBuiltInEnvironment>';
|
|
102
|
-
}
|
|
103
91
|
else {
|
|
104
92
|
return (0, json_1.jsonReplacer)(k, v);
|
|
105
93
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { IEnvironment, REnvironmentInformation } from './environment';
|
|
2
2
|
import type { ControlDependency } from '../info';
|
|
3
3
|
export declare function overwriteIEnvironmentWith(base: IEnvironment | undefined, next: IEnvironment | undefined, includeParent?: boolean, applyCds?: readonly ControlDependency[]): IEnvironment;
|
|
4
4
|
export declare function overwriteEnvironment(base: REnvironmentInformation, next: REnvironmentInformation | undefined, applyCds?: readonly ControlDependency[]): REnvironmentInformation;
|
|
@@ -50,7 +50,7 @@ function overwriteIEnvironmentWith(base, next, includeParent = true, applyCds) {
|
|
|
50
50
|
}
|
|
51
51
|
let parent;
|
|
52
52
|
if (includeParent) {
|
|
53
|
-
parent = base.parent.
|
|
53
|
+
parent = base.parent.builtInEnv ? base.parent : overwriteIEnvironmentWith(base.parent, next.parent, includeParent, applyCds);
|
|
54
54
|
}
|
|
55
55
|
else {
|
|
56
56
|
parent = base.parent;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { REnvironmentInformation } from './environment';
|
|
1
|
+
import type { IEnvironment, REnvironmentInformation } from './environment';
|
|
2
2
|
import type { Identifier } from './identifier';
|
|
3
3
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
4
4
|
/**
|
|
5
5
|
* Removes all definitions of a given name from the environment.
|
|
6
6
|
*/
|
|
7
|
-
export declare function remove(name: Identifier, environment: REnvironmentInformation): REnvironmentInformation;
|
|
7
|
+
export declare function remove(name: Identifier, environment: REnvironmentInformation, defaultEnvironment: IEnvironment): REnvironmentInformation;
|
|
8
8
|
/** Creates a copy of the original environment but without the definitions of the given ids */
|
|
9
9
|
export declare function removeAll(definitions: readonly {
|
|
10
10
|
nodeId: NodeId;
|
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.remove = remove;
|
|
4
4
|
exports.removeAll = removeAll;
|
|
5
|
-
const environment_1 = require("./environment");
|
|
6
5
|
const info_1 = require("../info");
|
|
7
6
|
const clone_1 = require("./clone");
|
|
8
7
|
/**
|
|
9
8
|
* Removes all definitions of a given name from the environment.
|
|
10
9
|
*/
|
|
11
|
-
function remove(name, environment) {
|
|
10
|
+
function remove(name, environment, defaultEnvironment) {
|
|
12
11
|
let current = environment.current;
|
|
13
12
|
do {
|
|
14
13
|
const definition = current.memory.get(name);
|
|
@@ -19,7 +18,7 @@ function remove(name, environment) {
|
|
|
19
18
|
}
|
|
20
19
|
}
|
|
21
20
|
current = current.parent;
|
|
22
|
-
} while (current.id !==
|
|
21
|
+
} while (current.id !== defaultEnvironment.id);
|
|
23
22
|
// we never remove built ins
|
|
24
23
|
return environment;
|
|
25
24
|
}
|
|
@@ -46,7 +45,7 @@ function removeAll(definitions, environment) {
|
|
|
46
45
|
}
|
|
47
46
|
}
|
|
48
47
|
current = current.parent;
|
|
49
|
-
} while (current.
|
|
48
|
+
} while (!current.builtInEnv);
|
|
50
49
|
// we never remove built ins so we can stop one early
|
|
51
50
|
return environment;
|
|
52
51
|
}
|
|
@@ -5,9 +5,9 @@ import { ReferenceType } from './identifier';
|
|
|
5
5
|
/**
|
|
6
6
|
* Resolves a given identifier name to a list of its possible definition location using R scoping and resolving rules.
|
|
7
7
|
*
|
|
8
|
-
* @param name
|
|
9
|
-
* @param environment
|
|
10
|
-
* @param target
|
|
8
|
+
* @param name - The name of the identifier to resolve
|
|
9
|
+
* @param environment - The current environment used for name resolution
|
|
10
|
+
* @param target - The target (meta) type of the identifier to resolve
|
|
11
11
|
*
|
|
12
12
|
* @returns A list of possible identifier definitions (one if the definition location is exactly and always known), or `undefined`
|
|
13
13
|
* if the identifier is undefined in the current scope/with the current environment information.
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.resolveByName = resolveByName;
|
|
4
4
|
exports.resolvesToBuiltInConstant = resolvesToBuiltInConstant;
|
|
5
|
-
const environment_1 = require("./environment");
|
|
6
5
|
const logic_1 = require("../../util/logic");
|
|
7
6
|
const identifier_1 = require("./identifier");
|
|
8
7
|
const info_1 = require("../info");
|
|
@@ -24,9 +23,9 @@ const TargetTypePredicate = {
|
|
|
24
23
|
/**
|
|
25
24
|
* Resolves a given identifier name to a list of its possible definition location using R scoping and resolving rules.
|
|
26
25
|
*
|
|
27
|
-
* @param name
|
|
28
|
-
* @param environment
|
|
29
|
-
* @param target
|
|
26
|
+
* @param name - The name of the identifier to resolve
|
|
27
|
+
* @param environment - The current environment used for name resolution
|
|
28
|
+
* @param target - The target (meta) type of the identifier to resolve
|
|
30
29
|
*
|
|
31
30
|
* @returns A list of possible identifier definitions (one if the definition location is exactly and always known), or `undefined`
|
|
32
31
|
* if the identifier is undefined in the current scope/with the current environment information.
|
|
@@ -48,7 +47,7 @@ function resolveByName(name, environment, target = identifier_1.ReferenceType.Un
|
|
|
48
47
|
}
|
|
49
48
|
}
|
|
50
49
|
current = current.parent;
|
|
51
|
-
} while (current.
|
|
50
|
+
} while (!current.builtInEnv);
|
|
52
51
|
const builtIns = current.memory.get(name);
|
|
53
52
|
if (definitions) {
|
|
54
53
|
return builtIns === undefined ? definitions : definitions.concat(builtIns);
|
|
@@ -27,9 +27,9 @@ export interface ResolveInfo {
|
|
|
27
27
|
* us later, in the {@link trackAliasInEnvironments} function, to get all the
|
|
28
28
|
* aliases of an identifier.
|
|
29
29
|
*
|
|
30
|
-
* @param sourceIds
|
|
31
|
-
* @param dataflow
|
|
32
|
-
* @param environment
|
|
30
|
+
* @param sourceIds - node ids to get the definitions for
|
|
31
|
+
* @param dataflow - dataflow graph
|
|
32
|
+
* @param environment - environment
|
|
33
33
|
* @returns node id of alias
|
|
34
34
|
*/
|
|
35
35
|
export declare function getAliases(sourceIds: readonly NodeId[], dataflow: DataflowGraph, environment: REnvironmentInformation): NodeId[] | undefined;
|
|
@@ -46,12 +46,12 @@ export declare function getAliases(sourceIds: readonly NodeId[], dataflow: Dataf
|
|
|
46
46
|
* to resolve values. For e.g. in the Dependency Query it is used to resolve calls
|
|
47
47
|
* like `lapply(c("a", "b", "c"), library, character.only = TRUE)`
|
|
48
48
|
*
|
|
49
|
-
* @param id
|
|
50
|
-
* @param environment
|
|
51
|
-
* @param graph
|
|
52
|
-
* @param idMap
|
|
53
|
-
* @param full
|
|
54
|
-
* @param resolve
|
|
49
|
+
* @param id - The node id or node to resolve
|
|
50
|
+
* @param environment - The current environment used for name resolution
|
|
51
|
+
* @param graph - The graph to resolve in
|
|
52
|
+
* @param idMap - The id map to resolve the node if given as an id
|
|
53
|
+
* @param full - Whether to track aliases on resolve
|
|
54
|
+
* @param resolve - Variable resolve mode
|
|
55
55
|
*/
|
|
56
56
|
export declare function resolveIdToValue(id: NodeId | RNodeWithParent | undefined, { environment, graph, idMap, full, resolve }: ResolveInfo): ResolveResult;
|
|
57
57
|
/**
|
|
@@ -64,7 +64,7 @@ export declare function resolveIdToValue(id: NodeId | RNodeWithParent | undefine
|
|
|
64
64
|
* @param resolve - Variable resolve mode
|
|
65
65
|
* @param identifier - Identifier to resolve
|
|
66
66
|
* @param use - Environment to use
|
|
67
|
-
* @param graph -
|
|
67
|
+
* @param graph - dataflow graph
|
|
68
68
|
* @param idMap - id map of Dataflow graph
|
|
69
69
|
* @returns Value of Identifier or Top
|
|
70
70
|
*/
|
|
@@ -85,8 +85,8 @@ export declare function trackAliasesInGraph(id: NodeId, graph: DataflowGraph, id
|
|
|
85
85
|
*
|
|
86
86
|
* Resolve an Identifier to a constant, if the identifier is a constant
|
|
87
87
|
*
|
|
88
|
-
* @param name
|
|
89
|
-
* @param environment
|
|
88
|
+
* @param name - Identifier to resolve
|
|
89
|
+
* @param environment - Environment to use
|
|
90
90
|
* @returns Value of Constant or Top
|
|
91
91
|
*/
|
|
92
92
|
export declare function resolveToConstants(name: Identifier | undefined, environment: REnvironmentInformation): ResolveResult;
|