@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.
Files changed (145) hide show
  1. package/README.md +42 -30
  2. package/abstract-interpretation/data-frame/absint-visitor.d.ts +2 -3
  3. package/abstract-interpretation/data-frame/absint-visitor.js +14 -16
  4. package/abstract-interpretation/data-frame/mappers/function-mapper.js +3 -3
  5. package/abstract-interpretation/data-frame/semantics.d.ts +1 -1
  6. package/abstract-interpretation/data-frame/semantics.js +7 -10
  7. package/abstract-interpretation/data-frame/shape-inference.js +2 -8
  8. package/benchmark/slicer.js +7 -5
  9. package/benchmark/stats/size-of.js +3 -3
  10. package/benchmark/summarizer/second-phase/graph.js +1 -1
  11. package/benchmark/summarizer/second-phase/process.js +1 -1
  12. package/cli/benchmark-app.d.ts +1 -0
  13. package/cli/benchmark-app.js +1 -0
  14. package/cli/benchmark-helper-app.d.ts +1 -0
  15. package/cli/benchmark-helper-app.js +4 -3
  16. package/cli/common/options.js +2 -0
  17. package/cli/repl/commands/repl-query.js +1 -1
  18. package/cli/repl/server/connection.js +14 -5
  19. package/control-flow/basic-cfg-guided-visitor.d.ts +1 -2
  20. package/control-flow/basic-cfg-guided-visitor.js +0 -6
  21. package/control-flow/cfg-simplification.d.ts +6 -0
  22. package/control-flow/cfg-simplification.js +18 -9
  23. package/control-flow/control-flow-graph.d.ts +2 -8
  24. package/control-flow/control-flow-graph.js +1 -6
  25. package/control-flow/extract-cfg.d.ts +2 -2
  26. package/control-flow/extract-cfg.js +52 -63
  27. package/core/pipeline-executor.js +0 -8
  28. package/core/steps/all/static-slicing/00-slice.d.ts +7 -1
  29. package/core/steps/all/static-slicing/00-slice.js +9 -3
  30. package/core/steps/pipeline/default-pipelines.d.ts +74 -74
  31. package/dataflow/environments/append.js +1 -1
  32. package/dataflow/environments/built-in-config.d.ts +12 -4
  33. package/dataflow/environments/built-in-config.js +23 -82
  34. package/dataflow/environments/built-in.d.ts +40 -6
  35. package/dataflow/environments/built-in.js +119 -23
  36. package/dataflow/environments/clone.d.ts +3 -2
  37. package/dataflow/environments/clone.js +6 -5
  38. package/dataflow/environments/define.js +1 -2
  39. package/dataflow/environments/diff.js +1 -3
  40. package/dataflow/environments/environment.d.ts +18 -24
  41. package/dataflow/environments/environment.js +25 -37
  42. package/dataflow/environments/overwrite.d.ts +1 -1
  43. package/dataflow/environments/overwrite.js +1 -1
  44. package/dataflow/environments/remove.d.ts +2 -2
  45. package/dataflow/environments/remove.js +3 -4
  46. package/dataflow/environments/resolve-by-name.d.ts +3 -3
  47. package/dataflow/environments/resolve-by-name.js +4 -5
  48. package/dataflow/eval/resolve/alias-tracking.d.ts +12 -12
  49. package/dataflow/eval/resolve/alias-tracking.js +12 -12
  50. package/dataflow/eval/resolve/resolve.js +1 -1
  51. package/dataflow/extractor.js +6 -1
  52. package/dataflow/graph/dataflowgraph-builder.d.ts +3 -1
  53. package/dataflow/graph/dataflowgraph-builder.js +2 -2
  54. package/dataflow/graph/graph.d.ts +2 -1
  55. package/dataflow/graph/graph.js +6 -2
  56. package/dataflow/graph/invert-dfg.d.ts +2 -0
  57. package/dataflow/graph/invert-dfg.js +17 -0
  58. package/dataflow/info.d.ts +1 -1
  59. package/dataflow/internal/linker.js +9 -9
  60. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +1 -1
  61. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -4
  62. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +5 -5
  63. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +9 -7
  64. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +2 -2
  65. package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +1 -1
  66. package/dataflow/processor.d.ts +5 -1
  67. package/documentation/doc-util/doc-env.js +1 -2
  68. package/documentation/doc-util/doc-query.js +1 -1
  69. package/documentation/doc-util/doc-search.js +2 -2
  70. package/documentation/print-cfg-wiki.js +3 -4
  71. package/documentation/print-core-wiki.js +2 -2
  72. package/documentation/print-dataflow-graph-wiki.js +7 -0
  73. package/documentation/print-faq-wiki.js +4 -0
  74. package/documentation/print-linter-wiki.js +32 -4
  75. package/documentation/print-linting-and-testing-wiki.js +13 -1
  76. package/documentation/print-onboarding-wiki.js +4 -0
  77. package/documentation/print-query-wiki.js +12 -3
  78. package/linter/linter-executor.js +1 -2
  79. package/linter/linter-format.d.ts +26 -4
  80. package/linter/linter-format.js +25 -6
  81. package/linter/linter-rules.d.ts +40 -12
  82. package/linter/linter-rules.js +3 -1
  83. package/linter/rules/absolute-path.d.ts +4 -7
  84. package/linter/rules/absolute-path.js +9 -6
  85. package/linter/rules/dataframe-access-validation.d.ts +3 -1
  86. package/linter/rules/dataframe-access-validation.js +3 -1
  87. package/linter/rules/dead-code.d.ts +43 -0
  88. package/linter/rules/dead-code.js +50 -0
  89. package/linter/rules/deprecated-functions.d.ts +3 -2
  90. package/linter/rules/deprecated-functions.js +3 -1
  91. package/linter/rules/file-path-validity.d.ts +4 -4
  92. package/linter/rules/file-path-validity.js +8 -6
  93. package/linter/rules/naming-convention.d.ts +4 -3
  94. package/linter/rules/naming-convention.js +3 -1
  95. package/linter/rules/seeded-randomness.d.ts +4 -3
  96. package/linter/rules/seeded-randomness.js +3 -1
  97. package/linter/rules/unused-definition.d.ts +2 -0
  98. package/linter/rules/unused-definition.js +3 -1
  99. package/package.json +1 -1
  100. package/queries/base-query-format.d.ts +2 -0
  101. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +7 -7
  102. package/queries/catalog/dependencies-query/dependencies-query-executor.js +24 -1
  103. package/queries/catalog/dependencies-query/function-info/function-info.d.ts +9 -5
  104. package/queries/catalog/dependencies-query/function-info/read-functions.js +5 -2
  105. package/queries/catalog/dependencies-query/function-info/write-functions.js +6 -0
  106. package/queries/catalog/linter-query/linter-query-format.js +1 -1
  107. package/queries/catalog/location-map-query/location-map-query-executor.js +7 -5
  108. package/queries/catalog/location-map-query/location-map-query-format.d.ts +3 -0
  109. package/queries/catalog/location-map-query/location-map-query-format.js +1 -0
  110. package/queries/catalog/search-query/search-query-executor.js +1 -1
  111. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  112. package/queries/catalog/static-slice-query/static-slice-query-executor.js +3 -2
  113. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +3 -0
  114. package/queries/catalog/static-slice-query/static-slice-query-format.js +3 -1
  115. package/queries/query-print.d.ts +1 -1
  116. package/queries/query-print.js +0 -1
  117. package/queries/query.d.ts +16 -5
  118. package/queries/query.js +24 -11
  119. package/search/flowr-search-builder.d.ts +6 -6
  120. package/search/flowr-search-executor.d.ts +2 -2
  121. package/search/flowr-search-executor.js +1 -1
  122. package/search/flowr-search.d.ts +13 -8
  123. package/search/flowr-search.js +21 -0
  124. package/search/search-executor/search-enrichers.d.ts +87 -20
  125. package/search/search-executor/search-enrichers.js +44 -5
  126. package/search/search-executor/search-generators.d.ts +4 -4
  127. package/search/search-executor/search-generators.js +12 -7
  128. package/search/search-executor/search-mappers.js +3 -2
  129. package/search/search-executor/search-transformer.d.ts +3 -3
  130. package/search/search-executor/search-transformer.js +2 -2
  131. package/slicing/static/fingerprint.js +1 -2
  132. package/slicing/static/slice-call.d.ts +2 -1
  133. package/slicing/static/slice-call.js +3 -3
  134. package/slicing/static/static-slicer.d.ts +6 -5
  135. package/slicing/static/static-slicer.js +13 -7
  136. package/util/collections/arrays.d.ts +2 -0
  137. package/util/collections/arrays.js +9 -0
  138. package/util/containers.d.ts +1 -0
  139. package/util/containers.js +1 -0
  140. package/util/json.js +1 -4
  141. package/util/mermaid/dfg.js +5 -4
  142. package/util/prefix.d.ts +1 -1
  143. package/util/range.d.ts +1 -0
  144. package/util/range.js +5 -1
  145. package/util/version.js +1 -1
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EmptyBuiltInMemory = exports.BuiltInMemory = exports.BuiltInEvalHandlerMapper = exports.BuiltInProcessorMapper = void 0;
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, config) {
45
- const { information: res, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs, origin: config.useAsProcessor ?? 'builtin:default' });
46
- if (config.returnsNthArgument !== undefined) {
47
- const arg = config.returnsNthArgument === 'last' ? processedArguments[args.length - 1] : processedArguments[config.returnsNthArgument];
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 (config.readAllArguments) {
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 (config.hasUnknownSideEffects) {
60
- if (typeof config.hasUnknownSideEffects !== 'boolean') {
61
- (0, unknown_side_effect_1.handleUnknownSideEffect)(res.graph, res.environment, rootId, config.hasUnknownSideEffects);
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 = config.treatAsFnCall?.[name.content];
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: [config.useAsProcessor ?? 'builtin:default']
92
+ origin: [activeProcessor]
94
93
  });
95
94
  }
96
95
  }
97
96
  }
98
- if (config.cfg !== undefined) {
99
- res.exitPoints = [...res.exitPoints, { type: config.cfg, nodeId: rootId, controlDependencies: data.controlDependencies }];
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
- exports.BuiltInMemory.set(name, d);
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
- exports.BuiltInMemory = new Map();
152
- exports.EmptyBuiltInMemory = new Map();
153
- (0, built_in_config_1.registerBuiltInDefinitions)(default_builtin_config_1.DefaultBuiltinConfig);
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 - The environment information to clone.
5
- * @param recurseParents - Whether to clone the parent environments as well.
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.id === environment_1.BuiltInEnvironment.id) {
10
- return environment_1.BuiltInEnvironment;
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 - The environment information to clone.
20
- * @param recurseParents - Whether to clone the parent environments as well.
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.id !== environment_1.BuiltInEnvironment.id);
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 ((a.memory === built_in_1.BuiltInMemory || a.memory === built_in_1.EmptyBuiltInMemory) &&
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 { Identifier, IdentifierDefinition, IdentifierReference } from './identifier';
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: EnvironmentMemory;
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: Map<Identifier, IdentifierDefinition[]>;
30
- constructor(parent: IEnvironment);
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 EnvironmentMemory}).
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.EmptyBuiltInEnvironment = exports.BuiltInEnvironment = exports.Environment = void 0;
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
- let environmentIdCounter = 0;
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 = environmentIdCounter++;
58
+ id;
51
59
  parent;
52
60
  memory;
53
- constructor(parent) {
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
- if (exports.BuiltInEnvironment.memory === undefined) {
85
- exports.BuiltInEnvironment.memory = built_in_1.BuiltInMemory;
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(fullBuiltIns ? exports.BuiltInEnvironment : exports.EmptyBuiltInEnvironment),
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 === exports.BuiltInEnvironment) {
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 { REnvironmentInformation, IEnvironment } from './environment';
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.id === environment_1.BuiltInEnvironment.id ? environment_1.BuiltInEnvironment : overwriteIEnvironmentWith(base.parent, next.parent, includeParent, applyCds);
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 !== environment_1.BuiltInEnvironment.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.id !== environment_1.BuiltInEnvironment.id);
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 - 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
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 - The name of the identifier to resolve
28
- * @param environment - The current environment used for name resolution
29
- * @param target - The target (meta) type of the identifier to resolve
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.id !== environment_1.BuiltInEnvironment.id);
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 - node ids to get the definitions for
31
- * @param dataflow - dataflow graph
32
- * @param environment - 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 - 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
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 - Dataflow 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 - Identifier to resolve
89
- * @param environment - Environment to use
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;