@eagleoutice/flowr 2.2.13 → 2.2.15

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 +4 -4
  2. package/cli/repl/commands/repl-cfg.d.ts +2 -2
  3. package/cli/repl/commands/repl-cfg.js +4 -4
  4. package/cli/repl/commands/repl-commands.js +3 -3
  5. package/cli/repl/commands/repl-execute.js +2 -1
  6. package/cli/repl/server/connection.js +1 -1
  7. package/cli/script-core/statistics-helper-core.js +1 -1
  8. package/config.js +1 -1
  9. package/control-flow/basic-cfg-guided-visitor.d.ts +3 -3
  10. package/control-flow/cfg-dead-code.d.ts +4 -0
  11. package/control-flow/cfg-dead-code.js +81 -0
  12. package/control-flow/cfg-simplification.d.ts +17 -6
  13. package/control-flow/cfg-simplification.js +23 -19
  14. package/control-flow/control-flow-graph.d.ts +2 -1
  15. package/control-flow/control-flow-graph.js +1 -0
  16. package/control-flow/dfg-cfg-guided-visitor.d.ts +4 -4
  17. package/control-flow/dfg-cfg-guided-visitor.js +1 -1
  18. package/control-flow/extract-cfg.d.ts +2 -2
  19. package/control-flow/extract-cfg.js +70 -67
  20. package/control-flow/semantic-cfg-guided-visitor.d.ts +17 -8
  21. package/control-flow/semantic-cfg-guided-visitor.js +50 -17
  22. package/control-flow/simple-visitor.d.ts +4 -0
  23. package/control-flow/simple-visitor.js +14 -0
  24. package/control-flow/syntax-cfg-guided-visitor.d.ts +2 -2
  25. package/dataflow/environments/built-in-config.d.ts +1 -0
  26. package/dataflow/environments/built-in.d.ts +10 -1
  27. package/dataflow/environments/built-in.js +9 -3
  28. package/dataflow/environments/default-builtin-config.js +1 -1
  29. package/dataflow/environments/resolve-by-name.d.ts +0 -36
  30. package/dataflow/environments/resolve-by-name.js +0 -240
  31. package/dataflow/eval/resolve/alias-tracking.d.ts +87 -0
  32. package/dataflow/eval/resolve/alias-tracking.js +349 -0
  33. package/dataflow/eval/resolve/resolve.d.ts +34 -0
  34. package/dataflow/eval/resolve/resolve.js +93 -0
  35. package/dataflow/eval/values/general.d.ts +27 -0
  36. package/dataflow/eval/values/general.js +73 -0
  37. package/dataflow/eval/values/intervals/interval-constants.d.ts +4 -0
  38. package/dataflow/eval/values/intervals/interval-constants.js +27 -0
  39. package/dataflow/eval/values/logical/logical-constants.d.ts +7 -0
  40. package/dataflow/eval/values/logical/logical-constants.js +31 -0
  41. package/dataflow/eval/values/r-value.d.ts +58 -0
  42. package/dataflow/eval/values/r-value.js +90 -0
  43. package/dataflow/eval/values/scalar/scalar-consatnts.d.ts +15 -0
  44. package/dataflow/eval/values/scalar/scalar-consatnts.js +35 -0
  45. package/dataflow/eval/values/sets/set-constants.d.ts +7 -0
  46. package/dataflow/eval/values/sets/set-constants.js +34 -0
  47. package/dataflow/eval/values/string/string-constants.d.ts +8 -0
  48. package/dataflow/eval/values/string/string-constants.js +40 -0
  49. package/dataflow/eval/values/vectors/vector-constants.d.ts +14 -0
  50. package/dataflow/eval/values/vectors/vector-constants.js +35 -0
  51. package/dataflow/graph/unknown-replacement.d.ts +11 -0
  52. package/dataflow/graph/unknown-replacement.js +12 -0
  53. package/dataflow/graph/unknown-side-effect.d.ts +7 -0
  54. package/dataflow/graph/unknown-side-effect.js +13 -0
  55. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +8 -5
  56. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +4 -2
  57. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +12 -9
  58. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +5 -4
  59. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +9 -2
  60. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +12 -15
  61. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +23 -0
  62. package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
  63. package/documentation/doc-util/doc-cfg.d.ts +1 -1
  64. package/documentation/doc-util/doc-cfg.js +3 -3
  65. package/documentation/doc-util/doc-query.d.ts +6 -3
  66. package/documentation/doc-util/doc-query.js +3 -1
  67. package/documentation/print-cfg-wiki.js +31 -31
  68. package/documentation/print-dataflow-graph-wiki.js +4 -3
  69. package/documentation/print-engines-wiki.js +1 -1
  70. package/documentation/print-linter-wiki.d.ts +1 -0
  71. package/documentation/print-linter-wiki.js +76 -0
  72. package/documentation/print-query-wiki.js +80 -0
  73. package/linter/linter-executor.d.ts +9 -0
  74. package/linter/linter-executor.js +26 -0
  75. package/linter/linter-format.d.ts +65 -0
  76. package/linter/linter-format.js +9 -0
  77. package/linter/linter-rules.d.ts +42 -0
  78. package/linter/linter-rules.js +14 -0
  79. package/linter/rules/1-deprecated-functions.d.ts +34 -0
  80. package/linter/rules/1-deprecated-functions.js +54 -0
  81. package/linter/rules/2-file-path-validity.d.ts +48 -0
  82. package/linter/rules/2-file-path-validity.js +93 -0
  83. package/package.json +2 -1
  84. package/queries/catalog/call-context-query/call-context-query-executor.js +1 -1
  85. package/queries/catalog/call-context-query/call-context-query-format.d.ts +2 -2
  86. package/queries/catalog/call-context-query/call-context-query-format.js +5 -1
  87. package/queries/catalog/cluster-query/cluster-query-format.d.ts +2 -0
  88. package/queries/catalog/cluster-query/cluster-query-format.js +5 -1
  89. package/queries/catalog/config-query/config-query-format.d.ts +1 -0
  90. package/queries/catalog/config-query/config-query-format.js +2 -1
  91. package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +3 -0
  92. package/queries/catalog/control-flow-query/control-flow-query-executor.js +20 -0
  93. package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +81 -0
  94. package/queries/catalog/control-flow-query/control-flow-query-format.js +34 -0
  95. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -0
  96. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +2 -1
  97. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +2 -0
  98. package/queries/catalog/dataflow-query/dataflow-query-format.js +9 -1
  99. package/queries/catalog/dependencies-query/dependencies-query-executor.js +33 -32
  100. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -0
  101. package/queries/catalog/dependencies-query/dependencies-query-format.js +10 -1
  102. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -0
  103. package/queries/catalog/happens-before-query/happens-before-query-format.js +2 -1
  104. package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -0
  105. package/queries/catalog/id-map-query/id-map-query-format.js +2 -1
  106. package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -0
  107. package/queries/catalog/lineage-query/lineage-query-format.js +5 -1
  108. package/queries/catalog/linter-query/linter-query-executor.d.ts +3 -0
  109. package/queries/catalog/linter-query/linter-query-executor.js +28 -0
  110. package/queries/catalog/linter-query/linter-query-format.d.ts +80 -0
  111. package/queries/catalog/linter-query/linter-query-format.js +44 -0
  112. package/queries/catalog/location-map-query/location-map-query-format.d.ts +1 -0
  113. package/queries/catalog/location-map-query/location-map-query-format.js +2 -1
  114. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -0
  115. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +2 -1
  116. package/queries/catalog/origin-query/origin-query-format.d.ts +2 -0
  117. package/queries/catalog/origin-query/origin-query-format.js +5 -1
  118. package/queries/catalog/project-query/project-query-executor.js +1 -1
  119. package/queries/catalog/project-query/project-query-format.d.ts +1 -0
  120. package/queries/catalog/project-query/project-query-format.js +2 -1
  121. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +3 -3
  122. package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +3 -1
  123. package/queries/catalog/resolve-value-query/resolve-value-query-format.js +4 -23
  124. package/queries/catalog/search-query/search-query-format.d.ts +1 -0
  125. package/queries/catalog/search-query/search-query-format.js +5 -1
  126. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +2 -0
  127. package/queries/catalog/static-slice-query/static-slice-query-format.js +9 -1
  128. package/queries/query.d.ts +143 -1
  129. package/queries/query.js +4 -0
  130. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +11 -4
  131. package/r-bridge/retriever.js +1 -1
  132. package/search/flowr-search-builder.d.ts +31 -2
  133. package/search/flowr-search-builder.js +30 -0
  134. package/search/flowr-search.d.ts +7 -1
  135. package/search/search-executor/search-enrichers.d.ts +73 -0
  136. package/search/search-executor/search-enrichers.js +101 -0
  137. package/search/search-executor/search-generators.d.ts +6 -1
  138. package/search/search-executor/search-generators.js +21 -1
  139. package/search/search-executor/search-mappers.d.ts +19 -0
  140. package/search/search-executor/search-mappers.js +21 -0
  141. package/search/search-executor/search-transformer.d.ts +12 -0
  142. package/search/search-executor/search-transformer.js +11 -1
  143. package/slicing/criterion/parse.d.ts +8 -0
  144. package/slicing/criterion/parse.js +20 -0
  145. package/util/version.js +1 -1
@@ -34,6 +34,8 @@ const flowr_search_builder_1 = require("../search/flowr-search-builder");
34
34
  const vertex_1 = require("../dataflow/graph/vertex");
35
35
  const doc_types_1 = require("./doc-util/doc-types");
36
36
  const path_1 = __importDefault(require("path"));
37
+ const control_flow_query_executor_1 = require("../queries/catalog/control-flow-query/control-flow-query-executor");
38
+ const doc_cfg_1 = require("./doc-util/doc-cfg");
37
39
  (0, doc_query_1.registerQueryDocumentation)('call-context', {
38
40
  name: 'Call-Context Query',
39
41
  type: 'active',
@@ -477,6 +479,84 @@ Here, \`resolveValue\` tells the dependency query to resolve the value of this a
477
479
  `;
478
480
  }
479
481
  });
482
+ (0, doc_query_1.registerQueryDocumentation)('linter', {
483
+ name: 'Linter Query',
484
+ type: 'active',
485
+ shortDescription: 'Lints a given R script for common issues.',
486
+ functionName: dependencies_query_executor_1.executeDependenciesQuery.name,
487
+ functionFile: '../queries/catalog/linter-query/linter-query-executor.ts',
488
+ buildExplanation: async (shell) => {
489
+ const exampleCode = 'read.csv("i_do_not_exist.csv")';
490
+ return `
491
+ This query lints a given R script for common issues, such as missing files, unused variables, and more.
492
+
493
+ In other words, if you have a script simply reading: \`${exampleCode}\`, the following query returns all smells detected:
494
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
495
+ type: 'linter'
496
+ }], { showCode: false, collapseQuery: true })}
497
+
498
+ You can also configure which rules to apply and what settings to use for these rules.
499
+ We welcome any feedback and suggestions for new rules on this (consider opening a [new issue](${doc_issue_1.NewIssueUrl})).
500
+ `;
501
+ }
502
+ });
503
+ (0, doc_query_1.registerQueryDocumentation)('control-flow', {
504
+ name: 'Control-Flow Query',
505
+ type: 'active',
506
+ shortDescription: 'Provides the control-flow of the program.',
507
+ functionName: control_flow_query_executor_1.executeControlFlowQuery.name,
508
+ functionFile: '../queries/catalog/control-flow-query/control-flow-query-executor.ts',
509
+ buildExplanation: async (shell) => {
510
+ const exampleCode = 'if(TRUE) 1 else 2';
511
+ return `
512
+ This control-flow query provides you access to the control flow graph.
513
+
514
+ In other words, if you have a script simply reading: \`${exampleCode}\`, the following query returns the CFG:
515
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
516
+ type: 'control-flow'
517
+ }], { showCode: false, collapseQuery: true, collapseResult: true })}
518
+
519
+ You can also overwrite the simplification passes to tune the perspective. for example, if you want to have basic blocks:
520
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
521
+ type: 'control-flow',
522
+ config: {
523
+ simplificationPasses: ['unique-cf-sets', 'to-basic-blocks']
524
+ }
525
+ }], { showCode: false, collapseResult: true })}
526
+
527
+ this produces:
528
+
529
+ ${await (0, doc_cfg_1.printCfgCode)(shell, exampleCode, { showCode: false, prefix: 'flowchart RL\n', simplifications: ['to-basic-blocks'] })}
530
+
531
+
532
+ If, on the other hand, you want to prune dead code edges:
533
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
534
+ type: 'control-flow',
535
+ config: {
536
+ simplificationPasses: ['unique-cf-sets', 'analyze-dead-code']
537
+ }
538
+ }], { showCode: false, collapseResult: true })}
539
+
540
+ this produces:
541
+
542
+ ${await (0, doc_cfg_1.printCfgCode)(shell, exampleCode, { showCode: false, prefix: 'flowchart RL\n', simplifications: ['analyze-dead-code'] })}
543
+
544
+
545
+ Or, completely remove dead code:
546
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
547
+ type: 'control-flow',
548
+ config: {
549
+ simplificationPasses: ['unique-cf-sets', 'analyze-dead-code', 'remove-dead-code']
550
+ }
551
+ }], { showCode: false, collapseResult: true })}
552
+
553
+ this produces:
554
+
555
+ ${await (0, doc_cfg_1.printCfgCode)(shell, exampleCode, { showCode: false, prefix: 'flowchart RL\n', simplifications: ['analyze-dead-code', 'remove-dead-code'] })}
556
+
557
+ `;
558
+ }
559
+ });
480
560
  (0, doc_query_1.registerQueryDocumentation)('location-map', {
481
561
  name: 'Location Map Query',
482
562
  type: 'active',
@@ -0,0 +1,9 @@
1
+ import type { LintingRuleConfig, LintingRuleNames } from './linter-rules';
2
+ import type { NormalizedAst } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
3
+ import type { DataflowInformation } from '../dataflow/info';
4
+ import type { LintingResults } from './linter-format';
5
+ import type { DeepPartial } from 'ts-essentials';
6
+ export declare function executeLintingRule<Name extends LintingRuleNames>(ruleName: Name, input: {
7
+ normalize: NormalizedAst;
8
+ dataflow: DataflowInformation;
9
+ }, config?: DeepPartial<LintingRuleConfig<Name>>): LintingResults<Name>;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeLintingRule = executeLintingRule;
4
+ const linter_rules_1 = require("./linter-rules");
5
+ const flowr_search_executor_1 = require("../search/flowr-search-executor");
6
+ const flowr_search_1 = require("../search/flowr-search");
7
+ function executeLintingRule(ruleName, input, config) {
8
+ const rule = linter_rules_1.LintingRules[ruleName];
9
+ const fullConfig = { ...rule.defaultConfig, ...config };
10
+ const ruleSearch = rule.createSearch(fullConfig, input);
11
+ const searchStart = Date.now();
12
+ const searchResult = (0, flowr_search_executor_1.runSearch)(ruleSearch, input);
13
+ const searchTime = Date.now() - searchStart;
14
+ const processStart = Date.now();
15
+ const result = rule.processSearchResult(new flowr_search_1.FlowrSearchElements(searchResult), fullConfig, input);
16
+ const processTime = Date.now() - processStart;
17
+ return {
18
+ ...result,
19
+ '.meta': {
20
+ ...result['.meta'],
21
+ searchTimeMs: searchTime,
22
+ processTimeMs: processTime
23
+ }
24
+ };
25
+ }
26
+ //# sourceMappingURL=linter-executor.js.map
@@ -0,0 +1,65 @@
1
+ import type { FlowrSearchLike } from '../search/flowr-search-builder';
2
+ import type { FlowrSearchElement, FlowrSearchElements } from '../search/flowr-search';
3
+ import type { MergeableRecord } from '../util/objects';
4
+ import type { GeneratorNames } from '../search/search-executor/search-generators';
5
+ import type { TransformerNames } from '../search/search-executor/search-transformer';
6
+ import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
7
+ import type { LintingRuleConfig, LintingRuleMetadata, LintingRuleNames, LintingRuleResult } from './linter-rules';
8
+ import type { DataflowInformation } from '../dataflow/info';
9
+ import type { DeepPartial } from 'ts-essentials';
10
+ /**
11
+ * The base interface for a linting rule, which contains all of its relevant settings.
12
+ * The registry of valid linting rules is stored in {@link LintingRules}.
13
+ */
14
+ export interface LintingRule<Result extends LintingResult, Metadata extends MergeableRecord, Config extends MergeableRecord = never, Info = ParentInformation, Elements extends FlowrSearchElement<Info>[] = FlowrSearchElement<Info>[]> {
15
+ /**
16
+ * Creates a flowR search that will then be executed and whose results will be passed to {@link processSearchResult}.
17
+ * In the future, additional optimizations and transformations may be applied to the search between this function and {@link processSearchResult}.
18
+ */
19
+ readonly createSearch: (config: Config, data: {
20
+ normalize: NormalizedAst;
21
+ dataflow: DataflowInformation;
22
+ }) => FlowrSearchLike<Info, GeneratorNames, TransformerNames[], FlowrSearchElements<Info, Elements>>;
23
+ /**
24
+ * Processes the search results of the search created through {@link createSearch}.
25
+ * This function is expected to return the linting results from this rule for the given search, ie usually the given script file.
26
+ */
27
+ readonly processSearchResult: (elements: FlowrSearchElements<Info, Elements>, config: Config, data: {
28
+ normalize: NormalizedAst;
29
+ dataflow: DataflowInformation;
30
+ }) => {
31
+ results: Result[];
32
+ '.meta': Metadata;
33
+ };
34
+ /**
35
+ * A function used to pretty-print the given linting result.
36
+ * By default, the {@link LintingResult#certainty} is automatically printed alongside this information.
37
+ */
38
+ readonly prettyPrint: (result: Result, metadata: Metadata) => string;
39
+ /**
40
+ * The default config for this linting rule.
41
+ * The default config is combined with the user config when executing the rule.
42
+ */
43
+ readonly defaultConfig: NoInfer<Config>;
44
+ }
45
+ /**
46
+ * A linting result for a single linting rule match.
47
+ */
48
+ export interface LintingResult {
49
+ readonly certainty: LintingCertainty;
50
+ }
51
+ export interface ConfiguredLintingRule<Name extends LintingRuleNames = LintingRuleNames> {
52
+ readonly name: Name;
53
+ readonly config: DeepPartial<LintingRuleConfig<Name>>;
54
+ }
55
+ export interface LintingResults<Name extends LintingRuleNames> {
56
+ results: LintingRuleResult<Name>[];
57
+ '.meta': LintingRuleMetadata<Name> & {
58
+ readonly searchTimeMs: number;
59
+ readonly processTimeMs: number;
60
+ };
61
+ }
62
+ export declare enum LintingCertainty {
63
+ Maybe = "maybe",
64
+ Definitely = "definitely"
65
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LintingCertainty = void 0;
4
+ var LintingCertainty;
5
+ (function (LintingCertainty) {
6
+ LintingCertainty["Maybe"] = "maybe";
7
+ LintingCertainty["Definitely"] = "definitely";
8
+ })(LintingCertainty || (exports.LintingCertainty = LintingCertainty = {}));
9
+ //# sourceMappingURL=linter-format.js.map
@@ -0,0 +1,42 @@
1
+ import type { LintingRule } from './linter-format';
2
+ /**
3
+ * The registry of currently supported linting rules.
4
+ * A linting rule can be executed on a dataflow pipeline result using {@link executeLintingRule}.
5
+ */
6
+ export declare const LintingRules: {
7
+ readonly 'deprecated-functions': {
8
+ readonly createSearch: (_config: import("./rules/1-deprecated-functions").DeprecatedFunctionsConfig) => import("../search/flowr-search-builder").FlowrSearchBuilder<"all", ["with"], import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../search/flowr-search").FlowrSearchElements<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../search/search-executor/search-enrichers").EnrichedFlowrSearchElement<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>>;
9
+ readonly processSearchResult: (elements: import("../search/flowr-search").FlowrSearchElements<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../search/flowr-search").FlowrSearchElement<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>, config: import("./rules/1-deprecated-functions").DeprecatedFunctionsConfig) => {
10
+ results: {
11
+ certainty: import("./linter-format").LintingCertainty.Definitely;
12
+ function: import("../dataflow/environments/identifier").Identifier;
13
+ range: import("../util/range").SourceRange;
14
+ }[];
15
+ '.meta': import("./rules/1-deprecated-functions").DeprecatedFunctionsMetadata;
16
+ };
17
+ readonly prettyPrint: (result: import("./rules/1-deprecated-functions").DeprecatedFunctionsResult) => string;
18
+ readonly defaultConfig: {
19
+ readonly deprecatedFunctions: ["all_equal", "arrange_all", "distinct_all", "filter_all", "group_by_all", "summarise_all", "mutate_all", "select_all", "vars", "all_vars", "id", "failwith", "select_vars", "rename_vars", "select_var", "current_vars", "bench_tbls", "compare_tbls", "compare_tbls2", "eval_tbls", "eval_tbls2", "location", "changes", "combine", "do", "funs", "add_count_", "add_tally_", "arrange_", "count_", "distinct_", "do_", "filter_", "funs_", "group_by_", "group_indices_", "mutate_", "tally_", "transmute_", "rename_", "rename_vars_", "select_", "select_vars_", "slice_", "summarise_", "summarize_", "summarise_each", "src_local", "tbl_df", "add_rownames", "group_nest", "group_split", "with_groups", "nest_by", "progress_estimated", "recode", "sample_n", "top_n", "transmute", "fct_explicit_na", "aes_", "aes_auto", "annotation_logticks", "is.Coord", "coord_flip", "coord_map", "is.facet", "fortify", "is.ggproto", "guide_train", "is.ggplot", "qplot", "is.theme", "gg_dep", "liply", "isplit2", "list_along", "cross", "invoke", "at_depth", "prepend", "rerun", "splice", "`%@%`", "rbernoulli", "rdunif", "when", "update_list", "map_raw", "accumulate", "reduce_right", "flatten", "map_dfr", "as_vector", "transpose", "melt_delim", "melt_fwf", "melt_table", "read_table2", "str_interp", "as_tibble", "data_frame", "tibble_", "data_frame_", "lst_", "as_data_frame", "as.tibble", "frame_data", "trunc_mat", "is.tibble", "tidy_names", "set_tidy_names", "repair_names", "extract_numeric", "complete_", "drop_na_", "expand_", "crossing_", "nesting_", "extract_", "fill_", "gather_", "nest_", "separate_rows_", "separate_", "spread_", "unite_", "unnest_", "extract", "gather", "nest_legacy", "separate_rows", "separate", "spread"];
20
+ };
21
+ };
22
+ readonly 'file-path-validity': {
23
+ readonly createSearch: (config: import("./rules/2-file-path-validity").FilePathValidityConfig) => import("../search/flowr-search-builder").FlowrSearchBuilder<"from-query", [], import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../search/flowr-search").FlowrSearchElements<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../search/flowr-search").FlowrSearchElementFromQuery<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>>;
24
+ readonly processSearchResult: (elements: import("../search/flowr-search").FlowrSearchElements<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../search/flowr-search").FlowrSearchElementFromQuery<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>, config: import("./rules/2-file-path-validity").FilePathValidityConfig, data: {
25
+ normalize: import("../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
26
+ dataflow: import("../dataflow/info").DataflowInformation;
27
+ }) => {
28
+ results: import("./rules/2-file-path-validity").FilePathValidityResult[];
29
+ ".meta": import("./rules/2-file-path-validity").FilePathValidityMetadata;
30
+ };
31
+ readonly prettyPrint: (result: import("./rules/2-file-path-validity").FilePathValidityResult) => string;
32
+ readonly defaultConfig: {
33
+ readonly additionalReadFunctions: [];
34
+ readonly additionalWriteFunctions: [];
35
+ readonly includeUnknown: false;
36
+ };
37
+ };
38
+ };
39
+ export type LintingRuleNames = keyof typeof LintingRules;
40
+ export type LintingRuleMetadata<Name extends LintingRuleNames> = typeof LintingRules[Name] extends LintingRule<infer _Result, infer Metadata, infer _Config, infer _Info, infer _Elements> ? Metadata : never;
41
+ export type LintingRuleResult<Name extends LintingRuleNames> = typeof LintingRules[Name] extends LintingRule<infer Result, infer _Metadata, infer _Config, infer _Info, infer _Elements> ? Result : never;
42
+ export type LintingRuleConfig<Name extends LintingRuleNames> = typeof LintingRules[Name] extends LintingRule<infer _Result, infer _Metadata, infer Config, infer _Info, infer _Elements> ? Config : never;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LintingRules = void 0;
4
+ const _1_deprecated_functions_1 = require("./rules/1-deprecated-functions");
5
+ const _2_file_path_validity_1 = require("./rules/2-file-path-validity");
6
+ /**
7
+ * The registry of currently supported linting rules.
8
+ * A linting rule can be executed on a dataflow pipeline result using {@link executeLintingRule}.
9
+ */
10
+ exports.LintingRules = {
11
+ 'deprecated-functions': _1_deprecated_functions_1.R1_DEPRECATED_FUNCTIONS,
12
+ 'file-path-validity': _2_file_path_validity_1.R2_FILE_PATH_VALIDITY
13
+ };
14
+ //# sourceMappingURL=linter-rules.js.map
@@ -0,0 +1,34 @@
1
+ import type { LintingResult } from '../linter-format';
2
+ import { LintingCertainty } from '../linter-format';
3
+ import type { MergeableRecord } from '../../util/objects';
4
+ import type { SourceRange } from '../../util/range';
5
+ import type { Identifier } from '../../dataflow/environments/identifier';
6
+ export interface DeprecatedFunctionsResult extends LintingResult {
7
+ function: string;
8
+ range: SourceRange;
9
+ }
10
+ export interface DeprecatedFunctionsConfig extends MergeableRecord {
11
+ /**
12
+ * The list of function names that should be marked as deprecated.
13
+ */
14
+ deprecatedFunctions: string[];
15
+ }
16
+ export interface DeprecatedFunctionsMetadata extends MergeableRecord {
17
+ totalRelevant: number;
18
+ totalNotDeprecated: number;
19
+ }
20
+ export declare const R1_DEPRECATED_FUNCTIONS: {
21
+ readonly createSearch: (_config: DeprecatedFunctionsConfig) => import("../../search/flowr-search-builder").FlowrSearchBuilder<"all", ["with"], import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../../search/flowr-search").FlowrSearchElements<import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../../search/search-executor/search-enrichers").EnrichedFlowrSearchElement<import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>>;
22
+ readonly processSearchResult: (elements: import("../../search/flowr-search").FlowrSearchElements<import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../../search/flowr-search").FlowrSearchElement<import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>, config: DeprecatedFunctionsConfig) => {
23
+ results: {
24
+ certainty: LintingCertainty.Definitely;
25
+ function: Identifier;
26
+ range: SourceRange;
27
+ }[];
28
+ '.meta': DeprecatedFunctionsMetadata;
29
+ };
30
+ readonly prettyPrint: (result: DeprecatedFunctionsResult) => string;
31
+ readonly defaultConfig: {
32
+ readonly deprecatedFunctions: ["all_equal", "arrange_all", "distinct_all", "filter_all", "group_by_all", "summarise_all", "mutate_all", "select_all", "vars", "all_vars", "id", "failwith", "select_vars", "rename_vars", "select_var", "current_vars", "bench_tbls", "compare_tbls", "compare_tbls2", "eval_tbls", "eval_tbls2", "location", "changes", "combine", "do", "funs", "add_count_", "add_tally_", "arrange_", "count_", "distinct_", "do_", "filter_", "funs_", "group_by_", "group_indices_", "mutate_", "tally_", "transmute_", "rename_", "rename_vars_", "select_", "select_vars_", "slice_", "summarise_", "summarize_", "summarise_each", "src_local", "tbl_df", "add_rownames", "group_nest", "group_split", "with_groups", "nest_by", "progress_estimated", "recode", "sample_n", "top_n", "transmute", "fct_explicit_na", "aes_", "aes_auto", "annotation_logticks", "is.Coord", "coord_flip", "coord_map", "is.facet", "fortify", "is.ggproto", "guide_train", "is.ggplot", "qplot", "is.theme", "gg_dep", "liply", "isplit2", "list_along", "cross", "invoke", "at_depth", "prepend", "rerun", "splice", "`%@%`", "rbernoulli", "rdunif", "when", "update_list", "map_raw", "accumulate", "reduce_right", "flatten", "map_dfr", "as_vector", "transpose", "melt_delim", "melt_fwf", "melt_table", "read_table2", "str_interp", "as_tibble", "data_frame", "tibble_", "data_frame_", "lst_", "as_data_frame", "as.tibble", "frame_data", "trunc_mat", "is.tibble", "tidy_names", "set_tidy_names", "repair_names", "extract_numeric", "complete_", "drop_na_", "expand_", "crossing_", "nesting_", "extract_", "fill_", "gather_", "nest_", "separate_rows_", "separate_", "spread_", "unite_", "unnest_", "extract", "gather", "nest_legacy", "separate_rows", "separate", "spread"];
33
+ };
34
+ };
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.R1_DEPRECATED_FUNCTIONS = void 0;
4
+ const linter_format_1 = require("../linter-format");
5
+ const flowr_search_builder_1 = require("../../search/flowr-search-builder");
6
+ const dfg_1 = require("../../util/mermaid/dfg");
7
+ const search_enrichers_1 = require("../../search/search-executor/search-enrichers");
8
+ exports.R1_DEPRECATED_FUNCTIONS = {
9
+ createSearch: (_config) => flowr_search_builder_1.Q.all().with(search_enrichers_1.Enrichment.CallTargets),
10
+ processSearchResult: (elements, config) => {
11
+ const metadata = {
12
+ totalRelevant: 0,
13
+ totalNotDeprecated: 0
14
+ };
15
+ return {
16
+ results: elements.getElements()
17
+ .flatMap(element => {
18
+ const targets = (0, search_enrichers_1.enrichmentContent)(element, search_enrichers_1.Enrichment.CallTargets).targets;
19
+ // if there is a call target that is not built-in (ie a custom function), we don't want to mark it as deprecated
20
+ // eventually we'd want to solve this with an argument to the CallTargets enrichment like satisfiesCallTargets does!
21
+ if (targets.some(t => typeof t !== 'string')) {
22
+ return [];
23
+ }
24
+ return targets.map(target => {
25
+ metadata.totalRelevant++;
26
+ return {
27
+ range: element.node.info.fullRange,
28
+ target: target
29
+ };
30
+ });
31
+ })
32
+ .filter(element => {
33
+ if (config.deprecatedFunctions.includes(element.target)) {
34
+ return true;
35
+ }
36
+ else {
37
+ metadata.totalNotDeprecated++;
38
+ return false;
39
+ }
40
+ })
41
+ .map(element => ({
42
+ certainty: linter_format_1.LintingCertainty.Definitely,
43
+ function: element.target,
44
+ range: element.range
45
+ })),
46
+ '.meta': metadata
47
+ };
48
+ },
49
+ prettyPrint: result => `Function \`${result.function}\` at ${(0, dfg_1.formatRange)(result.range)}`,
50
+ defaultConfig: {
51
+ deprecatedFunctions: ['all_equal', 'arrange_all', 'distinct_all', 'filter_all', 'group_by_all', 'summarise_all', 'mutate_all', 'select_all', 'vars', 'all_vars', 'id', 'failwith', 'select_vars', 'rename_vars', 'select_var', 'current_vars', 'bench_tbls', 'compare_tbls', 'compare_tbls2', 'eval_tbls', 'eval_tbls2', 'location', 'changes', 'combine', 'do', 'funs', 'add_count_', 'add_tally_', 'arrange_', 'count_', 'distinct_', 'do_', 'filter_', 'funs_', 'group_by_', 'group_indices_', 'mutate_', 'tally_', 'transmute_', 'rename_', 'rename_vars_', 'select_', 'select_vars_', 'slice_', 'summarise_', 'summarize_', 'summarise_each', 'src_local', 'tbl_df', 'add_rownames', 'group_nest', 'group_split', 'with_groups', 'nest_by', 'progress_estimated', 'recode', 'sample_n', 'top_n', 'transmute', 'fct_explicit_na', 'aes_', 'aes_auto', 'annotation_logticks', 'is.Coord', 'coord_flip', 'coord_map', 'is.facet', 'fortify', 'is.ggproto', 'guide_train', 'is.ggplot', 'qplot', 'is.theme', 'gg_dep', 'liply', 'isplit2', 'list_along', 'cross', 'invoke', 'at_depth', 'prepend', 'rerun', 'splice', '`%@%`', 'rbernoulli', 'rdunif', 'when', 'update_list', 'map_raw', 'accumulate', 'reduce_right', 'flatten', 'map_dfr', 'as_vector', 'transpose', 'melt_delim', 'melt_fwf', 'melt_table', 'read_table2', 'str_interp', 'as_tibble', 'data_frame', 'tibble_', 'data_frame_', 'lst_', 'as_data_frame', 'as.tibble', 'frame_data', 'trunc_mat', 'is.tibble', 'tidy_names', 'set_tidy_names', 'repair_names', 'extract_numeric', 'complete_', 'drop_na_', 'expand_', 'crossing_', 'nesting_', 'extract_', 'fill_', 'gather_', 'nest_', 'separate_rows_', 'separate_', 'spread_', 'unite_', 'unnest_', 'extract', 'gather', 'nest_legacy', 'separate_rows', 'separate', 'spread',]
52
+ }
53
+ };
54
+ //# sourceMappingURL=1-deprecated-functions.js.map
@@ -0,0 +1,48 @@
1
+ import type { LintingResult } from '../linter-format';
2
+ import type { MergeableRecord } from '../../util/objects';
3
+ import type { SourceRange } from '../../util/range';
4
+ import type { ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
5
+ import type { FlowrSearchElementFromQuery } from '../../search/flowr-search';
6
+ import type { FunctionInfo } from '../../queries/catalog/dependencies-query/function-info/function-info';
7
+ export interface FilePathValidityResult extends LintingResult {
8
+ filePath: string;
9
+ range: SourceRange;
10
+ }
11
+ export interface FilePathValidityConfig extends MergeableRecord {
12
+ /**
13
+ * The set of functions that should additionally be considered as reading a file path.
14
+ * Entries in this array use the {@link FunctionInfo} format from the dependencies query.
15
+ */
16
+ additionalReadFunctions: FunctionInfo[];
17
+ /**
18
+ * The set of functions that should additionally be considered as writing to a file path.
19
+ * Entries in this array use the {@link FunctionInfo} format from the dependencies query.
20
+ */
21
+ additionalWriteFunctions: FunctionInfo[];
22
+ /**
23
+ * Whether unknown file paths should be included as linting results.
24
+ */
25
+ includeUnknown: boolean;
26
+ }
27
+ export interface FilePathValidityMetadata extends MergeableRecord {
28
+ totalReads: number;
29
+ totalUnknown: number;
30
+ totalWritesBeforeAlways: number;
31
+ totalValid: number;
32
+ }
33
+ export declare const R2_FILE_PATH_VALIDITY: {
34
+ readonly createSearch: (config: FilePathValidityConfig) => import("../../search/flowr-search-builder").FlowrSearchBuilder<"from-query", [], ParentInformation, import("../../search/flowr-search").FlowrSearchElements<ParentInformation, FlowrSearchElementFromQuery<ParentInformation>[]>>;
35
+ readonly processSearchResult: (elements: import("../../search/flowr-search").FlowrSearchElements<ParentInformation, FlowrSearchElementFromQuery<ParentInformation>[]>, config: FilePathValidityConfig, data: {
36
+ normalize: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
37
+ dataflow: import("../../dataflow/info").DataflowInformation;
38
+ }) => {
39
+ results: FilePathValidityResult[];
40
+ ".meta": FilePathValidityMetadata;
41
+ };
42
+ readonly prettyPrint: (result: FilePathValidityResult) => string;
43
+ readonly defaultConfig: {
44
+ readonly additionalReadFunctions: [];
45
+ readonly additionalWriteFunctions: [];
46
+ readonly includeUnknown: false;
47
+ };
48
+ };
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.R2_FILE_PATH_VALIDITY = void 0;
4
+ const linter_format_1 = require("../linter-format");
5
+ const flowr_search_builder_1 = require("../../search/flowr-search-builder");
6
+ const dfg_1 = require("../../util/mermaid/dfg");
7
+ const dependencies_query_format_1 = require("../../queries/catalog/dependencies-query/dependencies-query-format");
8
+ const built_in_source_1 = require("../../dataflow/internal/process/functions/call/built-in/built-in-source");
9
+ const logic_1 = require("../../util/logic");
10
+ const config_1 = require("../../config");
11
+ const retriever_1 = require("../../r-bridge/retriever");
12
+ const read_functions_1 = require("../../queries/catalog/dependencies-query/function-info/read-functions");
13
+ const write_functions_1 = require("../../queries/catalog/dependencies-query/function-info/write-functions");
14
+ const extract_cfg_1 = require("../../control-flow/extract-cfg");
15
+ const happens_before_1 = require("../../control-flow/happens-before");
16
+ exports.R2_FILE_PATH_VALIDITY = {
17
+ createSearch: (config) => flowr_search_builder_1.Q.fromQuery({
18
+ type: 'dependencies',
19
+ // we only want to check read and write functions, so we explicitly clear all others
20
+ ignoreDefaultFunctions: true,
21
+ readFunctions: read_functions_1.ReadFunctions.concat(config.additionalReadFunctions),
22
+ writeFunctions: write_functions_1.WriteFunctions.concat(config.additionalWriteFunctions)
23
+ }),
24
+ processSearchResult: (elements, config, data) => {
25
+ const cfg = (0, extract_cfg_1.extractSimpleCfg)(data.normalize).graph;
26
+ const metadata = {
27
+ totalReads: 0,
28
+ totalUnknown: 0,
29
+ totalWritesBeforeAlways: 0,
30
+ totalValid: 0
31
+ };
32
+ return {
33
+ results: elements.getElements().flatMap(element => {
34
+ const results = element.queryResult;
35
+ const matchingRead = results.readData.find(r => r.nodeId == element.node.info.id);
36
+ if (!matchingRead) {
37
+ return [];
38
+ }
39
+ metadata.totalReads++;
40
+ const range = element.node.info.fullRange;
41
+ // check if we can't parse the file path statically
42
+ if (matchingRead.source === dependencies_query_format_1.Unknown) {
43
+ metadata.totalUnknown++;
44
+ if (config.includeUnknown) {
45
+ return [{
46
+ range,
47
+ filePath: dependencies_query_format_1.Unknown,
48
+ certainty: linter_format_1.LintingCertainty.Maybe
49
+ }];
50
+ }
51
+ else {
52
+ return [];
53
+ }
54
+ }
55
+ // check if any write to the same file happens before the read, and exclude this case if so
56
+ const writesToFile = results.writtenData.filter(r => samePath(r.destination, matchingRead.source));
57
+ const writesBefore = writesToFile.map(w => (0, happens_before_1.happensBefore)(cfg, w.nodeId, element.node.info.id));
58
+ if (writesBefore.some(w => w === logic_1.Ternary.Always)) {
59
+ metadata.totalWritesBeforeAlways++;
60
+ return [];
61
+ }
62
+ // check if the file exists!
63
+ const paths = (0, built_in_source_1.findSource)(matchingRead.source, {
64
+ referenceChain: element.node.info.file ? [(0, retriever_1.requestFromInput)(`file://${element.node.info.file}`)] : []
65
+ });
66
+ if (paths && paths.length) {
67
+ metadata.totalValid++;
68
+ return [];
69
+ }
70
+ return [{
71
+ range,
72
+ filePath: matchingRead.source,
73
+ certainty: writesBefore && writesBefore.length && writesBefore.every(w => w === logic_1.Ternary.Maybe) ? linter_format_1.LintingCertainty.Maybe : linter_format_1.LintingCertainty.Definitely
74
+ }];
75
+ }),
76
+ '.meta': metadata
77
+ };
78
+ },
79
+ prettyPrint: result => `Path \`${result.filePath}\` at ${(0, dfg_1.formatRange)(result.range)}`,
80
+ defaultConfig: {
81
+ additionalReadFunctions: [],
82
+ additionalWriteFunctions: [],
83
+ includeUnknown: false
84
+ }
85
+ };
86
+ function samePath(a, b) {
87
+ if ((0, config_1.getConfig)().solver.resolveSource?.ignoreCapitalization === true) {
88
+ a = a.toLowerCase();
89
+ b = b.toLowerCase();
90
+ }
91
+ return a === b;
92
+ }
93
+ //# sourceMappingURL=2-file-path-validity.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eagleoutice/flowr",
3
- "version": "2.2.13",
3
+ "version": "2.2.15",
4
4
  "description": "Static Dataflow Analyzer and Program Slicer for the R Programming Language",
5
5
  "types": "dist/src/index.d.ts",
6
6
  "repository": {
@@ -37,6 +37,7 @@
37
37
  "wiki:onboarding": "ts-node src/documentation/print-onboarding-wiki.ts",
38
38
  "wiki:faq": "ts-node src/documentation/print-faq-wiki.ts",
39
39
  "wiki:cfg": "ts-node src/documentation/print-cfg-wiki.ts",
40
+ "wiki:linter": "ts-node src/documentation/print-linter-wiki.ts",
40
41
  "gen:readme": "ts-node src/documentation/print-readme.ts",
41
42
  "build": "tsc --project .",
42
43
  "build-dev": "npm run build && npm run build:copy-wasm",
@@ -180,7 +180,7 @@ function executeCallContextQueries({ dataflow: { graph }, ast }, queries) {
180
180
  const { promotedQueries, requiresCfg } = promoteQueryCallNames(queries);
181
181
  let cfg = undefined;
182
182
  if (requiresCfg) {
183
- cfg = (0, extract_cfg_1.extractCFG)(ast, graph, []);
183
+ cfg = (0, extract_cfg_1.extractCfg)(ast, graph, []);
184
184
  }
185
185
  const queriesWhichWantAliases = promotedQueries.filter(q => q.includeAliases);
186
186
  for (const [nodeId, info] of graph.vertices(true)) {
@@ -56,7 +56,7 @@ export interface DefaultCallContextQueryFormat<RegexType extends RegExp | string
56
56
  * For now, this uses the static Control-Flow-Graph produced by flowR as the FD over-approximation is still not stable (see #1005).
57
57
  * In short, this means that we are unable to detect origins over function call boundaries but plan on being more precise in the future.
58
58
  */
59
- interface LinkToLastCall<CallName extends RegExp | string = RegExp | string> extends BaseQueryFormat {
59
+ export interface LinkToLastCall<CallName extends RegExp | string = RegExp | string> extends BaseQueryFormat {
60
60
  readonly type: 'link-to-last-call';
61
61
  /** Regex regarding the function name of the last call. Similar to {@link DefaultCallContextQueryFormat#callName}, strings are interpreted as a `RegExp`. */
62
62
  readonly callName: CallName;
@@ -110,5 +110,5 @@ export declare const CallContextQueryDefinition: {
110
110
  readonly executor: typeof executeCallContextQueries;
111
111
  readonly asciiSummarizer: (formatter: OutputFormatter, processed: PipelineOutput<typeof DEFAULT_DATAFLOW_PIPELINE>, queryResults: BaseQueryResult, result: string[]) => boolean;
112
112
  readonly schema: Joi.ObjectSchema<any>;
113
+ readonly flattenInvolvedNodes: (queryResults: BaseQueryResult) => NodeId[];
113
114
  };
114
- export {};
@@ -39,6 +39,10 @@ exports.CallContextQueryDefinition = {
39
39
  includeUndefinedFiles: joi_1.default.boolean().optional().description('If `fileFilter` is set, but a nodes `file` attribute is `undefined`, should we include it in the results? Defaults to `true`.')
40
40
  }).optional().description('Filter that, when set, a node\'s file attribute must match to be considered'),
41
41
  linkTo: joi_1.default.alternatives(CallContextQueryLinkTo, joi_1.default.array().items(CallContextQueryLinkTo)).optional().description('Links the current call to the last call of the given kind. This way, you can link a call like `points` to the latest graphics plot etc.')
42
- }).description('Call context query used to find calls in the dataflow graph')
42
+ }).description('Call context query used to find calls in the dataflow graph'),
43
+ flattenInvolvedNodes: (queryResults) => {
44
+ const out = queryResults;
45
+ return Object.values(out.kinds).flatMap(({ subkinds }) => Object.values(subkinds).flatMap(subkinds => subkinds.map(subkind => subkind.id)));
46
+ }
43
47
  };
44
48
  //# sourceMappingURL=call-context-query-format.js.map
@@ -2,6 +2,7 @@ import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
2
2
  import Joi from 'joi';
3
3
  import type { DataflowGraphClusters } from '../../../dataflow/cluster';
4
4
  import { executeDataflowClusterQuery } from './cluster-query-executor';
5
+ import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
5
6
  /**
6
7
  * Calculates and returns all clusters encountered in the dataflow graph.
7
8
  */
@@ -69,4 +70,5 @@ export declare const ClusterQueryDefinition: {
69
70
  readonly dependencies: readonly ["normalize"];
70
71
  }>>, queryResults: BaseQueryResult, result: string[]) => true;
71
72
  readonly schema: Joi.ObjectSchema<any>;
73
+ readonly flattenInvolvedNodes: (queryResults: BaseQueryResult) => NodeId[];
72
74
  };
@@ -27,6 +27,10 @@ exports.ClusterQueryDefinition = {
27
27
  },
28
28
  schema: joi_1.default.object({
29
29
  type: joi_1.default.string().valid('dataflow-cluster').required().description('The type of the query.'),
30
- }).description('The cluster query calculates and returns all clusters in the dataflow graph.')
30
+ }).description('The cluster query calculates and returns all clusters in the dataflow graph.'),
31
+ flattenInvolvedNodes: (queryResults) => {
32
+ const out = queryResults;
33
+ return out.clusters.flatMap(({ members }) => members);
34
+ }
31
35
  };
32
36
  //# sourceMappingURL=cluster-query-format.js.map
@@ -13,4 +13,5 @@ export declare const ConfigQueryDefinition: {
13
13
  readonly executor: typeof executeConfigQuery;
14
14
  readonly asciiSummarizer: (formatter: OutputFormatter, _processed: unknown, queryResults: BaseQueryResult, result: string[]) => boolean;
15
15
  readonly schema: Joi.ObjectSchema<any>;
16
+ readonly flattenInvolvedNodes: () => never[];
16
17
  };
@@ -19,6 +19,7 @@ exports.ConfigQueryDefinition = {
19
19
  },
20
20
  schema: joi_1.default.object({
21
21
  type: joi_1.default.string().valid('config').required().description('The type of the query.'),
22
- }).description('The config query retrieves the current configuration of the flowR instance.')
22
+ }).description('The config query retrieves the current configuration of the flowR instance.'),
23
+ flattenInvolvedNodes: () => []
23
24
  };
24
25
  //# sourceMappingURL=config-query-format.js.map
@@ -0,0 +1,3 @@
1
+ import type { ControlFlowQuery, ControlFlowQueryResult } from './control-flow-query-format';
2
+ import type { BasicQueryData } from '../../base-query-format';
3
+ export declare function executeControlFlowQuery({ dataflow: { graph }, ast }: BasicQueryData, queries: readonly ControlFlowQuery[]): ControlFlowQueryResult;