@eagleoutice/flowr 2.10.4 → 2.10.5

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 (81) hide show
  1. package/README.md +37 -20
  2. package/abstract-interpretation/absint-visitor.d.ts +17 -21
  3. package/abstract-interpretation/absint-visitor.js +47 -48
  4. package/abstract-interpretation/data-frame/dataframe-domain.d.ts +0 -3
  5. package/abstract-interpretation/data-frame/shape-inference.d.ts +2 -1
  6. package/abstract-interpretation/data-frame/shape-inference.js +5 -4
  7. package/abstract-interpretation/domains/abstract-domain.d.ts +17 -16
  8. package/abstract-interpretation/domains/abstract-domain.js +25 -27
  9. package/abstract-interpretation/domains/bounded-set-domain.js +1 -1
  10. package/abstract-interpretation/domains/multi-value-state-domain.d.ts +32 -0
  11. package/abstract-interpretation/domains/multi-value-state-domain.js +60 -0
  12. package/abstract-interpretation/domains/partial-product-domain.d.ts +43 -0
  13. package/abstract-interpretation/domains/partial-product-domain.js +163 -0
  14. package/abstract-interpretation/domains/product-domain.d.ts +2 -29
  15. package/abstract-interpretation/domains/product-domain.js +6 -123
  16. package/abstract-interpretation/domains/set-range-domain.js +3 -3
  17. package/abstract-interpretation/domains/set-upper-bound-domain.js +1 -1
  18. package/abstract-interpretation/domains/singleton-domain.js +1 -1
  19. package/abstract-interpretation/domains/state-abstract-domain.d.ts +13 -28
  20. package/abstract-interpretation/domains/state-abstract-domain.js +16 -38
  21. package/abstract-interpretation/domains/state-domain-like.d.ts +36 -0
  22. package/abstract-interpretation/domains/state-domain-like.js +3 -0
  23. package/cli/flowr.js +11 -1
  24. package/config.d.ts +7 -0
  25. package/config.js +22 -3
  26. package/control-flow/semantic-cfg-guided-visitor.d.ts +4 -0
  27. package/control-flow/semantic-cfg-guided-visitor.js +20 -32
  28. package/dataflow/environments/default-builtin-config.d.ts +10 -0
  29. package/dataflow/environments/default-builtin-config.js +2 -1
  30. package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +2 -0
  31. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +38 -21
  32. package/documentation/doc-readme.js +13 -2
  33. package/documentation/wiki-absint.d.ts +1 -2
  34. package/documentation/wiki-absint.js +34 -10
  35. package/documentation/wiki-analyzer.js +3 -4
  36. package/documentation/wiki-interface.js +21 -16
  37. package/linter/linter-rules.d.ts +2 -2
  38. package/linter/rules/problematic-inputs.d.ts +4 -3
  39. package/linter/rules/problematic-inputs.js +3 -4
  40. package/package.json +3 -3
  41. package/project/flowr-analyzer-builder.d.ts +6 -3
  42. package/project/flowr-analyzer-builder.js +12 -5
  43. package/project/plugins/file-plugins/files/flowr-rmarkdown-file.d.ts +4 -3
  44. package/project/plugins/file-plugins/files/flowr-rmarkdown-file.js +17 -4
  45. package/project/plugins/flowr-analyzer-plugin.d.ts +1 -1
  46. package/project/plugins/flowr-analyzer-plugin.js +1 -1
  47. package/queries/catalog/input-sources-query/input-source-functions.d.ts +6 -0
  48. package/queries/catalog/input-sources-query/input-source-functions.js +50 -0
  49. package/queries/catalog/input-sources-query/input-sources-query-executor.d.ts +1 -1
  50. package/queries/catalog/input-sources-query/input-sources-query-executor.js +19 -53
  51. package/queries/catalog/input-sources-query/input-sources-query-format.d.ts +2 -1
  52. package/queries/catalog/input-sources-query/input-sources-query-format.js +26 -11
  53. package/queries/catalog/input-sources-query/simple-input-classifier.d.ts +18 -41
  54. package/queries/catalog/input-sources-query/simple-input-classifier.js +165 -103
  55. package/r-bridge/lang-4.x/ast/model/model.d.ts +4 -4
  56. package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +3 -3
  57. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +3 -3
  58. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +3 -3
  59. package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +3 -3
  60. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +3 -3
  61. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +3 -3
  62. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +3 -3
  63. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +3 -3
  64. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +3 -3
  65. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +3 -3
  66. package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +3 -3
  67. package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +3 -3
  68. package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +3 -3
  69. package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +3 -3
  70. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +3 -3
  71. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +3 -3
  72. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +3 -3
  73. package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +3 -3
  74. package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +3 -3
  75. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +3 -3
  76. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +3 -3
  77. package/util/record.d.ts +18 -3
  78. package/util/record.js +22 -1
  79. package/util/version.js +1 -1
  80. package/project/plugins/flowr-analyzer-plugin-defaults.d.ts +0 -5
  81. package/project/plugins/flowr-analyzer-plugin-defaults.js +0 -37
@@ -1,32 +1,33 @@
1
1
  import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
2
2
  import { AbstractDomain, type AnyAbstractDomain, type ConcreteDomain } from './abstract-domain';
3
3
  import { Bottom, Top } from './lattice';
4
+ import type { StateDomainLike } from './state-domain-like';
4
5
  /** The type of the concrete state of the concrete domain of a state abstract domain that maps keys to a concrete value in the concrete domain */
5
6
  export type ConcreteState<Domain extends AnyAbstractDomain> = ReadonlyMap<NodeId, ConcreteDomain<Domain>>;
6
7
  /** The type of the actual values of the state abstract domain as map of keys to domain values */
7
- type StateDomainValue<Domain extends AnyAbstractDomain> = ReadonlyMap<NodeId, Domain>;
8
+ export type StateDomainValue<Domain extends AnyAbstractDomain> = ReadonlyMap<NodeId, Domain>;
8
9
  /** The type of the Top element of the state abstract domain as (empty) map of keys to domain values */
9
- type StateDomainTop = ReadonlyMap<NodeId, never>;
10
+ export type StateDomainTop = ReadonlyMap<NodeId, never>;
10
11
  /** The type of the Bottom element of the state abstract domain as {@link Bottom} symbol */
11
- type StateDomainBottom = typeof Bottom;
12
+ export type StateDomainBottom = typeof Bottom;
12
13
  /** The type of the abstract values of the state abstract domain that are Top, Bottom, or actual values */
13
- type StateDomainLift<Domain extends AnyAbstractDomain> = StateDomainValue<Domain> | StateDomainBottom;
14
+ export type StateDomainLift<Domain extends AnyAbstractDomain> = StateDomainValue<Domain> | StateDomainBottom;
14
15
  /**
15
16
  * A state abstract domain that maps AST node IDs of a program to abstract values of an abstract domain.
16
17
  * The Bottom element is defined as {@link Bottom} symbol and the Top element as empty mapping.
17
18
  * @template Domain - Type of the value abstract domain to map the AST node IDs to
18
19
  * @see {@link NodeId} for the node IDs of the AST nodes
19
20
  */
20
- export declare class StateAbstractDomain<Domain extends AnyAbstractDomain, Value extends StateDomainLift<Domain> = StateDomainLift<Domain>> extends AbstractDomain<ConcreteState<Domain>, StateDomainValue<Domain>, StateDomainTop, StateDomainBottom, Value> {
21
- protected domain: Domain;
21
+ export declare class StateAbstractDomain<Domain extends AnyAbstractDomain, Value extends StateDomainLift<Domain> = StateDomainLift<Domain>> extends AbstractDomain<ConcreteState<Domain>, StateDomainValue<Domain>, StateDomainTop, StateDomainBottom, Value> implements StateDomainLike<Domain> {
22
+ readonly domain: Domain;
22
23
  constructor(value: Value, domain: Domain);
23
24
  create(value: StateDomainLift<Domain>): this;
24
- static top<Domain extends AnyAbstractDomain>(domain: Domain): StateAbstractDomain<Domain, StateDomainTop>;
25
- static bottom<Domain extends AnyAbstractDomain>(domain: Domain): StateAbstractDomain<Domain, StateDomainBottom>;
26
- get(key: NodeId): Domain | undefined;
27
- has(key: NodeId): boolean;
28
- protected set(key: NodeId, value: Domain): void;
29
- protected remove(key: NodeId): void;
25
+ static top<Domain extends AnyAbstractDomain, StateDomain extends StateAbstractDomain<Domain, StateDomainTop>>(this: new (value: StateDomainTop, domain: Domain) => StateDomain, domain: Domain): StateDomain;
26
+ static bottom<Domain extends AnyAbstractDomain, StateDomain extends StateAbstractDomain<Domain, StateDomainBottom>>(this: new (value: StateDomainBottom, domain: Domain) => StateDomain, domain: Domain): StateDomain;
27
+ get(node: NodeId): Domain | undefined;
28
+ has(node: NodeId): boolean;
29
+ set(node: NodeId, value: Domain): void;
30
+ remove(node: NodeId): void;
30
31
  top(): this & StateAbstractDomain<Domain, StateDomainTop>;
31
32
  bottom(): this & StateAbstractDomain<Domain, StateDomainBottom>;
32
33
  equals(other: this): boolean;
@@ -43,19 +44,3 @@ export declare class StateAbstractDomain<Domain extends AnyAbstractDomain, Value
43
44
  isBottom(): this is this & StateAbstractDomain<Domain, StateDomainBottom>;
44
45
  isValue(): this is this & StateAbstractDomain<Domain, StateDomainValue<Domain>>;
45
46
  }
46
- /**
47
- * A mutable version of the {@link StateAbstractDomain} with {@link MutableStateAbstractDomain#set|`set`} and {@link MutableStateAbstractDomain#remove|`remove`}.
48
- */
49
- export declare class MutableStateAbstractDomain<Domain extends AnyAbstractDomain, Value extends StateDomainLift<Domain> = StateDomainLift<Domain>> extends StateAbstractDomain<Domain, Value> {
50
- create(value: StateDomainLift<Domain>): this;
51
- static top<Domain extends AnyAbstractDomain>(domain: Domain): MutableStateAbstractDomain<Domain, StateDomainTop>;
52
- static bottom<Domain extends AnyAbstractDomain>(domain: Domain): MutableStateAbstractDomain<Domain, StateDomainBottom>;
53
- set(key: NodeId, value: Domain): void;
54
- remove(key: NodeId): void;
55
- }
56
- /**
57
- * The type of the value abstract domain of a state abstract domain (i.e. the abstract domain a state abstract domain maps to).
58
- * @template StateDomain - The state abstract domain to get the value abstract domain type for
59
- */
60
- export type ValueAbstractDomain<StateDomain extends StateAbstractDomain<AnyAbstractDomain>> = StateDomain extends StateAbstractDomain<infer Domain> ? Domain : never;
61
- export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MutableStateAbstractDomain = exports.StateAbstractDomain = void 0;
3
+ exports.StateAbstractDomain = void 0;
4
4
  const abstract_domain_1 = require("./abstract-domain");
5
5
  const lattice_1 = require("./lattice");
6
6
  /**
@@ -24,33 +24,32 @@ class StateAbstractDomain extends abstract_domain_1.AbstractDomain {
24
24
  return new StateAbstractDomain(value, this.domain);
25
25
  }
26
26
  static top(domain) {
27
- return new StateAbstractDomain(new Map(), domain);
27
+ return new this(new Map(), domain);
28
28
  }
29
29
  static bottom(domain) {
30
- return new StateAbstractDomain(lattice_1.Bottom, domain);
30
+ return new this(lattice_1.Bottom, domain);
31
31
  }
32
- get(key) {
33
- return this.value === lattice_1.Bottom ? this.domain.bottom() : this.value.get(key);
32
+ get(node) {
33
+ return this.value === lattice_1.Bottom ? this.domain.bottom() : this.value.get(node);
34
34
  }
35
- has(key) {
36
- return this.value !== lattice_1.Bottom && this.value.has(key);
35
+ has(node) {
36
+ return this.value !== lattice_1.Bottom && this.value.has(node);
37
37
  }
38
- set(key, value) {
39
- if (this.value === lattice_1.Bottom) {
40
- this._value = new Map();
38
+ set(node, value) {
39
+ if (this.value !== lattice_1.Bottom) {
40
+ this._value.set(node, value);
41
41
  }
42
- this._value.set(key, value);
43
42
  }
44
- remove(key) {
43
+ remove(node) {
45
44
  if (this.value !== lattice_1.Bottom) {
46
- this._value.delete(key);
45
+ this._value.delete(node);
47
46
  }
48
47
  }
49
48
  top() {
50
- return StateAbstractDomain.top(this.domain);
49
+ return this.create(new Map());
51
50
  }
52
51
  bottom() {
53
- return StateAbstractDomain.bottom(this.domain);
52
+ return this.create(lattice_1.Bottom);
54
53
  }
55
54
  equals(other) {
56
55
  if (this.value === other.value) {
@@ -216,38 +215,17 @@ class StateAbstractDomain extends abstract_domain_1.AbstractDomain {
216
215
  if (this.value === lattice_1.Bottom) {
217
216
  return lattice_1.BottomSymbol;
218
217
  }
219
- return '(' + this.value.entries().toArray().map(([key, value]) => `${(0, abstract_domain_1.domainElementToString)(key)} -> ${value.toString()}`).join(', ') + ')';
218
+ return '(' + this.value.entries().toArray().map(([key, value]) => `${abstract_domain_1.AbstractDomain.toString(key)} -> ${value.toString()}`).join(', ') + ')';
220
219
  }
221
220
  isTop() {
222
221
  return this.value !== lattice_1.Bottom && this.value.size === 0;
223
222
  }
224
223
  isBottom() {
225
- return this.value == lattice_1.Bottom;
224
+ return this.value === lattice_1.Bottom;
226
225
  }
227
226
  isValue() {
228
227
  return this.value !== lattice_1.Bottom;
229
228
  }
230
229
  }
231
230
  exports.StateAbstractDomain = StateAbstractDomain;
232
- /**
233
- * A mutable version of the {@link StateAbstractDomain} with {@link MutableStateAbstractDomain#set|`set`} and {@link MutableStateAbstractDomain#remove|`remove`}.
234
- */
235
- class MutableStateAbstractDomain extends StateAbstractDomain {
236
- create(value) {
237
- return new MutableStateAbstractDomain(value, this.domain);
238
- }
239
- static top(domain) {
240
- return new MutableStateAbstractDomain(new Map(), domain);
241
- }
242
- static bottom(domain) {
243
- return new MutableStateAbstractDomain(lattice_1.Bottom, domain);
244
- }
245
- set(key, value) {
246
- super.set(key, value);
247
- }
248
- remove(key) {
249
- super.remove(key);
250
- }
251
- }
252
- exports.MutableStateAbstractDomain = MutableStateAbstractDomain;
253
231
  //# sourceMappingURL=state-abstract-domain.js.map
@@ -0,0 +1,36 @@
1
+ import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
2
+ import { type AnyAbstractDomain } from './abstract-domain';
3
+ /**
4
+ * An interface for state-like domains that store abstract values for AST nodes.
5
+ */
6
+ export interface StateDomainLike<Domain extends AnyAbstractDomain> {
7
+ /**
8
+ * The underlying value domain of the state domain.
9
+ */
10
+ get domain(): Domain;
11
+ /**
12
+ * Gets the inferred abstract value for an AST node ID.
13
+ */
14
+ get(node: NodeId): Domain | undefined;
15
+ /**
16
+ * Checks whether the state domain has an inferred value for an AST node ID.
17
+ */
18
+ has(node: NodeId): boolean;
19
+ /**
20
+ * Removes the inferred value for an AST node ID from the state domain.
21
+ */
22
+ remove(node: NodeId): void;
23
+ /**
24
+ * Sets the inferred value for an AST node ID from the state domain.
25
+ */
26
+ set(node: NodeId, value: Domain): void;
27
+ }
28
+ /**
29
+ * A type representing any state abstract domain that stores abstract values for AST nodes.
30
+ */
31
+ export type AnyStateDomain<Domain extends AnyAbstractDomain> = AnyAbstractDomain & StateDomainLike<Domain>;
32
+ /**
33
+ * The type of the value abstract domain of a state abstract domain.
34
+ * @template StateDomain - The state abstract domain to get the value abstract domain type for
35
+ */
36
+ export type ValueDomain<StateDomain extends AnyStateDomain<AnyAbstractDomain>> = StateDomain extends AnyStateDomain<infer Domain> ? Domain : never;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=state-domain-like.js.map
package/cli/flowr.js CHANGED
@@ -102,6 +102,15 @@ function hookSignalHandlers(engines) {
102
102
  process.on('SIGINT', end);
103
103
  process.on('SIGTERM', end);
104
104
  }
105
+ function getReplPlugins(config) {
106
+ const plugins = config.repl.plugins.filter(p => p !== 'flowr:default');
107
+ if (plugins.length !== config.repl.plugins.length) {
108
+ return plugins.concat(config.defaultPlugins);
109
+ }
110
+ else {
111
+ return plugins;
112
+ }
113
+ }
105
114
  async function mainRepl() {
106
115
  const config = createConfig();
107
116
  if (options.script) {
@@ -128,9 +137,10 @@ async function mainRepl() {
128
137
  process.exit(0);
129
138
  }
130
139
  hookSignalHandlers(engines);
131
- const analyzer = new flowr_analyzer_builder_1.FlowrAnalyzerBuilder()
140
+ const analyzer = new flowr_analyzer_builder_1.FlowrAnalyzerBuilder(false)
132
141
  .setParser(defaultEngine)
133
142
  .setConfig(config)
143
+ .registerPlugins(...getReplPlugins(config))
134
144
  .buildSync();
135
145
  const allowRSessionAccess = options['r-session-access'] ?? false;
136
146
  if (options.execute) {
package/config.d.ts CHANGED
@@ -6,6 +6,7 @@ import type { DeepWritable, Paths, PathValue } from 'ts-essentials';
6
6
  import type { DataflowProcessors } from './dataflow/processor';
7
7
  import type { ParentInformation } from './r-bridge/lang-4.x/ast/model/processing/decorate';
8
8
  import type { FlowrAnalyzerContext } from './project/context/flowr-analyzer-context';
9
+ import type { BuiltInFlowrPluginArgs, BuiltInFlowrPluginName } from './project/plugins/plugin-registry';
9
10
  export declare enum VariableResolve {
10
11
  /** Don't resolve constants at all */
11
12
  Disabled = "disabled",
@@ -83,6 +84,7 @@ export interface FlowrLaxSourcingOptions extends MergeableRecord {
83
84
  */
84
85
  readonly applyReplacements?: Record<string, string>[];
85
86
  }
87
+ export type ConfigPlugin<T extends BuiltInFlowrPluginName | string> = T | string | (T extends BuiltInFlowrPluginName ? [T, BuiltInFlowrPluginArgs<T>] : [string, unknown[]]);
86
88
  /**
87
89
  * The configuration file format for flowR.
88
90
  * @see {@link FlowrConfig.default} for the default configuration.
@@ -106,12 +108,16 @@ export interface FlowrConfig extends MergeableRecord {
106
108
  };
107
109
  };
108
110
  };
111
+ /** Plugins to load by default when creating a new FlowrAnalyzer */
112
+ readonly defaultPlugins: ConfigPlugin<string>[];
109
113
  /** Configuration options for the REPL */
110
114
  readonly repl: {
111
115
  /** Whether to show quick stats in the REPL after each evaluation */
112
116
  quickStats: boolean;
113
117
  /** This instruments the dataflow processors to count how often each processor is called */
114
118
  dfProcessorHeat: boolean;
119
+ /** Plugins to load in REPL mode */
120
+ plugins: (ConfigPlugin<string> | 'flowr:default')[];
115
121
  };
116
122
  readonly project: {
117
123
  /** Whether to resolve unknown paths loaded by the r project disk when trying to source/analyze files */
@@ -226,6 +232,7 @@ export type EngineConfig = TreeSitterEngineConfig | RShellEngineConfig;
226
232
  export type KnownEngines = {
227
233
  [T in EngineConfig['type']]?: KnownParser;
228
234
  };
235
+ export declare const FlowrDefaultPlugins: string[];
229
236
  /**
230
237
  * Helper Object to work with {@link FlowrConfig}, provides the default config and the Joi schema for validation.
231
238
  */
package/config.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.FlowrConfig = exports.DropPathsOption = exports.InferWorkingDirectory = exports.VariableResolve = void 0;
6
+ exports.FlowrConfig = exports.FlowrDefaultPlugins = exports.DropPathsOption = exports.InferWorkingDirectory = exports.VariableResolve = void 0;
7
7
  const objects_1 = require("./util/objects");
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const fs_1 = __importDefault(require("fs"));
@@ -50,6 +50,21 @@ const defaultEngineConfigs = {
50
50
  'tree-sitter': { type: 'tree-sitter' },
51
51
  'r-shell': { type: 'r-shell' }
52
52
  };
53
+ exports.FlowrDefaultPlugins = [
54
+ 'file:description',
55
+ 'versions:description',
56
+ 'loading-order:description',
57
+ 'meta:description',
58
+ 'files:vignette',
59
+ 'files:test',
60
+ 'file:rmd',
61
+ 'file:qmd',
62
+ 'file:rnw',
63
+ 'file:ipynb',
64
+ 'file:namespace',
65
+ 'file:news',
66
+ 'file:license',
67
+ ];
53
68
  /**
54
69
  * Helper Object to work with {@link FlowrConfig}, provides the default config and the Joi schema for validation.
55
70
  */
@@ -70,9 +85,11 @@ exports.FlowrConfig = {
70
85
  }
71
86
  }
72
87
  },
88
+ defaultPlugins: exports.FlowrDefaultPlugins,
73
89
  repl: {
74
90
  quickStats: false,
75
- dfProcessorHeat: false
91
+ dfProcessorHeat: false,
92
+ plugins: ['flowr:default'],
76
93
  },
77
94
  project: {
78
95
  resolveUnknownPathsOnDisk: true
@@ -122,9 +139,11 @@ exports.FlowrConfig = {
122
139
  }).optional().description('Do you want to overwrite (parts) of the builtin definition?')
123
140
  }).optional().description('Semantics regarding how to handle the R environment.')
124
141
  }).description('Configure language semantics and how flowR handles them.'),
142
+ defaultPlugins: joi_1.default.array().items(joi_1.default.alternatives().try(joi_1.default.string(), joi_1.default.array().ordered(joi_1.default.string(), joi_1.default.array().items(joi_1.default.any())).length(2))).optional().description('The default plugins to load when creating a new instance of FlowrAnalyzer'),
125
143
  repl: joi_1.default.object({
126
144
  quickStats: joi_1.default.boolean().optional().description('Whether to show quick stats in the REPL after each evaluation.'),
127
- dfProcessorHeat: joi_1.default.boolean().optional().description('This instruments the dataflow processors to count how often each processor is called.')
145
+ dfProcessorHeat: joi_1.default.boolean().optional().description('This instruments the dataflow processors to count how often each processor is called.'),
146
+ plugins: joi_1.default.array().items(joi_1.default.alternatives().try(joi_1.default.string(), joi_1.default.array().ordered(joi_1.default.string(), joi_1.default.array().items(joi_1.default.any())).length(2))).optional().description('The plugins to load in REPL mode')
128
147
  }).description('Configuration options for the REPL.'),
129
148
  project: joi_1.default.object({
130
149
  resolveUnknownPathsOnDisk: joi_1.default.boolean().optional().description('Whether to resolve unknown paths loaded by the r project disk when trying to source/analyze files.')
@@ -572,4 +572,8 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, ControlFlow ex
572
572
  protected onPurrFormulaCall(_data: {
573
573
  call: DataflowGraphVertexFunctionCall;
574
574
  }): void;
575
+ protected getSourceAndTarget(call: DataflowGraphVertexFunctionCall): {
576
+ target: NodeId | undefined;
577
+ source: NodeId | undefined;
578
+ };
575
579
  }
@@ -200,22 +200,8 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
200
200
  return this.onVectorCall({ call });
201
201
  case built_in_proc_name_1.BuiltInProcName.Assignment:
202
202
  case built_in_proc_name_1.BuiltInProcName.AssignmentLike:
203
- case built_in_proc_name_1.BuiltInProcName.TableAssignment: {
204
- const outgoing = this.config.dfg.outgoingEdges(call.id);
205
- if (outgoing) {
206
- const target = outgoing.entries().filter(([, e]) => edge_1.DfEdge.includesType(e, edge_1.EdgeType.Returns)).toArray();
207
- if (target.length === 1) {
208
- const targetOut = this.config.dfg.outgoingEdges(target[0][0]);
209
- if (targetOut) {
210
- const source = targetOut.entries().filter(([t, e]) => edge_1.DfEdge.includesType(e, edge_1.EdgeType.DefinedBy) && t !== call.id).toArray();
211
- if (source.length === 1) {
212
- return this.onAssignmentCall({ call, target: target[0][0], source: source[0][0] });
213
- }
214
- }
215
- }
216
- }
217
- return this.onAssignmentCall({ call, target: undefined, source: undefined });
218
- }
203
+ case built_in_proc_name_1.BuiltInProcName.TableAssignment:
204
+ return this.onAssignmentCall({ call, ...this.getSourceAndTarget(call) });
219
205
  case built_in_proc_name_1.BuiltInProcName.SpecialBinOp:
220
206
  if (call.args.length !== 2) {
221
207
  return this.onSpecialBinaryOpCall({ call });
@@ -234,22 +220,8 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
234
220
  return this.onRepeatLoopCall({ call, body: call.args[0] });
235
221
  case built_in_proc_name_1.BuiltInProcName.WhileLoop:
236
222
  return this.onWhileLoopCall({ call, condition: call.args[0], body: call.args[1] });
237
- case built_in_proc_name_1.BuiltInProcName.Replacement: {
238
- const outgoing = this.config.dfg.outgoingEdges(call.id);
239
- if (outgoing) {
240
- const target = outgoing.entries().filter(([, e]) => edge_1.DfEdge.includesType(e, edge_1.EdgeType.Returns)).toArray();
241
- if (target.length === 1) {
242
- const targetOut = this.config.dfg.outgoingEdges(target[0][0]);
243
- if (targetOut) {
244
- const source = targetOut.entries().filter(([t, e]) => edge_1.DfEdge.includesType(e, edge_1.EdgeType.DefinedBy) && t !== call.id).toArray();
245
- if (source.length === 1) {
246
- return this.onReplacementCall({ call, target: target[0][0], source: source[0][0] });
247
- }
248
- }
249
- }
250
- }
251
- return this.onReplacementCall({ call, target: undefined, source: undefined });
252
- }
223
+ case built_in_proc_name_1.BuiltInProcName.Replacement:
224
+ return this.onReplacementCall({ call, ...this.getSourceAndTarget(call) });
253
225
  case built_in_proc_name_1.BuiltInProcName.Library:
254
226
  return this.onLibraryCall({ call });
255
227
  case built_in_proc_name_1.BuiltInProcName.Try:
@@ -646,6 +618,22 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
646
618
  * This event triggers for any purr formula as in `map(df, ~ .x + 1)`
647
619
  */
648
620
  onPurrFormulaCall(_data) { }
621
+ getSourceAndTarget(call) {
622
+ const outgoing = this.config.dfg.outgoingEdges(call.id);
623
+ if (outgoing !== undefined) {
624
+ const target = outgoing.entries().filter(([, e]) => edge_1.DfEdge.includesType(e, edge_1.EdgeType.Returns)).toArray();
625
+ if (target.length === 1) {
626
+ const targetOut = this.config.dfg.outgoingEdges(target[0][0]);
627
+ if (targetOut !== undefined) {
628
+ const source = targetOut.entries().filter(([t, e]) => edge_1.DfEdge.includesType(e, edge_1.EdgeType.DefinedBy) && t !== call.id).toArray();
629
+ if (source.length === 1) {
630
+ return { target: target[0][0], source: source[0][0] };
631
+ }
632
+ }
633
+ }
634
+ }
635
+ return { target: undefined, source: undefined };
636
+ }
649
637
  }
650
638
  exports.SemanticCfgGuidedVisitor = SemanticCfgGuidedVisitor;
651
639
  //# sourceMappingURL=semantic-cfg-guided-visitor.js.map
@@ -234,6 +234,16 @@ export declare const DefaultBuiltinConfig: [{
234
234
  readonly processor: BuiltInProcName.Eval;
235
235
  readonly config: {
236
236
  readonly includeFunctionCall: true;
237
+ readonly supportFunctionCall: false;
238
+ };
239
+ readonly assumePrimitive: true;
240
+ }, {
241
+ readonly type: "function";
242
+ readonly names: ["evalText"];
243
+ readonly processor: BuiltInProcName.Eval;
244
+ readonly config: {
245
+ readonly includeFunctionCall: true;
246
+ readonly supportFunctionCall: true;
237
247
  };
238
248
  readonly assumePrimitive: true;
239
249
  }, {
@@ -231,7 +231,8 @@ exports.DefaultBuiltinConfig = [
231
231
  '.Fortran': ['.NAME']
232
232
  }
233
233
  }, assumePrimitive: true },
234
- { type: 'function', names: ['eval'], processor: built_in_proc_name_1.BuiltInProcName.Eval, config: { includeFunctionCall: true }, assumePrimitive: true },
234
+ { type: 'function', names: ['eval'], processor: built_in_proc_name_1.BuiltInProcName.Eval, config: { includeFunctionCall: true, supportFunctionCall: false }, assumePrimitive: true },
235
+ { type: 'function', names: ['evalText'], processor: built_in_proc_name_1.BuiltInProcName.Eval, config: { includeFunctionCall: true, supportFunctionCall: true }, assumePrimitive: true },
235
236
  { type: 'function', names: ['cat'], processor: built_in_proc_name_1.BuiltInProcName.Default, config: { forceArgs: 'all', hasUnknownSideEffects: { type: 'link-to-last-call', callName: /^sink$/ } }, assumePrimitive: false },
236
237
  { type: 'function', names: ['switch'], processor: built_in_proc_name_1.BuiltInProcName.Default, config: { forceArgs: [true] }, assumePrimitive: false },
237
238
  { type: 'function', names: ['return'], processor: built_in_proc_name_1.BuiltInProcName.Default, config: { returnsNthArgument: 0, cfg: 1 /* ExitPointType.Return */, useAsProcessor: built_in_proc_name_1.BuiltInProcName.Return }, assumePrimitive: true },
@@ -10,4 +10,6 @@ import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/proce
10
10
  export declare function processEvalCall<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: {
11
11
  /** should this produce an explicit source function call in the graph? */
12
12
  includeFunctionCall?: boolean;
13
+ /** if selected processes evalText function call, else processes eval*/
14
+ supportFunctionCall?: boolean;
13
15
  }): DataflowInformation;
@@ -40,7 +40,7 @@ function processEvalCall(name, args, rootId, data, config) {
40
40
  (0, unknown_side_effect_1.handleUnknownSideEffect)(information.graph, information.environment, rootId);
41
41
  return information;
42
42
  }
43
- const code = resolveEvalToCode(evalArgument.value, data.environment, data.completeAst.idMap, data.ctx);
43
+ const code = resolveEvalToCode(evalArgument.value, config, data);
44
44
  if (code) {
45
45
  const idGenerator = (0, decorate_1.sourcedDeterministicCountingIdGenerator)(name.lexeme + '::' + rootId, name.location);
46
46
  data = {
@@ -73,35 +73,52 @@ function processEvalCall(name, args, rootId, data, config) {
73
73
  (0, unknown_side_effect_1.handleUnknownSideEffect)(information.graph, information.environment, rootId);
74
74
  return information;
75
75
  }
76
- function resolveEvalToCode(evalArgument, env, idMap, ctx) {
76
+ function resolveEvalToCode(evalArgument, config, data) {
77
+ const ctx = data.ctx;
78
+ const env = data.environment;
79
+ const idMap = data.completeAst.idMap;
77
80
  const val = evalArgument;
78
- if (val.type === type_1.RType.FunctionCall && val.named && val.functionName.content === 'parse') {
79
- const arg = val.arguments.find(v => v !== r_function_call_1.EmptyArgument && v.name?.content === 'text');
80
- const nArg = val.arguments.find(v => v !== r_function_call_1.EmptyArgument && v.name?.content === 'n');
81
- if (nArg !== undefined || arg === undefined || arg === r_function_call_1.EmptyArgument) {
82
- return undefined;
83
- }
84
- if (arg.value?.type === type_1.RType.String) {
85
- return [arg.value.content.str];
81
+ if (config.supportFunctionCall) {
82
+ if (val.type === type_1.RType.String) {
83
+ return [val.content.str];
86
84
  }
87
- else if (arg.value?.type === type_1.RType.Symbol) {
88
- const resolved = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(arg.value.info.id, { environment: env, idMap: idMap, resolve: ctx.config.solver.variables, ctx }));
85
+ else if (val.type === type_1.RType.Symbol) {
86
+ const resolved = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(val.info.id, { environment: env, idMap: idMap, resolve: ctx.config.solver.variables, ctx }));
89
87
  if (resolved) {
90
88
  return (0, string_constants_1.collectStrings)(resolved.elements);
91
89
  }
92
90
  }
93
- else if (arg.value?.type === type_1.RType.FunctionCall && arg.value.named && ['paste', 'paste0'].includes(identifier_1.Identifier.getName(arg.value.functionName.content))) {
94
- return handlePaste(ctx.config, arg.value.arguments, env, idMap, arg.value.functionName.content === 'paste' ? [' '] : [''], ctx);
95
- }
96
- return undefined;
97
- }
98
- else if (val.type === type_1.RType.Symbol) {
99
- // const resolved = resolveValueOfVariable(val.content, env);
100
- // see https://github.com/flowr-analysis/flowr/pull/1467
101
91
  return undefined;
102
92
  }
103
93
  else {
104
- return undefined;
94
+ if (val.type === type_1.RType.FunctionCall && val.named && val.functionName.content === 'parse') {
95
+ const arg = val.arguments.find(v => v !== r_function_call_1.EmptyArgument && v.name?.content === 'text');
96
+ const nArg = val.arguments.find(v => v !== r_function_call_1.EmptyArgument && v.name?.content === 'n');
97
+ if (nArg !== undefined || arg === undefined || arg === r_function_call_1.EmptyArgument) {
98
+ return undefined;
99
+ }
100
+ if (arg.value?.type === type_1.RType.String) {
101
+ return [arg.value.content.str];
102
+ }
103
+ else if (arg.value?.type === type_1.RType.Symbol) {
104
+ const resolved = (0, general_1.valueSetGuard)((0, alias_tracking_1.resolveIdToValue)(arg.value.info.id, { environment: env, idMap: idMap, resolve: ctx.config.solver.variables, ctx }));
105
+ if (resolved) {
106
+ return (0, string_constants_1.collectStrings)(resolved.elements);
107
+ }
108
+ }
109
+ else if (arg.value?.type === type_1.RType.FunctionCall && arg.value.named && ['paste', 'paste0'].includes(identifier_1.Identifier.getName(arg.value.functionName.content))) {
110
+ return handlePaste(ctx.config, arg.value.arguments, env, idMap, arg.value.functionName.content === 'paste' ? [' '] : [''], ctx);
111
+ }
112
+ return undefined;
113
+ }
114
+ else if (val.type === type_1.RType.Symbol) {
115
+ // const resolved = resolveValueOfVariable(val.content, env);
116
+ // see https://github.com/flowr-analysis/flowr/pull/1467
117
+ return undefined;
118
+ }
119
+ else {
120
+ return undefined;
121
+ }
105
122
  }
106
123
  }
107
124
  function getAsString(config, val, env, idMap, ctx) {
@@ -17,9 +17,20 @@ const doc_issue_1 = require("./doc-util/doc-issue");
17
17
  const strings_1 = require("../util/text/strings");
18
18
  const doc_maker_1 = require("./wiki-mk/doc-maker");
19
19
  const PublicationsMain = [
20
+ {
21
+ header: 'Supporting the Comprehension of Data Analysis Scripts (FSE \'25, Tool)',
22
+ description: 'This refers to an updated tool demonstration of the framework. Preprint available at <a href="https://doi.org/10.48550/arXiv.2604.15963" target="_blank">arXiv:2604.15963</a>.',
23
+ doi: 'https://doi.org/10.1145/3803437.3806402',
24
+ bibtex: String.raw `@article{10.1145/3803437.3806402,
25
+ author = {Sihler, Florian and Gerstl, Oliver and Pfrenger, Lars and Schubert, Julian and Tichy, Matthias},
26
+ title = {Supporting the Comprehension of Data Analysis Scripts},
27
+ year = {2026},
28
+ doi = {10.1145/3803437.3806402}
29
+ }`
30
+ },
20
31
  {
21
32
  header: 'Statically Analyzing the Dataflow of R Programs (OOPSLA \'25)',
22
- description: 'Please cite this paper if you are using flowR in your research.',
33
+ description: '**Please cite this paper if you are using flowR in your research.**',
23
34
  doi: 'https://doi.org/10.1145/3763087',
24
35
  bibtex: String.raw `@article{10.1145/3763087,
25
36
  author = {Sihler, Florian and Tichy, Matthias},
@@ -42,7 +53,7 @@ const PublicationsMain = [
42
53
  },
43
54
  {
44
55
  header: 'flowR: A Static Program Slicer for R (ASE \'24, Tool)',
45
- description: `This refers to the tool-demonstration of the <a href="${doc_files_1.FlowrVsCode}">VS Code Extension</a>.`,
56
+ description: `This refers to the tool-demonstration of the <a href="${doc_files_1.FlowrVsCode}" target="_blank">VS Code Extension</a>.`,
46
57
  doi: 'https://doi.org/10.1145/3691620.3695359',
47
58
  bibtex: `@inproceedings{DBLP:conf/kbse/SihlerT24,
48
59
  author = {Florian Sihler and
@@ -1,5 +1,4 @@
1
- import type { DocMakerArgs } from './wiki-mk/doc-maker';
2
- import { DocMaker } from './wiki-mk/doc-maker';
1
+ import { DocMaker, type DocMakerArgs } from './wiki-mk/doc-maker';
3
2
  export declare class WikiAbsint extends DocMaker<'wiki/Abstract Interpretation.md'> {
4
3
  constructor();
5
4
  protected text({ ctx }: DocMakerArgs): Promise<string>;