@eagleoutice/flowr 2.6.0 → 2.6.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 (71) hide show
  1. package/README.md +36 -40
  2. package/abstract-interpretation/data-frame/absint-visitor.d.ts +1 -1
  3. package/abstract-interpretation/data-frame/absint-visitor.js +1 -1
  4. package/cli/flowr.js +8 -4
  5. package/cli/repl/commands/repl-cfg.js +4 -4
  6. package/cli/repl/commands/repl-commands.js +2 -2
  7. package/cli/repl/commands/repl-dataflow.js +4 -4
  8. package/cli/repl/commands/repl-execute.d.ts +1 -1
  9. package/cli/repl/commands/repl-execute.js +8 -8
  10. package/cli/repl/commands/repl-lineage.d.ts +2 -2
  11. package/cli/repl/commands/repl-lineage.js +11 -12
  12. package/cli/repl/commands/repl-main.d.ts +4 -7
  13. package/cli/repl/commands/repl-normalize.js +2 -2
  14. package/cli/repl/commands/repl-parse.js +3 -2
  15. package/cli/repl/commands/repl-query.js +3 -3
  16. package/cli/repl/commands/repl-quit.js +1 -1
  17. package/cli/repl/commands/repl-version.d.ts +1 -16
  18. package/cli/repl/commands/repl-version.js +2 -19
  19. package/cli/repl/core.d.ts +9 -9
  20. package/cli/repl/core.js +14 -20
  21. package/cli/repl/print-version.js +2 -2
  22. package/cli/repl/server/connection.js +6 -2
  23. package/cli/repl/server/messages/message-hello.d.ts +1 -1
  24. package/cli/repl/server/server.js +2 -2
  25. package/core/steps/all/core/20-dataflow.d.ts +3 -1
  26. package/core/steps/pipeline/default-pipelines.d.ts +66 -50
  27. package/dataflow/environments/default-builtin-config.js +8 -0
  28. package/dataflow/eval/resolve/alias-tracking.js +2 -0
  29. package/dataflow/eval/resolve/resolve.js +3 -0
  30. package/dataflow/eval/values/r-value.d.ts +4 -1
  31. package/dataflow/eval/values/r-value.js +2 -0
  32. package/dataflow/extractor.d.ts +4 -1
  33. package/dataflow/extractor.js +7 -5
  34. package/dataflow/fn/higher-order-function.d.ts +9 -0
  35. package/dataflow/fn/higher-order-function.js +75 -0
  36. package/documentation/doc-util/doc-repl.js +5 -2
  37. package/documentation/print-dataflow-graph-wiki.js +2 -2
  38. package/documentation/print-query-wiki.js +20 -0
  39. package/documentation/print-readme.js +1 -1
  40. package/package.json +1 -1
  41. package/project/cache/flowr-analyzer-cache.d.ts +6 -5
  42. package/project/cache/flowr-analyzer-cache.js +21 -13
  43. package/project/cfg-kind.d.ts +17 -0
  44. package/project/cfg-kind.js +22 -0
  45. package/project/context/abstract-flowr-analyzer-context.d.ts +4 -0
  46. package/project/context/flowr-analyzer-context.d.ts +6 -0
  47. package/project/context/flowr-analyzer-context.js +11 -0
  48. package/project/context/flowr-analyzer-dependencies-context.d.ts +1 -0
  49. package/project/context/flowr-analyzer-dependencies-context.js +4 -0
  50. package/project/context/flowr-analyzer-files-context.d.ts +1 -0
  51. package/project/context/flowr-analyzer-files-context.js +4 -0
  52. package/project/context/flowr-analyzer-loading-order-context.d.ts +1 -0
  53. package/project/context/flowr-analyzer-loading-order-context.js +6 -0
  54. package/project/flowr-analyzer.d.ts +19 -18
  55. package/project/flowr-analyzer.js +15 -8
  56. package/queries/catalog/call-context-query/call-context-query-executor.js +2 -1
  57. package/queries/catalog/config-query/config-query-format.d.ts +1 -1
  58. package/queries/catalog/control-flow-query/control-flow-query-executor.js +2 -1
  59. package/queries/catalog/df-shape-query/df-shape-query-executor.js +1 -1
  60. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.d.ts +3 -0
  61. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +45 -0
  62. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +22 -0
  63. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.js +32 -0
  64. package/queries/query.d.ts +10 -2
  65. package/queries/query.js +2 -0
  66. package/r-bridge/parser.d.ts +7 -0
  67. package/search/search-executor/search-enrichers.js +2 -1
  68. package/util/r-value.d.ts +1 -1
  69. package/util/r-value.js +2 -0
  70. package/util/version.d.ts +17 -0
  71. package/util/version.js +28 -1
@@ -1,30 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.versionCommand = void 0;
4
- exports.retrieveVersionInformation = retrieveVersionInformation;
5
- exports.printVersionInformation = printVersionInformation;
6
4
  const version_1 = require("../../../util/version");
7
- const assert_1 = require("../../../util/assert");
8
- const versionRegex = /^\d+\.\d+\.\d+/m;
9
- async function retrieveVersionInformation(parser) {
10
- const flowr = (0, version_1.flowrVersion)().toString();
11
- const r = await parser.rVersion();
12
- (0, assert_1.guard)(versionRegex.test(flowr), `flowR version ${flowr} does not match the expected format!`);
13
- (0, assert_1.guard)(r === 'unknown' || r === 'none' || versionRegex.test(r), `R version ${r} does not match the expected format!`);
14
- return { flowr: flowr, r: r, engine: parser.name };
15
- }
16
- async function printVersionInformation(output, parser) {
17
- const { flowr, r, engine } = await retrieveVersionInformation(parser);
18
- output.stdout(`Engine: ${engine}`);
19
- output.stdout(` flowR: ${flowr}`);
20
- output.stdout(` R: ${r}`);
21
- }
22
5
  exports.versionCommand = {
23
6
  description: 'Prints the version of flowR as well as the current version of R',
24
- usesAnalyzer: false,
7
+ isCodeCommand: false,
25
8
  aliases: [],
26
9
  usageExample: ':version',
27
10
  script: false,
28
- fn: ({ output, parser }) => printVersionInformation(output, parser)
11
+ fn: ({ output, analyzer }) => (0, version_1.printVersionInformation)(output, analyzer)
29
12
  };
30
13
  //# sourceMappingURL=repl-version.js.map
@@ -1,33 +1,34 @@
1
1
  import * as readline from 'readline';
2
2
  import type { ReplOutput } from './commands/repl-main';
3
3
  import type { MergeableRecord } from '../../util/objects';
4
- import type { KnownParser } from '../../r-bridge/parser';
5
4
  import type { FlowrConfigOptions } from '../../config';
5
+ import type { FlowrAnalyzer } from '../../project/flowr-analyzer';
6
6
  /**
7
7
  * Used by the repl to provide automatic completions for a given (partial) input line
8
8
  */
9
9
  export declare function replCompleter(line: string, config: FlowrConfigOptions): [string[], string];
10
10
  export declare function makeDefaultReplReadline(config: FlowrConfigOptions): readline.ReadLineOptions;
11
11
  export declare function handleString(code: string): {
12
- input: string;
12
+ input: string | undefined;
13
13
  remaining: never[];
14
14
  };
15
15
  /**
16
16
  * This function interprets the given `expr` as a REPL command (see {@link repl} for more on the semantics).
17
17
  *
18
- * @param config - flowr Config
18
+ * @param analyzer - The flowR analyzer to use.
19
19
  * @param output - Defines two methods that every function in the repl uses to output its data.
20
20
  * @param expr - The expression to process.
21
- * @param parser - The {@link RShell} or {@link TreeSitterExecutor} to use (see {@link repl}).
22
21
  * @param allowRSessionAccess - If true, allows the execution of arbitrary R code.
23
22
  */
24
- export declare function replProcessAnswer(config: FlowrConfigOptions, output: ReplOutput, expr: string, parser: KnownParser, allowRSessionAccess: boolean): Promise<void>;
23
+ export declare function replProcessAnswer(analyzer: FlowrAnalyzer, output: ReplOutput, expr: string, allowRSessionAccess: boolean): Promise<void>;
25
24
  /**
26
25
  * Options for the {@link repl} function.
27
26
  */
28
27
  export interface FlowrReplOptions extends MergeableRecord {
29
- /** The shell to use, if you do not pass one it will automatically create a new one with the `revive` option set to 'always'. */
30
- readonly parser?: KnownParser;
28
+ /**
29
+ * The flowR analyzer to use.
30
+ */
31
+ readonly analyzer: FlowrAnalyzer;
31
32
  /**
32
33
  * A potentially customized readline interface to be used for the repl to *read* from the user, we write the output with the {@link ReplOutput | `output` } interface.
33
34
  * If you want to provide a custom one but use the same `completer`, refer to {@link replCompleter}.
@@ -48,10 +49,9 @@ export interface FlowrReplOptions extends MergeableRecord {
48
49
  * - Starting with anything else, indicating default R code to be directly executed. If you kill the underlying shell, that is on you! </li>
49
50
  *
50
51
  * @param options - The options for the repl. See {@link FlowrReplOptions} for more information.
51
- * @param config - The flowr config
52
52
  *
53
53
  * For the execution, this function makes use of {@link replProcessAnswer}.
54
54
  *
55
55
  */
56
- export declare function repl(config: FlowrConfigOptions, { parser, rl, output, historyFile, allowRSessionAccess }: FlowrReplOptions): Promise<void>;
56
+ export declare function repl({ analyzer, rl, output, historyFile, allowRSessionAccess }: FlowrReplOptions): Promise<void>;
57
57
  export declare function loadReplHistory(historyFile: string): string[] | undefined;
package/cli/repl/core.js CHANGED
@@ -58,11 +58,8 @@ const repl_commands_1 = require("./commands/repl-commands");
58
58
  const scripts_info_1 = require("../common/scripts-info");
59
59
  const retriever_1 = require("../../r-bridge/retriever");
60
60
  const repl_main_1 = require("./commands/repl-main");
61
- const shell_1 = require("../../r-bridge/shell");
62
61
  const log_1 = require("../../util/log");
63
- const config_1 = require("../../config");
64
62
  const query_1 = require("../../queries/query");
65
- const flowr_analyzer_builder_1 = require("../../project/flowr-analyzer-builder");
66
63
  let _replCompleterKeywords = undefined;
67
64
  function replCompleterKeywords() {
68
65
  if (_replCompleterKeywords === undefined) {
@@ -133,11 +130,11 @@ function makeDefaultReplReadline(config) {
133
130
  }
134
131
  function handleString(code) {
135
132
  return {
136
- input: code.startsWith('"') ? JSON.parse(code) : code,
133
+ input: code.length == 0 ? undefined : code.startsWith('"') ? JSON.parse(code) : code,
137
134
  remaining: []
138
135
  };
139
136
  }
140
- async function replProcessStatement(output, statement, parser, allowRSessionAccess, config) {
137
+ async function replProcessStatement(output, statement, analyzer, allowRSessionAccess) {
141
138
  if (statement.startsWith(':')) {
142
139
  const command = statement.slice(1).split(' ')[0].toLowerCase();
143
140
  const processor = (0, repl_commands_1.getCommand)(command);
@@ -145,17 +142,16 @@ async function replProcessStatement(output, statement, parser, allowRSessionAcce
145
142
  if (processor) {
146
143
  try {
147
144
  const remainingLine = statement.slice(command.length + 2).trim();
148
- if (processor.usesAnalyzer) {
145
+ if (processor.isCodeCommand) {
149
146
  const args = processor.argsParser(remainingLine);
150
- const request = (0, retriever_1.requestFromInput)(args.input);
151
- const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder(request)
152
- .setConfig(config)
153
- .setParser(parser)
154
- .build();
147
+ if (args.input) {
148
+ analyzer.reset();
149
+ analyzer.context().addRequest((0, retriever_1.requestFromInput)(args.input));
150
+ }
155
151
  await processor.fn({ output, analyzer, remainingArgs: args.remaining });
156
152
  }
157
153
  else {
158
- await processor.fn({ output, parser, remainingLine, allowRSessionAccess, config });
154
+ await processor.fn({ output, analyzer, remainingLine, allowRSessionAccess });
159
155
  }
160
156
  }
161
157
  catch (e) {
@@ -170,22 +166,21 @@ async function replProcessStatement(output, statement, parser, allowRSessionAcce
170
166
  }
171
167
  }
172
168
  else {
173
- await (0, repl_execute_1.tryExecuteRShellCommand)({ output, parser, remainingLine: statement, allowRSessionAccess, config });
169
+ await (0, repl_execute_1.tryExecuteRShellCommand)({ output, analyzer, remainingLine: statement, allowRSessionAccess });
174
170
  }
175
171
  }
176
172
  /**
177
173
  * This function interprets the given `expr` as a REPL command (see {@link repl} for more on the semantics).
178
174
  *
179
- * @param config - flowr Config
175
+ * @param analyzer - The flowR analyzer to use.
180
176
  * @param output - Defines two methods that every function in the repl uses to output its data.
181
177
  * @param expr - The expression to process.
182
- * @param parser - The {@link RShell} or {@link TreeSitterExecutor} to use (see {@link repl}).
183
178
  * @param allowRSessionAccess - If true, allows the execution of arbitrary R code.
184
179
  */
185
- async function replProcessAnswer(config, output, expr, parser, allowRSessionAccess) {
180
+ async function replProcessAnswer(analyzer, output, expr, allowRSessionAccess) {
186
181
  const statements = (0, args_1.splitAtEscapeSensitive)(expr, false, ';');
187
182
  for (const statement of statements) {
188
- await replProcessStatement(output, statement, parser, allowRSessionAccess, config);
183
+ await replProcessStatement(output, statement, analyzer, allowRSessionAccess);
189
184
  }
190
185
  }
191
186
  /**
@@ -196,12 +191,11 @@ async function replProcessAnswer(config, output, expr, parser, allowRSessionAcce
196
191
  * - Starting with anything else, indicating default R code to be directly executed. If you kill the underlying shell, that is on you! </li>
197
192
  *
198
193
  * @param options - The options for the repl. See {@link FlowrReplOptions} for more information.
199
- * @param config - The flowr config
200
194
  *
201
195
  * For the execution, this function makes use of {@link replProcessAnswer}.
202
196
  *
203
197
  */
204
- async function repl(config, { parser = new shell_1.RShell((0, config_1.getEngineConfig)(config, 'r-shell'), { revive: 2 /* RShellReviveOptions.Always */ }), rl = readline.createInterface(makeDefaultReplReadline(config)), output = repl_main_1.standardReplOutput, historyFile = defaultHistoryFile, allowRSessionAccess = false }) {
198
+ async function repl({ analyzer, rl = readline.createInterface(makeDefaultReplReadline(analyzer.flowrConfig)), output = repl_main_1.standardReplOutput, historyFile = defaultHistoryFile, allowRSessionAccess = false }) {
205
199
  if (historyFile) {
206
200
  rl.on('history', h => fs_1.default.writeFileSync(historyFile, h.join('\n'), { encoding: 'utf-8' }));
207
201
  }
@@ -210,7 +204,7 @@ async function repl(config, { parser = new shell_1.RShell((0, config_1.getEngine
210
204
  await new Promise((resolve, reject) => {
211
205
  rl.question((0, prompt_1.prompt)(), answer => {
212
206
  rl.pause();
213
- replProcessAnswer(config, output, answer, parser, allowRSessionAccess).then(() => {
207
+ replProcessAnswer(analyzer, output, answer, allowRSessionAccess).then(() => {
214
208
  rl.resume();
215
209
  resolve();
216
210
  }).catch(reject);
@@ -2,9 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.versionReplString = versionReplString;
4
4
  exports.printVersionRepl = printVersionRepl;
5
- const repl_version_1 = require("./commands/repl-version");
5
+ const version_1 = require("../../util/version");
6
6
  async function versionReplString(parser) {
7
- const version = await (0, repl_version_1.retrieveVersionInformation)(parser);
7
+ const version = await (0, version_1.retrieveVersionInformation)(parser);
8
8
  const rVersion = version.r === 'none' ? '' : version.r === 'unknown' ? ', R version unknown' : `, R v${version.r}`;
9
9
  const treeSitterVer = parser.name === 'tree-sitter' ? `, R grammar v${parser.treeSitterVersion()}` : '';
10
10
  return `flowR repl using flowR v${version.flowr}${rVersion}${treeSitterVer} (${version.engine} engine)`;
@@ -287,11 +287,15 @@ class FlowRServerConnection {
287
287
  stream
288
288
  });
289
289
  };
290
- void (0, core_1.replProcessAnswer)(this.config, {
290
+ const analyzer = new flowr_analyzer_builder_1.FlowrAnalyzerBuilder()
291
+ .setConfig(this.config)
292
+ .setParser(this.parser)
293
+ .buildSync();
294
+ void (0, core_1.replProcessAnswer)(analyzer, {
291
295
  formatter: request.ansi ? ansi_1.ansiFormatter : ansi_1.voidFormatter,
292
296
  stdout: msg => out('stdout', msg),
293
297
  stderr: msg => out('stderr', msg)
294
- }, request.expression, this.parser, this.allowRSessionAccess).then(() => {
298
+ }, request.expression, this.allowRSessionAccess).then(() => {
295
299
  (0, send_1.sendMessage)(this.socket, {
296
300
  type: 'end-repl-execution',
297
301
  id: request.id
@@ -1,5 +1,5 @@
1
- import type { VersionInformation } from '../../commands/repl-version';
2
1
  import type { IdMessageBase, MessageDefinition } from './all-messages';
2
+ import type { VersionInformation } from '../../../../util/version';
3
3
  /**
4
4
  * The hello message is automatically sent by the sever upon connection.
5
5
  */
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FlowRServer = exports.serverLog = void 0;
4
- const repl_version_1 = require("../commands/repl-version");
5
4
  const connection_1 = require("./connection");
6
5
  const send_1 = require("./send");
7
6
  const net_1 = require("./net");
8
7
  const log_1 = require("../../../util/log");
8
+ const version_1 = require("../../../util/version");
9
9
  // we detach from the main logger so that it can have its own switch
10
10
  exports.serverLog = new log_1.FlowrLogger({ name: 'server' });
11
11
  /**
@@ -32,7 +32,7 @@ class FlowRServer {
32
32
  this.config = config;
33
33
  }
34
34
  async start(port) {
35
- this.versionInformation = await (0, repl_version_1.retrieveVersionInformation)(this.engines[this.defaultEngine]);
35
+ this.versionInformation = await (0, version_1.retrieveVersionInformation)(this.engines[this.defaultEngine]);
36
36
  this.server.start(port);
37
37
  exports.serverLog.info(`Server listening on port ${port}`);
38
38
  }
@@ -10,7 +10,9 @@ declare function processor(results: {
10
10
  }, input: {
11
11
  request?: RParseRequests;
12
12
  parser?: Parser<KnownParserType>;
13
- }, config: FlowrConfigOptions): import("../../../../dataflow/info").DataflowInformation;
13
+ }, config: FlowrConfigOptions): import("../../../../dataflow/info").DataflowInformation & {
14
+ cfgQuick: import("../../../../control-flow/control-flow-graph").ControlFlowInformation | undefined;
15
+ };
14
16
  export declare const STATIC_DATAFLOW: {
15
17
  readonly humanReadableName: "dataflow";
16
18
  readonly processor: typeof processor;
@@ -8,6 +8,20 @@ import type { RShell } from '../../../r-bridge/shell';
8
8
  import type { TreeSitterExecutor } from '../../../r-bridge/lang-4.x/tree-sitter/tree-sitter-executor';
9
9
  import type { FlowrConfigOptions } from '../../../config';
10
10
  export declare const DEFAULT_SLICING_PIPELINE: import("./pipeline").Pipeline<{
11
+ readonly name: "slice";
12
+ readonly humanReadableName: "static slice";
13
+ readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
14
+ readonly processor: (results: {
15
+ dataflow?: import("../../../dataflow/info").DataflowInformation;
16
+ normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
17
+ }, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, _config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
18
+ readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
19
+ readonly printer: {
20
+ readonly 0: typeof import("../../print/print").internalPrinter;
21
+ };
22
+ readonly dependencies: readonly ["dataflow"];
23
+ readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
24
+ } | {
11
25
  readonly name: "parse";
12
26
  readonly humanReadableName: "parse with R shell";
13
27
  readonly description: "Parse the given R code into an AST";
@@ -40,20 +54,6 @@ export declare const DEFAULT_SLICING_PIPELINE: import("./pipeline").Pipeline<{
40
54
  };
41
55
  readonly dependencies: readonly ["parse"];
42
56
  readonly requiredInput: import("../all/core/10-normalize").NormalizeRequiredInput;
43
- } | {
44
- readonly name: "slice";
45
- readonly humanReadableName: "static slice";
46
- readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
47
- readonly processor: (results: {
48
- dataflow?: import("../../../dataflow/info").DataflowInformation;
49
- normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
50
- }, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, _config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
51
- readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
52
- readonly printer: {
53
- readonly 0: typeof import("../../print/print").internalPrinter;
54
- };
55
- readonly dependencies: readonly ["dataflow"];
56
- readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
57
57
  } | {
58
58
  readonly humanReadableName: "dataflow";
59
59
  readonly processor: (results: {
@@ -61,7 +61,9 @@ export declare const DEFAULT_SLICING_PIPELINE: import("./pipeline").Pipeline<{
61
61
  }, input: {
62
62
  request?: import("../../../r-bridge/retriever").RParseRequests;
63
63
  parser?: Parser<import("../../../r-bridge/parser").KnownParserType>;
64
- }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation;
64
+ }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation & {
65
+ cfgQuick: import("../../../control-flow/control-flow-graph").ControlFlowInformation | undefined;
66
+ };
65
67
  readonly requiredInput: {};
66
68
  readonly name: "dataflow";
67
69
  readonly description: "Construct the dataflow graph";
@@ -90,6 +92,20 @@ export declare const DEFAULT_SLICING_PIPELINE: import("./pipeline").Pipeline<{
90
92
  readonly requiredInput: import("../all/static-slicing/10-reconstruct").ReconstructRequiredInput;
91
93
  }>;
92
94
  export declare const DEFAULT_SLICE_AND_RECONSTRUCT_PIPELINE: import("./pipeline").Pipeline<{
95
+ readonly name: "slice";
96
+ readonly humanReadableName: "static slice";
97
+ readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
98
+ readonly processor: (results: {
99
+ dataflow?: import("../../../dataflow/info").DataflowInformation;
100
+ normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
101
+ }, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, _config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
102
+ readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
103
+ readonly printer: {
104
+ readonly 0: typeof import("../../print/print").internalPrinter;
105
+ };
106
+ readonly dependencies: readonly ["dataflow"];
107
+ readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
108
+ } | {
93
109
  readonly name: "parse";
94
110
  readonly humanReadableName: "parse with R shell";
95
111
  readonly description: "Parse the given R code into an AST";
@@ -122,20 +138,6 @@ export declare const DEFAULT_SLICE_AND_RECONSTRUCT_PIPELINE: import("./pipeline"
122
138
  };
123
139
  readonly dependencies: readonly ["parse"];
124
140
  readonly requiredInput: import("../all/core/10-normalize").NormalizeRequiredInput;
125
- } | {
126
- readonly name: "slice";
127
- readonly humanReadableName: "static slice";
128
- readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
129
- readonly processor: (results: {
130
- dataflow?: import("../../../dataflow/info").DataflowInformation;
131
- normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
132
- }, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, _config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
133
- readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
134
- readonly printer: {
135
- readonly 0: typeof import("../../print/print").internalPrinter;
136
- };
137
- readonly dependencies: readonly ["dataflow"];
138
- readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
139
141
  } | {
140
142
  readonly humanReadableName: "dataflow";
141
143
  readonly processor: (results: {
@@ -143,7 +145,9 @@ export declare const DEFAULT_SLICE_AND_RECONSTRUCT_PIPELINE: import("./pipeline"
143
145
  }, input: {
144
146
  request?: import("../../../r-bridge/retriever").RParseRequests;
145
147
  parser?: Parser<import("../../../r-bridge/parser").KnownParserType>;
146
- }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation;
148
+ }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation & {
149
+ cfgQuick: import("../../../control-flow/control-flow-graph").ControlFlowInformation | undefined;
150
+ };
147
151
  readonly requiredInput: {};
148
152
  readonly name: "dataflow";
149
153
  readonly description: "Construct the dataflow graph";
@@ -172,6 +176,20 @@ export declare const DEFAULT_SLICE_AND_RECONSTRUCT_PIPELINE: import("./pipeline"
172
176
  readonly requiredInput: import("../all/static-slicing/10-reconstruct").ReconstructRequiredInput;
173
177
  }>;
174
178
  export declare const DEFAULT_SLICE_WITHOUT_RECONSTRUCT_PIPELINE: import("./pipeline").Pipeline<{
179
+ readonly name: "slice";
180
+ readonly humanReadableName: "static slice";
181
+ readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
182
+ readonly processor: (results: {
183
+ dataflow?: import("../../../dataflow/info").DataflowInformation;
184
+ normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
185
+ }, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, _config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
186
+ readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
187
+ readonly printer: {
188
+ readonly 0: typeof import("../../print/print").internalPrinter;
189
+ };
190
+ readonly dependencies: readonly ["dataflow"];
191
+ readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
192
+ } | {
175
193
  readonly name: "parse";
176
194
  readonly humanReadableName: "parse with R shell";
177
195
  readonly description: "Parse the given R code into an AST";
@@ -204,20 +222,6 @@ export declare const DEFAULT_SLICE_WITHOUT_RECONSTRUCT_PIPELINE: import("./pipel
204
222
  };
205
223
  readonly dependencies: readonly ["parse"];
206
224
  readonly requiredInput: import("../all/core/10-normalize").NormalizeRequiredInput;
207
- } | {
208
- readonly name: "slice";
209
- readonly humanReadableName: "static slice";
210
- readonly description: "Calculate the actual static slice from the dataflow graph and the given slicing criteria";
211
- readonly processor: (results: {
212
- dataflow?: import("../../../dataflow/info").DataflowInformation;
213
- normalize?: import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
214
- }, input: Partial<import("../all/static-slicing/00-slice").SliceRequiredInput>, _config: FlowrConfigOptions) => Readonly<import("../../../slicing/static/slicer-types").SliceResult>;
215
- readonly executed: import("../pipeline-step").PipelineStepStage.OncePerRequest;
216
- readonly printer: {
217
- readonly 0: typeof import("../../print/print").internalPrinter;
218
- };
219
- readonly dependencies: readonly ["dataflow"];
220
- readonly requiredInput: import("../all/static-slicing/00-slice").SliceRequiredInput;
221
225
  } | {
222
226
  readonly humanReadableName: "dataflow";
223
227
  readonly processor: (results: {
@@ -225,7 +229,9 @@ export declare const DEFAULT_SLICE_WITHOUT_RECONSTRUCT_PIPELINE: import("./pipel
225
229
  }, input: {
226
230
  request?: import("../../../r-bridge/retriever").RParseRequests;
227
231
  parser?: Parser<import("../../../r-bridge/parser").KnownParserType>;
228
- }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation;
232
+ }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation & {
233
+ cfgQuick: import("../../../control-flow/control-flow-graph").ControlFlowInformation | undefined;
234
+ };
229
235
  readonly requiredInput: {};
230
236
  readonly name: "dataflow";
231
237
  readonly description: "Construct the dataflow graph";
@@ -260,7 +266,9 @@ export declare const TREE_SITTER_SLICING_PIPELINE: import("./pipeline").Pipeline
260
266
  }, input: {
261
267
  request?: import("../../../r-bridge/retriever").RParseRequests;
262
268
  parser?: Parser<import("../../../r-bridge/parser").KnownParserType>;
263
- }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation;
269
+ }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation & {
270
+ cfgQuick: import("../../../control-flow/control-flow-graph").ControlFlowInformation | undefined;
271
+ };
264
272
  readonly requiredInput: {};
265
273
  readonly name: "dataflow";
266
274
  readonly description: "Construct the dataflow graph";
@@ -341,7 +349,9 @@ export declare const TREE_SITTER_SLICE_AND_RECONSTRUCT_PIPELINE: import("./pipel
341
349
  }, input: {
342
350
  request?: import("../../../r-bridge/retriever").RParseRequests;
343
351
  parser?: Parser<import("../../../r-bridge/parser").KnownParserType>;
344
- }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation;
352
+ }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation & {
353
+ cfgQuick: import("../../../control-flow/control-flow-graph").ControlFlowInformation | undefined;
354
+ };
345
355
  readonly requiredInput: {};
346
356
  readonly name: "dataflow";
347
357
  readonly description: "Construct the dataflow graph";
@@ -422,7 +432,9 @@ export declare const TREE_SITTER_SLICE_WITHOUT_RECONSTRUCT_PIPELINE: import("./p
422
432
  }, input: {
423
433
  request?: import("../../../r-bridge/retriever").RParseRequests;
424
434
  parser?: Parser<import("../../../r-bridge/parser").KnownParserType>;
425
- }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation;
435
+ }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation & {
436
+ cfgQuick: import("../../../control-flow/control-flow-graph").ControlFlowInformation | undefined;
437
+ };
426
438
  readonly requiredInput: {};
427
439
  readonly name: "dataflow";
428
440
  readonly description: "Construct the dataflow graph";
@@ -513,7 +525,9 @@ export declare const DEFAULT_DATAFLOW_PIPELINE: import("./pipeline").Pipeline<{
513
525
  }, input: {
514
526
  request?: import("../../../r-bridge/retriever").RParseRequests;
515
527
  parser?: Parser<import("../../../r-bridge/parser").KnownParserType>;
516
- }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation;
528
+ }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation & {
529
+ cfgQuick: import("../../../control-flow/control-flow-graph").ControlFlowInformation | undefined;
530
+ };
517
531
  readonly requiredInput: {};
518
532
  readonly name: "dataflow";
519
533
  readonly description: "Construct the dataflow graph";
@@ -534,7 +548,9 @@ export declare const TREE_SITTER_DATAFLOW_PIPELINE: import("./pipeline").Pipelin
534
548
  }, input: {
535
549
  request?: import("../../../r-bridge/retriever").RParseRequests;
536
550
  parser?: Parser<import("../../../r-bridge/parser").KnownParserType>;
537
- }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation;
551
+ }, config: FlowrConfigOptions) => import("../../../dataflow/info").DataflowInformation & {
552
+ cfgQuick: import("../../../control-flow/control-flow-graph").ControlFlowInformation | undefined;
553
+ };
538
554
  readonly requiredInput: {};
539
555
  readonly name: "dataflow";
540
556
  readonly description: "Construct the dataflow graph";
@@ -212,6 +212,14 @@ exports.DefaultBuiltinConfig = [
212
212
  { type: 'function', names: ['('], processor: 'builtin:default', config: { returnsNthArgument: 0 }, assumePrimitive: true },
213
213
  { type: 'function', names: ['load', 'load_all', 'setwd', 'set.seed'], processor: 'builtin:default', config: { hasUnknownSideEffects: true, forceArgs: [true] }, assumePrimitive: false },
214
214
  { type: 'function', names: ['body', 'formals', 'environment'], processor: 'builtin:default', config: { hasUnknownSideEffects: true, forceArgs: [true] }, assumePrimitive: true },
215
+ { type: 'function', names: ['.Call', '.External', '.C', '.Fortran'], processor: 'builtin:default', config: { hasUnknownSideEffects: true, forceArgs: [true],
216
+ treatAsFnCall: {
217
+ '.Call': ['.NAME'],
218
+ '.External': ['.NAME'],
219
+ '.C': ['.NAME'],
220
+ '.Fortran': ['.NAME']
221
+ }
222
+ }, assumePrimitive: true },
215
223
  { type: 'function', names: ['eval'], processor: 'builtin:eval', config: { includeFunctionCall: true }, assumePrimitive: true },
216
224
  { type: 'function', names: ['cat'], processor: 'builtin:default', config: { forceArgs: 'all', hasUnknownSideEffects: { type: 'link-to-last-call', callName: /^sink$/ } }, assumePrimitive: false },
217
225
  { type: 'function', names: ['switch'], processor: 'builtin:default', config: { forceArgs: [true] }, assumePrimitive: false },
@@ -138,6 +138,8 @@ function resolveIdToValue(id, { environment, graph, idMap, full = true, resolve
138
138
  else {
139
139
  return r_value_1.Top;
140
140
  }
141
+ case type_1.RType.FunctionDefinition:
142
+ return (0, set_constants_1.setFrom)({ type: 'function-definition' });
141
143
  case type_1.RType.FunctionCall:
142
144
  case type_1.RType.BinaryOp:
143
145
  case type_1.RType.UnaryOp:
@@ -41,6 +41,9 @@ function resolveNode(resolve, a, env, graph, map) {
41
41
  else if (a.type === type_1.RType.Logical) {
42
42
  return a.content.valueOf() ? logical_constants_1.ValueLogicalTrue : logical_constants_1.ValueLogicalFalse;
43
43
  }
44
+ else if (a.type === type_1.RType.FunctionDefinition) {
45
+ return { type: 'function-definition' };
46
+ }
44
47
  else if ((a.type === type_1.RType.FunctionCall || a.type === type_1.RType.BinaryOp || a.type === type_1.RType.UnaryOp) && graph) {
45
48
  const origin = (0, dfg_get_origin_1.getOriginInDfg)(graph, a.info.id)?.[0];
46
49
  if (origin === undefined || origin.type !== 3 /* OriginType.BuiltInFunctionOrigin */) {
@@ -37,6 +37,9 @@ export interface ValueString<Str extends Lift<RStringValue> = Lift<RStringValue>
37
37
  type: 'string';
38
38
  value: Str;
39
39
  }
40
+ export interface ValueFunctionDefinition {
41
+ type: 'function-definition';
42
+ }
40
43
  export interface ValueMissing {
41
44
  type: 'missing';
42
45
  }
@@ -45,7 +48,7 @@ export interface ValueLogical {
45
48
  type: 'logical';
46
49
  value: Lift<TernaryLogical>;
47
50
  }
48
- export type Value = Lift<ValueInterval | ValueVector | ValueSet | ValueNumber | ValueString | ValueLogical | ValueMissing>;
51
+ export type Value = Lift<ValueInterval | ValueVector | ValueSet | ValueNumber | ValueString | ValueLogical | ValueMissing | ValueFunctionDefinition>;
49
52
  export type ValueType<V> = V extends {
50
53
  type: infer T;
51
54
  } ? T : never;
@@ -82,6 +82,8 @@ function stringifyValue(value) {
82
82
  return tryStringifyBoTop(v.value, l => l === 'maybe' ? 'maybe' : l ? 'TRUE' : 'FALSE', () => '⊤ (logical)', () => '⊥ (logical)');
83
83
  case 'missing':
84
84
  return '(missing)';
85
+ case 'function-definition':
86
+ return 'fn-def';
85
87
  default:
86
88
  (0, assert_1.assertUnreachable)(t);
87
89
  }
@@ -3,6 +3,7 @@ import type { DataflowProcessors } from './processor';
3
3
  import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
4
4
  import type { RParseRequests } from '../r-bridge/retriever';
5
5
  import type { KnownParserType, Parser } from '../r-bridge/parser';
6
+ import type { ControlFlowInformation } from '../control-flow/control-flow-graph';
6
7
  import type { FlowrConfigOptions } from '../config';
7
8
  /**
8
9
  * The best friend of {@link produceDataFlowGraph} and {@link processDataflowFor}.
@@ -15,4 +16,6 @@ export declare const processors: DataflowProcessors<ParentInformation>;
15
16
  * (e.g., in the event of a `source` call).
16
17
  * For the actual, canonical fold entry point, see {@link processDataflowFor}.
17
18
  */
18
- export declare function produceDataFlowGraph<OtherInfo>(parser: Parser<KnownParserType>, request: RParseRequests, completeAst: NormalizedAst<OtherInfo & ParentInformation>, config: FlowrConfigOptions): DataflowInformation;
19
+ export declare function produceDataFlowGraph<OtherInfo>(parser: Parser<KnownParserType>, request: RParseRequests, completeAst: NormalizedAst<OtherInfo & ParentInformation>, config: FlowrConfigOptions): DataflowInformation & {
20
+ cfgQuick: ControlFlowInformation | undefined;
21
+ };
@@ -59,14 +59,14 @@ exports.processors = {
59
59
  }
60
60
  };
61
61
  function resolveLinkToSideEffects(ast, graph) {
62
- let cfg = undefined;
62
+ let cf = undefined;
63
63
  for (const s of graph.unknownSideEffects) {
64
64
  if (typeof s !== 'object') {
65
65
  continue;
66
66
  }
67
- cfg ??= (0, extract_cfg_1.extractCfgQuick)(ast).graph;
67
+ cf ??= (0, extract_cfg_1.extractCfgQuick)(ast);
68
68
  /* this has to change whenever we add a new link to relations because we currently offer no abstraction for the type */
69
- const potentials = (0, identify_link_to_last_call_relation_1.identifyLinkToLastCallRelation)(s.id, cfg, graph, s.linkTo);
69
+ const potentials = (0, identify_link_to_last_call_relation_1.identifyLinkToLastCallRelation)(s.id, cf?.graph, graph, s.linkTo);
70
70
  for (const pot of potentials) {
71
71
  graph.addEdge(s.id, pot, edge_1.EdgeType.Reads);
72
72
  }
@@ -74,6 +74,7 @@ function resolveLinkToSideEffects(ast, graph) {
74
74
  graph.unknownSideEffects.delete(s);
75
75
  }
76
76
  }
77
+ return cf;
77
78
  }
78
79
  /**
79
80
  * This is the main function to produce the dataflow graph from a given request and normalized AST.
@@ -114,7 +115,8 @@ function produceDataFlowGraph(parser, request, completeAst, config) {
114
115
  }
115
116
  // finally, resolve linkages
116
117
  (0, built_in_function_definition_1.updateNestedFunctionCalls)(df.graph, df.environment);
117
- resolveLinkToSideEffects(completeAst, df.graph);
118
- return df;
118
+ const cfgQuick = resolveLinkToSideEffects(completeAst, df.graph);
119
+ // performance optimization: return cfgQuick as part of the result to avoid recomputation
120
+ return { ...df, cfgQuick };
119
121
  }
120
122
  //# sourceMappingURL=extractor.js.map
@@ -0,0 +1,9 @@
1
+ import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
2
+ import type { DataflowGraph } from '../graph/graph';
3
+ /**
4
+ * Determines whether the function with the given id is a higher-order function, i.e.,
5
+ * either takes a function as an argument or (may) returns a function.
6
+ * If the return is an identity, e.g., `function(x) x`, this is not considered higher-order,
7
+ * if no function is passed as an argument.
8
+ */
9
+ export declare function isHigherOrder(id: NodeId, graph: DataflowGraph): boolean;