@eagleoutice/flowr 2.5.0 → 2.6.0

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 (223) hide show
  1. package/README.md +57 -42
  2. package/cli/flowr.js +3 -29
  3. package/cli/repl/commands/repl-cfg.d.ts +5 -5
  4. package/cli/repl/commands/repl-cfg.js +21 -22
  5. package/cli/repl/commands/repl-commands.d.ts +3 -3
  6. package/cli/repl/commands/repl-commands.js +2 -0
  7. package/cli/repl/commands/repl-dataflow.d.ts +5 -5
  8. package/cli/repl/commands/repl-dataflow.js +27 -30
  9. package/cli/repl/commands/repl-execute.js +1 -0
  10. package/cli/repl/commands/repl-lineage.js +1 -0
  11. package/cli/repl/commands/repl-main.d.ts +34 -3
  12. package/cli/repl/commands/repl-normalize.d.ts +3 -3
  13. package/cli/repl/commands/repl-normalize.js +15 -19
  14. package/cli/repl/commands/repl-parse.d.ts +2 -2
  15. package/cli/repl/commands/repl-parse.js +13 -8
  16. package/cli/repl/commands/repl-query.d.ts +3 -3
  17. package/cli/repl/commands/repl-query.js +29 -19
  18. package/cli/repl/commands/repl-quit.js +1 -0
  19. package/cli/repl/commands/repl-version.js +1 -0
  20. package/cli/repl/core.d.ts +4 -1
  21. package/cli/repl/core.js +21 -1
  22. package/cli/repl/server/connection.d.ts +7 -3
  23. package/cli/repl/server/connection.js +40 -48
  24. package/cli/repl/server/messages/message-slice.d.ts +1 -1
  25. package/cli/slicer-app.js +1 -1
  26. package/config.d.ts +1 -1
  27. package/config.js +4 -1
  28. package/control-flow/extract-cfg.d.ts +1 -1
  29. package/control-flow/extract-cfg.js +1 -1
  30. package/core/pipeline-executor.d.ts +5 -0
  31. package/core/pipeline-executor.js +5 -0
  32. package/core/steps/pipeline/create-pipeline.js +1 -1
  33. package/core/steps/pipeline/default-pipelines.d.ts +42 -42
  34. package/core/steps/pipeline/default-pipelines.js +4 -1
  35. package/dataflow/graph/dataflowgraph-builder.d.ts +11 -12
  36. package/dataflow/graph/dataflowgraph-builder.js +6 -6
  37. package/documentation/doc-util/doc-query.d.ts +3 -6
  38. package/documentation/doc-util/doc-query.js +5 -17
  39. package/documentation/doc-util/doc-search.js +7 -10
  40. package/documentation/doc-util/doc-structure.d.ts +4 -0
  41. package/documentation/doc-util/doc-structure.js +28 -0
  42. package/documentation/doc-util/doc-types.d.ts +5 -1
  43. package/documentation/doc-util/doc-types.js +29 -3
  44. package/documentation/print-analyzer-wiki.d.ts +1 -0
  45. package/documentation/print-analyzer-wiki.js +137 -0
  46. package/documentation/print-core-wiki.d.ts +2 -1
  47. package/documentation/print-core-wiki.js +58 -4
  48. package/documentation/print-dataflow-graph-wiki.js +15 -22
  49. package/documentation/print-interface-wiki.js +18 -1
  50. package/documentation/print-linter-wiki.js +5 -1
  51. package/documentation/print-normalized-ast-wiki.js +6 -8
  52. package/engines.d.ts +9 -0
  53. package/engines.js +38 -0
  54. package/linter/linter-executor.d.ts +2 -8
  55. package/linter/linter-executor.js +9 -4
  56. package/linter/linter-format.d.ts +8 -9
  57. package/linter/linter-rules.d.ts +57 -15
  58. package/linter/linter-rules.js +2 -0
  59. package/linter/rules/absolute-path.d.ts +1 -0
  60. package/linter/rules/dataframe-access-validation.d.ts +4 -3
  61. package/linter/rules/dataframe-access-validation.js +7 -4
  62. package/linter/rules/dead-code.d.ts +2 -1
  63. package/linter/rules/deprecated-functions.d.ts +15 -28
  64. package/linter/rules/deprecated-functions.js +5 -43
  65. package/linter/rules/file-path-validity.d.ts +2 -1
  66. package/linter/rules/file-path-validity.js +1 -1
  67. package/linter/rules/function-finder-util.d.ts +51 -0
  68. package/linter/rules/function-finder-util.js +77 -0
  69. package/linter/rules/naming-convention.d.ts +2 -1
  70. package/linter/rules/network-functions.d.ts +40 -0
  71. package/linter/rules/network-functions.js +24 -0
  72. package/linter/rules/seeded-randomness.d.ts +2 -1
  73. package/linter/rules/unused-definition.d.ts +2 -1
  74. package/linter/rules/useless-loop.d.ts +3 -2
  75. package/linter/rules/useless-loop.js +4 -6
  76. package/package.json +2 -1
  77. package/project/cache/flowr-analyzer-cache.d.ts +93 -0
  78. package/project/cache/flowr-analyzer-cache.js +156 -0
  79. package/project/cache/flowr-cache.d.ts +28 -0
  80. package/project/cache/flowr-cache.js +49 -0
  81. package/project/context/abstract-flowr-analyzer-context.d.ts +35 -0
  82. package/project/context/abstract-flowr-analyzer-context.js +46 -0
  83. package/project/context/flowr-analyzer-context.d.ts +48 -0
  84. package/project/context/flowr-analyzer-context.js +47 -0
  85. package/project/context/flowr-analyzer-dependencies-context.d.ts +38 -0
  86. package/project/context/flowr-analyzer-dependencies-context.js +39 -0
  87. package/project/context/flowr-analyzer-files-context.d.ts +86 -0
  88. package/project/context/flowr-analyzer-files-context.js +130 -0
  89. package/project/context/flowr-analyzer-loading-order-context.d.ts +76 -0
  90. package/project/context/flowr-analyzer-loading-order-context.js +90 -0
  91. package/project/context/flowr-file.d.ts +89 -0
  92. package/project/context/flowr-file.js +78 -0
  93. package/project/flowr-analyzer-builder.d.ts +106 -0
  94. package/project/flowr-analyzer-builder.js +197 -0
  95. package/project/flowr-analyzer.d.ts +125 -0
  96. package/project/flowr-analyzer.js +81 -0
  97. package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.d.ts +17 -0
  98. package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.js +28 -0
  99. package/project/plugins/file-plugins/flowr-analyzer-file-plugin.d.ts +21 -0
  100. package/project/plugins/file-plugins/flowr-analyzer-file-plugin.js +34 -0
  101. package/project/plugins/file-plugins/flowr-description-file.d.ts +24 -0
  102. package/project/plugins/file-plugins/flowr-description-file.js +38 -0
  103. package/project/plugins/flowr-analyzer-plugin.d.ts +90 -0
  104. package/project/plugins/flowr-analyzer-plugin.js +82 -0
  105. package/project/plugins/loading-order-plugins/flowr-analyzer-loading-order-description-file-plugin.d.ts +14 -0
  106. package/project/plugins/loading-order-plugins/flowr-analyzer-loading-order-description-file-plugin.js +56 -0
  107. package/project/plugins/loading-order-plugins/flowr-analyzer-loading-order-plugin.d.ts +13 -0
  108. package/project/plugins/loading-order-plugins/flowr-analyzer-loading-order-plugin.js +33 -0
  109. package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-description-file-plugin.d.ts +14 -0
  110. package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-description-file-plugin.js +41 -0
  111. package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-plugin.d.ts +10 -0
  112. package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-plugin.js +29 -0
  113. package/project/plugins/package-version-plugins/package.d.ts +15 -0
  114. package/project/plugins/package-version-plugins/package.js +56 -0
  115. package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.d.ts +15 -0
  116. package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.js +44 -0
  117. package/queries/base-query-format.d.ts +2 -8
  118. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  119. package/queries/catalog/call-context-query/call-context-query-executor.js +20 -13
  120. package/queries/catalog/call-context-query/call-context-query-format.d.ts +2 -3
  121. package/queries/catalog/call-context-query/call-context-query-format.js +2 -2
  122. package/queries/catalog/cluster-query/cluster-query-executor.d.ts +1 -1
  123. package/queries/catalog/cluster-query/cluster-query-executor.js +2 -2
  124. package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -54
  125. package/queries/catalog/cluster-query/cluster-query-format.js +2 -2
  126. package/queries/catalog/config-query/config-query-executor.d.ts +1 -1
  127. package/queries/catalog/config-query/config-query-executor.js +5 -5
  128. package/queries/catalog/config-query/config-query-format.d.ts +1 -1
  129. package/queries/catalog/config-query/config-query-format.js +1 -1
  130. package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +1 -1
  131. package/queries/catalog/control-flow-query/control-flow-query-executor.js +2 -3
  132. package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +1 -54
  133. package/queries/catalog/control-flow-query/control-flow-query-format.js +2 -2
  134. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-executor.d.ts +1 -1
  135. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-executor.js +2 -2
  136. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -54
  137. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +1 -1
  138. package/queries/catalog/dataflow-query/dataflow-query-executor.d.ts +1 -1
  139. package/queries/catalog/dataflow-query/dataflow-query-executor.js +2 -2
  140. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -54
  141. package/queries/catalog/dataflow-query/dataflow-query-format.js +1 -1
  142. package/queries/catalog/dependencies-query/dependencies-query-executor.d.ts +1 -1
  143. package/queries/catalog/dependencies-query/dependencies-query-executor.js +19 -12
  144. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +7 -56
  145. package/queries/catalog/dependencies-query/dependencies-query-format.js +7 -4
  146. package/queries/catalog/df-shape-query/df-shape-query-executor.d.ts +1 -1
  147. package/queries/catalog/df-shape-query/df-shape-query-executor.js +4 -4
  148. package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +1 -54
  149. package/queries/catalog/df-shape-query/df-shape-query-format.js +1 -1
  150. package/queries/catalog/happens-before-query/happens-before-query-executor.d.ts +1 -1
  151. package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -1
  152. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -54
  153. package/queries/catalog/happens-before-query/happens-before-query-format.js +1 -1
  154. package/queries/catalog/id-map-query/id-map-query-executor.d.ts +1 -1
  155. package/queries/catalog/id-map-query/id-map-query-executor.js +2 -2
  156. package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -54
  157. package/queries/catalog/id-map-query/id-map-query-format.js +2 -2
  158. package/queries/catalog/lineage-query/lineage-query-executor.d.ts +1 -1
  159. package/queries/catalog/lineage-query/lineage-query-executor.js +2 -2
  160. package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -54
  161. package/queries/catalog/lineage-query/lineage-query-format.js +1 -1
  162. package/queries/catalog/linter-query/linter-query-executor.d.ts +1 -1
  163. package/queries/catalog/linter-query/linter-query-executor.js +2 -3
  164. package/queries/catalog/linter-query/linter-query-format.d.ts +1 -54
  165. package/queries/catalog/linter-query/linter-query-format.js +1 -1
  166. package/queries/catalog/location-map-query/location-map-query-executor.d.ts +1 -1
  167. package/queries/catalog/location-map-query/location-map-query-executor.js +3 -2
  168. package/queries/catalog/location-map-query/location-map-query-format.d.ts +1 -1
  169. package/queries/catalog/location-map-query/location-map-query-format.js +1 -1
  170. package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.d.ts +1 -1
  171. package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.js +2 -2
  172. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -54
  173. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +1 -1
  174. package/queries/catalog/origin-query/origin-query-executor.d.ts +2 -2
  175. package/queries/catalog/origin-query/origin-query-executor.js +3 -3
  176. package/queries/catalog/origin-query/origin-query-format.d.ts +1 -54
  177. package/queries/catalog/origin-query/origin-query-format.js +1 -1
  178. package/queries/catalog/project-query/project-query-executor.d.ts +1 -1
  179. package/queries/catalog/project-query/project-query-executor.js +2 -2
  180. package/queries/catalog/project-query/project-query-format.d.ts +1 -54
  181. package/queries/catalog/project-query/project-query-format.js +1 -1
  182. package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +1 -1
  183. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +4 -2
  184. package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +1 -54
  185. package/queries/catalog/resolve-value-query/resolve-value-query-format.js +1 -1
  186. package/queries/catalog/search-query/search-query-executor.d.ts +1 -1
  187. package/queries/catalog/search-query/search-query-executor.js +3 -3
  188. package/queries/catalog/search-query/search-query-format.d.ts +1 -54
  189. package/queries/catalog/search-query/search-query-format.js +1 -1
  190. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  191. package/queries/catalog/static-slice-query/static-slice-query-executor.js +3 -3
  192. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -54
  193. package/queries/catalog/static-slice-query/static-slice-query-format.js +1 -1
  194. package/queries/query-print.d.ts +4 -4
  195. package/queries/query-print.js +12 -12
  196. package/queries/query.d.ts +29 -885
  197. package/queries/query.js +1 -1
  198. package/r-bridge/retriever.d.ts +6 -5
  199. package/r-bridge/retriever.js +9 -5
  200. package/search/flowr-search-executor.d.ts +3 -5
  201. package/search/flowr-search-executor.js +6 -4
  202. package/search/flowr-search-filters.d.ts +12 -6
  203. package/search/flowr-search-filters.js +1 -1
  204. package/search/flowr-search.d.ts +5 -16
  205. package/search/flowr-search.js +14 -5
  206. package/search/search-executor/search-enrichers.d.ts +37 -36
  207. package/search/search-executor/search-enrichers.js +4 -4
  208. package/search/search-executor/search-generators.d.ts +12 -12
  209. package/search/search-executor/search-generators.js +27 -19
  210. package/search/search-executor/search-mappers.d.ts +5 -5
  211. package/search/search-executor/search-transformer.d.ts +17 -17
  212. package/search/search-executor/search-transformer.js +14 -7
  213. package/util/collections/arrays.d.ts +1 -0
  214. package/util/collections/arrays.js +15 -0
  215. package/util/collections/objectmap.d.ts +17 -0
  216. package/util/collections/objectmap.js +28 -0
  217. package/util/containers.d.ts +0 -1
  218. package/util/containers.js +0 -1
  219. package/util/files.d.ts +17 -0
  220. package/util/files.js +65 -0
  221. package/util/formats/adapter.d.ts +4 -2
  222. package/util/formats/adapter.js +11 -4
  223. package/util/version.js +1 -1
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const shell_1 = require("../r-bridge/shell");
7
+ const log_1 = require("../../test/functionality/_helper/log");
8
+ const doc_auto_gen_1 = require("./doc-util/doc-auto-gen");
9
+ const doc_types_1 = require("./doc-util/doc-types");
10
+ const path_1 = __importDefault(require("path"));
11
+ const flowr_analyzer_1 = require("../project/flowr-analyzer");
12
+ const flowr_analyzer_builder_1 = require("../project/flowr-analyzer-builder");
13
+ const doc_structure_1 = require("./doc-util/doc-structure");
14
+ const doc_files_1 = require("./doc-util/doc-files");
15
+ async function analyzerQuickExample() {
16
+ const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder()
17
+ .addRequestFromInput('x <- 1; print(x)')
18
+ .setEngine('tree-sitter')
19
+ .build();
20
+ // get the dataflow
21
+ const df = await analyzer.dataflow();
22
+ // obtain the identified loading order
23
+ console.log(analyzer.inspectContext().files.loadingOrder.getLoadingOrder());
24
+ // run a dependency query
25
+ const results = await analyzer.query([{ type: 'dependencies' }]);
26
+ return { analyzer, df, results };
27
+ }
28
+ async function getText(shell) {
29
+ const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
30
+ const types = (0, doc_types_1.getTypesFromFolder)({
31
+ rootFolder: path_1.default.resolve('src/'),
32
+ inlineTypes: doc_types_1.mermaidHide
33
+ });
34
+ return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'analyzer', rVersion: rversion })}
35
+
36
+ We are currently working on documenting the capabilities of the analyzer (with the plugins, their loading order, etc.). In general, the code documentation
37
+ starting with the ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, types.info)} and the ${(0, doc_types_1.shortLink)(flowr_analyzer_builder_1.FlowrAnalyzerBuilder.name, types.info)}
38
+ should be the best starting point.
39
+
40
+ ${(0, doc_structure_1.collapsibleToc)({
41
+ 'Overview': undefined,
42
+ 'Builder Configuration': undefined,
43
+ 'Plugins': {
44
+ 'Plugin Types': {
45
+ 'Dependency Identification': undefined,
46
+ 'Project Discovery': undefined,
47
+ 'File Loading': undefined,
48
+ 'Loading Order': undefined
49
+ },
50
+ 'How to add a new plugin': undefined,
51
+ 'How to add a new plugin type': undefined
52
+ },
53
+ 'Context Information': {
54
+ 'Files Context': undefined,
55
+ 'Loading Order Context': undefined,
56
+ 'Dependencies Context': undefined
57
+ },
58
+ 'Analyzer Internals': undefined
59
+ })}
60
+
61
+
62
+ ${(0, doc_structure_1.section)('Overview', 2)}
63
+
64
+ No matter whether you want to analyze a single R script, a couple of R notebooks, or a complete project,
65
+ your journey starts with the ${(0, doc_types_1.shortLink)(flowr_analyzer_builder_1.FlowrAnalyzerBuilder.name, types.info)} (further described in [Builder Configuration](#builder-configuration) below).
66
+ This builder allows you to configure the analysis in many different ways, for example, by specifying which files to analyze, which plugins to use, or
67
+ what [Engine](${doc_files_1.FlowrWikiBaseRef}/Engines) to use for the analysis.
68
+
69
+ ${(0, doc_structure_1.block)({
70
+ type: 'NOTE',
71
+ content: `If you want to quickly try out the analyzer, you can use the following code snippet that analyzes a simple R expression:
72
+
73
+ ${(0, doc_types_1.printCodeOfElement)({ program: types.program, info: types.info, dropLinesStart: 1, dropLinesEnd: 2, hideDefinedAt: true }, analyzerQuickExample.name)}
74
+ `
75
+ })}
76
+
77
+ **TODO**: mention [Context](#Context_Information)
78
+
79
+ ${(0, doc_structure_1.section)('Builder Configuration', 2)}
80
+
81
+ **TODO** also explain buildSync and that TreeSitter has to be initialized for this
82
+
83
+ ${(0, doc_structure_1.section)('Plugins', 2)}
84
+
85
+ ${(0, doc_structure_1.section)('Plugin Types', 3)}
86
+
87
+ During the construction of a new ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, types.info)}, plugins of different types are applied at different stages of the analysis.
88
+ These plugins are grouped by their ${(0, doc_types_1.shortLink)('PluginType', types.info)} and are applied in the following order (as shown in the documentation of the ${(0, doc_types_1.shortLink)('PluginType', types.info)}):
89
+
90
+ ${(() => {
91
+ const doc = (0, doc_types_1.getDocumentationForType)('PluginType', types.info);
92
+ // skip until the first ```text
93
+ const lines = doc.split('\n');
94
+ const start = lines.findIndex(l => l.trim().startsWith('```text'));
95
+ const end = lines.findIndex((l, i) => i > start && l.trim().startsWith('```'));
96
+ // github rendering pls fix xD
97
+ return start >= 0 && end > start ? '```text\n' + lines.slice(start + 1, end).join('\n').replaceAll('▶', '>') + '\n```' : doc;
98
+ })()}
99
+
100
+ We describe the different plugin types in more detail below.
101
+
102
+
103
+ ${(0, doc_structure_1.section)('Project Discovery', 4)}
104
+
105
+ ${(0, doc_structure_1.section)('File Loading', 4)}
106
+
107
+ ${(0, doc_structure_1.section)('Dependency Identification', 4)}
108
+
109
+ ${(0, doc_structure_1.section)('Loading Order', 4)}
110
+
111
+ ${(0, doc_structure_1.section)('How to add a new plugin', 3)}
112
+
113
+ ${(0, doc_structure_1.section)('How to add a new plugin type', 3)}
114
+
115
+ ${(0, doc_structure_1.section)('Context Information', 2)}
116
+
117
+ ${(0, doc_structure_1.section)('Files Context', 3)}
118
+
119
+ ${(0, doc_structure_1.section)('Loading Order Context', 3)}
120
+
121
+ ${(0, doc_structure_1.section)('Dependencies Context', 3)}
122
+
123
+ ${(0, doc_structure_1.section)('Analyzer Internals', 2)}
124
+
125
+ `;
126
+ }
127
+ /** if we run this script, we want a Markdown representation of the capabilities */
128
+ if (require.main === module) {
129
+ (0, log_1.setMinLevelOfAllLogs)(6 /* LogLevel.Fatal */);
130
+ const shell = new shell_1.RShell();
131
+ void getText(shell).then(str => {
132
+ console.log(str);
133
+ }).finally(() => {
134
+ shell.close();
135
+ });
136
+ }
137
+ //# sourceMappingURL=print-analyzer-wiki.js.map
@@ -1 +1,2 @@
1
- export {};
1
+ import { FlowrAnalyzer } from '../project/flowr-analyzer';
2
+ export declare function inspectContextExample(analyzer: FlowrAnalyzer): void;
@@ -3,6 +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.inspectContextExample = inspectContextExample;
6
7
  const shell_1 = require("../r-bridge/shell");
7
8
  const log_1 = require("../../test/functionality/_helper/log");
8
9
  const log_2 = require("../util/log");
@@ -43,6 +44,36 @@ const pipeline_executor_1 = require("../core/pipeline-executor");
43
44
  const pipeline_1 = require("../core/steps/pipeline/pipeline");
44
45
  const static_slicer_1 = require("../slicing/static/static-slicer");
45
46
  const config_1 = require("../config");
47
+ const flowr_analyzer_builder_1 = require("../project/flowr-analyzer-builder");
48
+ const flowr_analyzer_1 = require("../project/flowr-analyzer");
49
+ async function makeAnalyzerExample() {
50
+ const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder()
51
+ .addRequestFromInput('x <- 1; y <- x; print(y);')
52
+ .amendConfig(c => {
53
+ c.ignoreSourceCalls = true;
54
+ })
55
+ .setEngine('tree-sitter')
56
+ .build();
57
+ return analyzer;
58
+ }
59
+ async function extractStepsExample(analyzer) {
60
+ const normalizedAst = await analyzer.normalize();
61
+ const dataflow = await analyzer.dataflow();
62
+ const cfg = await analyzer.controlflow();
63
+ return { normalizedAst, dataflow, cfg };
64
+ }
65
+ async function sliceQueryExample(analyzer) {
66
+ const result = await analyzer.query([{
67
+ type: 'static-slice',
68
+ criteria: ['1@y']
69
+ }]);
70
+ return result;
71
+ }
72
+ function inspectContextExample(analyzer) {
73
+ const ctx = analyzer.inspectContext();
74
+ console.log('dplyr version', ctx.deps.getDependency('dplyr'));
75
+ console.log('loading order', ctx.files.loadingOrder.getLoadingOrder());
76
+ }
46
77
  async function getText(shell) {
47
78
  const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
48
79
  const sampleCode = 'x <- 1; print(x)';
@@ -80,6 +111,7 @@ See the [Getting flowR to Talk](#getting-flowr-to-talk) section below for more i
80
111
  `
81
112
  })}
82
113
 
114
+ * [Creating and Using a flowR Analyzer Instance](#creating-and-using-a-flowr-analyzer-instance)
83
115
  * [Pipelines and their Execution](#pipelines-and-their-execution)
84
116
  * [How flowR Produces Dataflow Graphs](#how-flowr-produces-dataflow-graphs)
85
117
  * [Overview](#overview)
@@ -89,10 +121,33 @@ See the [Getting flowR to Talk](#getting-flowr-to-talk) section below for more i
89
121
  * [Beyond the Dataflow Graph](#beyond-the-dataflow-graph)
90
122
  * [Static Backward Slicing](#static-backward-slicing)
91
123
  * [Getting flowR to Talk](#getting-flowr-to-talk)
92
-
124
+
125
+ ## Creating and Using a flowR Analyzer Instance
126
+
127
+ The ${(0, doc_types_1.shortLink)(flowr_analyzer_builder_1.FlowrAnalyzerBuilder.name, info)} class should be used as a starting point to create analyses in _flowR_.
128
+ It provides a fluent interface for the configuration and creation of a ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, info)} instance:
129
+
130
+ ${(0, doc_types_1.printCodeOfElement)({ program, info, dropLinesStart: 1, dropLinesEnd: 2, hideDefinedAt: true }, makeAnalyzerExample.name)}
131
+
132
+ Have a look at the [Engine](${doc_files_1.FlowrWikiBaseRef}/Engines) wiki page to understand the different engines and parsers you can use.
133
+
134
+ The analyzer instance can then be used to access analysis results like the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized-AST),
135
+ the [dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow-Graph), and the [controlflow graph](${doc_files_1.FlowrWikiBaseRef}/Control-Flow-Graph):
136
+
137
+ ${(0, doc_types_1.printCodeOfElement)({ program, info, dropLinesStart: 1, dropLinesEnd: 2, hideDefinedAt: true }, extractStepsExample.name)}
138
+
139
+ The underlying ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, info)} instance will take care of caching, updates, and running the appropriate steps.
140
+ It also exposes the [query API](${doc_files_1.FlowrWikiBaseRef}/Query-API):
141
+
142
+ ${(0, doc_types_1.printCodeOfElement)({ program, info, dropLinesStart: 1, dropLinesEnd: 2, hideDefinedAt: true }, sliceQueryExample.name)}
143
+
144
+ One of the additional advantages of using the ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, info)} is that it provides you with context information about the analyzed files:
145
+
146
+ ${(0, doc_types_1.printCodeOfElement)({ program, info, dropLinesStart: 1, dropLinesEnd: 1, hideDefinedAt: true }, inspectContextExample.name)}
147
+
93
148
  ## Pipelines and their Execution
94
149
 
95
- At the core of every analysis by flowR is the ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, info)} class which takes a sequence of analysis steps (in the form of a ${(0, doc_types_1.shortLink)('Pipeline', info)}) and executes it
150
+ At the core of every analysis done via a ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, info)} is the ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, info)} class which takes a sequence of analysis steps (in the form of a ${(0, doc_types_1.shortLink)('Pipeline', info)}) and executes it
96
151
  on a given input. In general, these pipeline steps are analysis agnostic and may use arbitrary input and ordering. However, two important and predefined pipelines,
97
152
  the ${(0, doc_types_1.shortLink)('DEFAULT_DATAFLOW_PIPELINE', info)} and the ${(0, doc_types_1.shortLink)('TREE_SITTER_DATAFLOW_PIPELINE', info)} adequately cover the most common analysis steps
98
153
  (differentiated only by the [Engine](${doc_files_1.FlowrWikiBaseRef}/Engines) used).
@@ -115,10 +170,9 @@ const executor = new PipelineExecutor(TREE_SITTER_DATAFLOW_PIPELINE, {
115
170
  const result = await executor.allRemainingSteps();
116
171
  `)}
117
172
 
118
- This is, roughly, what the ${(0, doc_types_1.shortLink)('replGetDataflow', info)} function does for the ${(0, doc_cli_option_1.getReplCommand)('dataflow')} REPL command when using the [\`tree-sitter\` engine](${doc_files_1.FlowrWikiBaseRef}/Engines).
173
+ This is, roughly, what the ${(0, doc_types_1.shortLink)('dataflow', info)} function does when using the [\`tree-sitter\` engine](${doc_files_1.FlowrWikiBaseRef}/Engines).
119
174
  We create a new ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, info)} with the ${(0, doc_types_1.shortLink)('TREE_SITTER_DATAFLOW_PIPELINE', info)} and then use ${(0, doc_types_1.shortLink)(`${pipeline_executor_1.PipelineExecutor.name}::${new pipeline_executor_1.PipelineExecutor(default_pipelines_1.TREE_SITTER_PARSE_PIPELINE, { parser: new tree_sitter_executor_1.TreeSitterExecutor(), request: (0, retriever_1.requestFromInput)('') }, config_1.defaultConfigOptions).allRemainingSteps.name}`, info)}
120
175
  to cause the execution of all contained steps (in general, pipelines can be executed step-by-step, but this is usually not required if you just want the result).
121
- ${(0, doc_types_1.shortLink)(retriever_1.requestFromInput.name, info)} is merely a convenience function to create a request object from a code string.
122
176
 
123
177
  In general, however, most flowR-internal functions which are tasked with generating dataflow prefer the use of ${(0, doc_types_1.shortLink)(default_pipelines_1.createDataflowPipeline.name, info)} as this function
124
178
  automatically selects the correct pipeline based on the engine used.
@@ -11,7 +11,6 @@ const dataflowgraph_builder_1 = require("../dataflow/graph/dataflowgraph-builder
11
11
  const assert_1 = require("../util/assert");
12
12
  const doc_dfg_1 = require("./doc-util/doc-dfg");
13
13
  const doc_files_1 = require("./doc-util/doc-files");
14
- const pipeline_executor_1 = require("../core/pipeline-executor");
15
14
  const retriever_1 = require("../r-bridge/retriever");
16
15
  const json_1 = require("../util/json");
17
16
  const doc_env_1 = require("./doc-util/doc-env");
@@ -39,6 +38,7 @@ const doc_issue_1 = require("./doc-util/doc-issue");
39
38
  const unnamed_call_handling_1 = require("../dataflow/internal/process/functions/call/unnamed-call-handling");
40
39
  const environment_builder_1 = require("../../test/functionality/_helper/dataflow/environment-builder");
41
40
  const config_1 = require("../config");
41
+ const flowr_analyzer_builder_1 = require("../project/flowr-analyzer-builder");
42
42
  async function subExplanation(shell, { description, code, expectedSubgraph }) {
43
43
  expectedSubgraph = await (0, doc_dfg_1.verifyExpectedSubgraph)(shell, code, expectedSubgraph);
44
44
  const marks = [];
@@ -742,12 +742,9 @@ ${(0, doc_structure_1.details)('Example: While-Loop Body', await (0, doc_dfg_1.p
742
742
  return results.join('\n');
743
743
  }
744
744
  async function dummyDataflow() {
745
- const shell = new shell_1.RShell();
746
- const result = await new pipeline_executor_1.PipelineExecutor(default_pipelines_1.DEFAULT_DATAFLOW_PIPELINE, {
747
- parser: shell,
748
- request: (0, retriever_1.requestFromInput)('x <- 1\nx + 1')
749
- }, config_1.defaultConfigOptions).allRemainingSteps();
750
- shell.close();
745
+ const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder((0, retriever_1.requestFromInput)('x <- 1\nx + 1')).build();
746
+ const result = await analyzer.dataflow();
747
+ analyzer.close();
751
748
  return result;
752
749
  }
753
750
  async function getText(shell) {
@@ -879,16 +876,12 @@ ${(0, doc_structure_1.details)('Example: Nested Conditionals', await (0, doc_dfg
879
876
 
880
877
  ${(0, doc_structure_1.section)('Dataflow Information', 2, 'dataflow-information')}
881
878
 
882
- Using _flowR's_ code interface (see the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface) wiki page for more), you can generate the dataflow information
883
- for a given piece of R code (in this case \`x <- 1; x + 1\`) as follows (using the ${(0, doc_types_1.shortLink)(shell_1.RShell.name, vertexType.info)} and the ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, vertexType.info)} classes):
879
+ Using _flowR's_ code interface (see the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface#creating-flowr-analyses) wiki page for more), you can generate the dataflow information
880
+ for a given piece of R code (in this case \`x <- 1; x + 1\`) as follows:
884
881
 
885
882
  ${(0, doc_code_1.codeBlock)('ts', `
886
- const shell = new ${shell_1.RShell.name}()
887
- const result = await new ${pipeline_executor_1.PipelineExecutor.name}(DEFAULT_DATAFLOW_PIPELINE, {
888
- shell,
889
- request: ${retriever_1.requestFromInput.name}('x <- 1; x + 1')
890
- }).allRemainingSteps();
891
- shell.close();
883
+ const analyzer = await new FlowrAnalyzerBuilder(requestFromInput('x <- 1\nx + 1')).build();
884
+ const result = await analyzer.dataflow();
892
885
  `)}
893
886
 
894
887
  <details>
@@ -906,7 +899,7 @@ Now, you can find the dataflow _information_ with \`result.dataflow\`. More spec
906
899
 
907
900
  ${await (async () => {
908
901
  const result = await dummyDataflow();
909
- const dfGraphString = (0, doc_dfg_1.printDfGraph)(result.dataflow.graph);
902
+ const dfGraphString = (0, doc_dfg_1.printDfGraph)(result.graph);
910
903
  return `
911
904
  ${dfGraphString}
912
905
 
@@ -917,7 +910,7 @@ However, the dataflow information contains more, quite a lot of information in f
917
910
  <summary style="color:gray">Dataflow Information as Json</summary>
918
911
 
919
912
  _As the information is pretty long, we inhibit pretty printing and syntax highlighting:_
920
- ${(0, doc_code_1.codeBlock)('text', JSON.stringify(result.dataflow, json_1.jsonReplacer))}
913
+ ${(0, doc_code_1.codeBlock)('text', JSON.stringify(result, json_1.jsonReplacer))}
921
914
 
922
915
  </details>
923
916
 
@@ -925,16 +918,16 @@ You may be interested in its implementation:
925
918
 
926
919
  ${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexType.info, root: 'DataflowInformation' })}
927
920
 
928
- Let's start by looking at the properties of the dataflow information object: ${Object.keys(result.dataflow).map(k => `\`${k}\``).join(', ')}.
921
+ Let's start by looking at the properties of the dataflow information object: ${Object.keys(result).map(k => `\`${k}\``).join(', ')}.
929
922
 
930
923
  ${(() => {
931
924
  /* this includes the meta field for timing */
932
- (0, assert_1.guard)(Object.keys(result.dataflow).length === 8, () => 'Update Dataflow Documentation!');
925
+ (0, assert_1.guard)(Object.keys(result).length === 8, () => 'Update Dataflow Documentation!');
933
926
  return '';
934
927
  })()}
935
928
 
936
929
  There are three sets of references.
937
- **in** (ids: ${JSON.stringify(new Set(result.dataflow.in.map(n => n.nodeId)), json_1.jsonReplacer)}) and **out** (ids: ${JSON.stringify(new Set(result.dataflow.out.map(n => n.nodeId)), json_1.jsonReplacer)}) contain the
930
+ **in** (ids: ${JSON.stringify(new Set(result.in.map(n => n.nodeId)), json_1.jsonReplacer)}) and **out** (ids: ${JSON.stringify(new Set(result.out.map(n => n.nodeId)), json_1.jsonReplacer)}) contain the
938
931
  ingoing and outgoing references of the subgraph at hand (in this case, the whole code, as we are at the end of the dataflow analysis).
939
932
  Besides the Ids, they also contain important meta-information (e.g., what is to be read).
940
933
  The third set, **unknownReferences**, contains all references that are not yet identified as read or written
@@ -944,12 +937,12 @@ The **environment** property contains the active environment information of the
944
937
  In other words, this is a linked list of tables (scopes), mapping identifiers to their respective definitions.
945
938
  A summarized version of the produced environment looks like this:
946
939
 
947
- ${(0, doc_env_1.printEnvironmentToMarkdown)(result.dataflow.environment.current)}
940
+ ${(0, doc_env_1.printEnvironmentToMarkdown)(result.environment.current)}
948
941
 
949
942
  This shows us that the local environment contains a single definition for \`x\` (with id 0) and that the parent environment is the built-in environment.
950
943
  Additionally, we get the information that the node with the id 2 was responsible for the definition of \`x\`.
951
944
 
952
- Last but not least, the information contains the single **entry point** (${JSON.stringify(result.dataflow.entryPoint)}) and a set of **exit points** (${JSON.stringify(result.dataflow.exitPoints.map(e => e.nodeId))}).
945
+ Last but not least, the information contains the single **entry point** (${JSON.stringify(result.entryPoint)}) and a set of **exit points** (${JSON.stringify(result.exitPoints.map(e => e.nodeId))}).
953
946
  Besides marking potential exits, the exit points also provide information about why the exit occurs and which control dependencies affect the exit.
954
947
 
955
948
  ### Unknown Side Effects
@@ -25,6 +25,7 @@ const doc_structure_1 = require("./doc-util/doc-structure");
25
25
  const doc_types_1 = require("./doc-util/doc-types");
26
26
  const path_1 = __importDefault(require("path"));
27
27
  const tree_sitter_executor_1 = require("../r-bridge/lang-4.x/tree-sitter/tree-sitter-executor");
28
+ const flowr_analyzer_1 = require("../project/flowr-analyzer");
28
29
  async function explainServer(shell) {
29
30
  (0, doc_data_server_messages_1.documentAllServerMessages)();
30
31
  return `
@@ -295,13 +296,29 @@ ${(0, doc_types_1.shortLink)(shell_1.RShell.name + '::' + shell.sendCommandWithO
295
296
 
296
297
  Besides that, the command ${(0, doc_types_1.shortLink)(shell_1.RShell.name + '::' + shell.tryToInjectHomeLibPath.name, types.info)} may be of interest, as it enables all libraries available on the host system.
297
298
 
299
+ ### Creating _flowR_ analyses
300
+
301
+ Nowadays, instances of ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, types.info)} should be used as central frontend to get analysis results from _flowR_.
302
+ For example, a program slice can be created like this:
303
+
304
+ ${(0, doc_code_1.codeBlock)('ts', `
305
+ const analyzer = await new FlowrAnalyzerBuilder(requestFromInput('x <- 1\\ny <- x\\nx')).build();
306
+ const result = await analyzer.query([
307
+ {
308
+ type: 'static-slice',
309
+ criteria: ['3@x']
310
+ }
311
+ ]);
312
+ //console.log(result['static-slice']);
313
+ `)}
314
+
298
315
  ### The Pipeline Executor
299
316
 
300
317
  Once, in the beginning, _flowR_ was meant to produce a dataflow graph merely to provide *program slices*.
301
318
  However, with continuous updates, the [dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow%20Graph) repeatedly proves to be the more interesting part.
302
319
  With this, we restructured _flowR_'s originally *hardcoded* pipeline to be far more flexible.
303
320
  Now, it can be theoretically extended or replaced with arbitrary steps, optional steps, and what we call 'decorations' of these steps.
304
- In short, if you still "just want to slice" you can do it like this with the ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, types.info)}:
321
+ In short, a slicing pipeline using the ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, types.info)} looks like this:
305
322
 
306
323
  ${(0, doc_code_1.codeBlock)('ts', `
307
324
  const slicer = new ${pipeline_executor_1.PipelineExecutor.name}(DEFAULT_SLICING_PIPELINE, {
@@ -87,10 +87,14 @@ See [here](${(0, doc_types_1.getTypePathLink)({ filePath: report.source.fileName
87
87
  }
88
88
  function registerRules(rVersion, shell, tagTypes, format = 'short') {
89
89
  const ruleExplanations = new Map();
90
- rule(shell, 'deprecated-functions', 'DeprecatedFunctionsConfig', 'DEPRECATED_FUNCTIONS', 'lint-deprecated-functions', `
90
+ rule(shell, 'deprecated-functions', 'FunctionsToDetectConfig', 'DEPRECATED_FUNCTIONS', 'lint-deprecated-functions', `
91
91
  first <- data.frame(x = c(1, 2, 3), y = c(1, 2, 3))
92
92
  second <- data.frame(x = c(1, 3, 2), y = c(1, 3, 2))
93
93
  dplyr::all_equal(first, second)
94
+ `, tagTypes);
95
+ rule(shell, 'network-functions', 'NetworkFunctionsConfig', 'NETWORK_FUNCTIONS', 'lint-network-functions', `
96
+ read.csv("https://example.com/data.csv")
97
+ download.file("https://foo.bar")
94
98
  `, tagTypes);
95
99
  rule(shell, 'file-path-validity', 'FilePathValidityConfig', 'FILE_PATH_VALIDITY', 'lint-file-path-validity', `
96
100
  my_data <- read.csv("C:/Users/me/Documents/My R Scripts/Reproducible.csv")
@@ -20,6 +20,7 @@ const visitor_1 = require("../r-bridge/lang-4.x/ast/model/processing/visitor");
20
20
  const collect_1 = require("../r-bridge/lang-4.x/ast/model/collect");
21
21
  const normalized_ast_fold_1 = require("../abstract-interpretation/normalized-ast-fold");
22
22
  const default_pipelines_1 = require("../core/steps/pipeline/default-pipelines");
23
+ const flowr_analyzer_1 = require("../project/flowr-analyzer");
23
24
  async function getText(shell) {
24
25
  const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
25
26
  const now = performance.now();
@@ -91,17 +92,14 @@ The following segments intend to give you an overview of how to work with the no
91
92
 
92
93
  ## How to Get a Normalized AST
93
94
 
94
- As explained alongside the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface#the-pipeline-executor) wiki page, you can use the
95
- ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, types.info)} to get the ${(0, doc_types_1.shortLink)('NormalizedAst', types.info)}. If you are only interested in the normalization,
96
- a pipeline like the ${(0, doc_types_1.shortLink)('DEFAULT_NORMALIZE_PIPELINE', types.info)} suffices:
95
+ As explained alongside the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface#creating-flowr-analyses) wiki page, you can use an instance of
96
+ ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, types.info)} to get the ${(0, doc_types_1.shortLink)('NormalizedAst', types.info)}:
97
97
 
98
98
  ${(0, doc_code_1.codeBlock)('ts', `
99
99
  async function getAst(code: string): Promise<RNode> {
100
- const result = await new ${pipeline_executor_1.PipelineExecutor.name}(DEFAULT_NORMALIZE_PIPELINE, {
101
- parser: new ${shell_1.RShell.name}(),
102
- request: ${retriever_1.requestFromInput.name}(code.trim())
103
- }).allRemainingSteps();
104
- return result.normalize.ast;
100
+ const analyzer = await new FlowrAnalyzerBuilder(${retriever_1.requestFromInput.name}(code.trim())).build();
101
+ const result = analyzer.normalizedAst();
102
+ return result.ast;
105
103
  }`)}
106
104
 
107
105
  From the REPL, you can use the ${(0, doc_cli_option_1.getReplCommand)('normalize')} command.
package/engines.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import type { FlowrConfigOptions, KnownEngines } from './config';
2
+ /**
3
+ * Retrieve all requested engine instance.
4
+ * Please make sure that if this includes the R engine, that you properly shut it down again!
5
+ */
6
+ export declare function retrieveEngineInstances(config: FlowrConfigOptions, defaultOnly?: boolean): Promise<{
7
+ engines: KnownEngines;
8
+ default: keyof KnownEngines;
9
+ }>;
package/engines.js ADDED
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.retrieveEngineInstances = retrieveEngineInstances;
4
+ const config_1 = require("./config");
5
+ const shell_1 = require("./r-bridge/shell");
6
+ const ansi_1 = require("./util/text/ansi");
7
+ const tree_sitter_executor_1 = require("./r-bridge/lang-4.x/tree-sitter/tree-sitter-executor");
8
+ const log_1 = require("./util/log");
9
+ /**
10
+ * Retrieve all requested engine instance.
11
+ * Please make sure that if this includes the R engine, that you properly shut it down again!
12
+ */
13
+ async function retrieveEngineInstances(config, defaultOnly = false) {
14
+ const engines = {};
15
+ if ((0, config_1.getEngineConfig)(config, 'r-shell') && (!defaultOnly || config.defaultEngine === 'r-shell')) {
16
+ // we keep an active shell session to allow other parse investigations :)
17
+ engines['r-shell'] = new shell_1.RShell((0, config_1.getEngineConfig)(config, 'r-shell'), {
18
+ revive: 2 /* RShellReviveOptions.Always */,
19
+ onRevive: (code, signal) => {
20
+ const signalText = signal == null ? '' : ` and signal ${signal}`;
21
+ console.log(ansi_1.formatter.format(`R process exited with code ${code}${signalText}. Restarting...`, { color: 5 /* Colors.Magenta */, effect: ansi_1.ColorEffect.Foreground }));
22
+ console.log((0, ansi_1.italic)(`If you want to exit, press either Ctrl+C twice, or enter ${(0, ansi_1.bold)(':quit')}`));
23
+ }
24
+ });
25
+ }
26
+ if ((0, config_1.getEngineConfig)(config, 'tree-sitter') && (!defaultOnly || config.defaultEngine === 'tree-sitter')) {
27
+ await tree_sitter_executor_1.TreeSitterExecutor.initTreeSitter((0, config_1.getEngineConfig)(config, 'tree-sitter'));
28
+ engines['tree-sitter'] = new tree_sitter_executor_1.TreeSitterExecutor();
29
+ }
30
+ let defaultEngine = config.defaultEngine;
31
+ if (!defaultEngine || !engines[defaultEngine]) {
32
+ // if a default engine isn't specified, we just take the first one we have
33
+ defaultEngine = Object.keys(engines)[0];
34
+ }
35
+ log_1.log.info(`Using engines ${Object.keys(engines).join(', ')} with default ${defaultEngine}`);
36
+ return { engines, default: defaultEngine };
37
+ }
38
+ //# sourceMappingURL=engines.js.map
@@ -1,11 +1,5 @@
1
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
2
  import type { LintingResults } from './linter-format';
5
3
  import type { DeepPartial } from 'ts-essentials';
6
- import type { FlowrConfigOptions } from '../config';
7
- export declare function executeLintingRule<Name extends LintingRuleNames>(ruleName: Name, input: {
8
- normalize: NormalizedAst;
9
- dataflow: DataflowInformation;
10
- config: FlowrConfigOptions;
11
- }, lintingRuleConfig?: DeepPartial<LintingRuleConfig<Name>>): LintingResults<Name>;
4
+ import type { FlowrAnalysisProvider } from '../project/flowr-analyzer';
5
+ export declare function executeLintingRule<Name extends LintingRuleNames>(ruleName: Name, input: FlowrAnalysisProvider, lintingRuleConfig?: DeepPartial<LintingRuleConfig<Name>>): Promise<LintingResults<Name>>;
@@ -4,16 +4,21 @@ exports.executeLintingRule = executeLintingRule;
4
4
  const linter_rules_1 = require("./linter-rules");
5
5
  const flowr_search_executor_1 = require("../search/flowr-search-executor");
6
6
  const objects_1 = require("../util/objects");
7
- function executeLintingRule(ruleName, input, lintingRuleConfig) {
7
+ async function executeLintingRule(ruleName, input, lintingRuleConfig) {
8
8
  try {
9
9
  const rule = linter_rules_1.LintingRules[ruleName];
10
10
  const fullConfig = (0, objects_1.deepMergeObject)(rule.info.defaultConfig, lintingRuleConfig);
11
- const ruleSearch = rule.createSearch(fullConfig, input);
11
+ const ruleSearch = rule.createSearch(fullConfig);
12
12
  const searchStart = Date.now();
13
- const searchResult = (0, flowr_search_executor_1.runSearch)(ruleSearch, input);
13
+ const searchResult = await (0, flowr_search_executor_1.runSearch)(ruleSearch, input);
14
14
  const searchTime = Date.now() - searchStart;
15
15
  const processStart = Date.now();
16
- const result = rule.processSearchResult(searchResult, fullConfig, input);
16
+ const result = await rule.processSearchResult(searchResult, fullConfig, {
17
+ normalize: await input.normalize(),
18
+ dataflow: await input.dataflow(),
19
+ cfg: await input.controlflow(),
20
+ config: input.flowrConfig,
21
+ });
17
22
  const processTime = Date.now() - processStart;
18
23
  return {
19
24
  ...result,
@@ -5,11 +5,12 @@ import type { GeneratorNames } from '../search/search-executor/search-generators
5
5
  import type { TransformerNames } from '../search/search-executor/search-transformer';
6
6
  import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
7
7
  import type { LintingRuleConfig, LintingRuleMetadata, LintingRuleNames, LintingRuleResult } from './linter-rules';
8
- import type { DataflowInformation } from '../dataflow/info';
9
- import type { FlowrConfigOptions } from '../config';
10
- import type { DeepPartial, DeepReadonly } from 'ts-essentials';
8
+ import type { AsyncOrSync, DeepPartial, DeepReadonly } from 'ts-essentials';
11
9
  import type { LintingRuleTag } from './linter-tags';
12
10
  import type { SourceRange } from '../util/range';
11
+ import type { DataflowInformation } from '../dataflow/info';
12
+ import type { FlowrConfigOptions } from '../config';
13
+ import type { ControlFlowInformation } from '../control-flow/control-flow-graph';
13
14
  export interface LinterRuleInformation<Config extends MergeableRecord = never> {
14
15
  /** Human-Readable name of the linting rule. */
15
16
  readonly name: string;
@@ -41,10 +42,7 @@ export interface LintingRule<Result extends LintingResult, Metadata extends Merg
41
42
  * Creates a flowR search that will then be executed and whose results will be passed to {@link processSearchResult}.
42
43
  * In the future, additional optimizations and transformations may be applied to the search between this function and {@link processSearchResult}.
43
44
  */
44
- readonly createSearch: (config: Config, data: {
45
- normalize: NormalizedAst;
46
- dataflow: DataflowInformation;
47
- }) => FlowrSearchLike<Info, GeneratorNames, TransformerNames[], FlowrSearchElements<Info, Elements>>;
45
+ readonly createSearch: (config: Config) => FlowrSearchLike<Info, GeneratorNames, TransformerNames[], FlowrSearchElements<Info, Elements>>;
48
46
  /**
49
47
  * Processes the search results of the search created through {@link createSearch}.
50
48
  * This function is expected to return the linting results from this rule for the given search, ie usually the given script file.
@@ -52,11 +50,12 @@ export interface LintingRule<Result extends LintingResult, Metadata extends Merg
52
50
  readonly processSearchResult: (elements: FlowrSearchElements<Info, Elements>, config: Config, data: {
53
51
  normalize: NormalizedAst;
54
52
  dataflow: DataflowInformation;
53
+ cfg: ControlFlowInformation;
55
54
  config: FlowrConfigOptions;
56
- }) => {
55
+ }) => AsyncOrSync<{
57
56
  results: Result[];
58
57
  '.meta': Metadata;
59
- };
58
+ }>;
60
59
  /**
61
60
  * A set of functions used to pretty-print the given linting result.
62
61
  * By default, the {@link LintingResult#certainty} and whether any {@link LintingResult#quickFix} values are available is automatically printed alongside this information.