@eagleoutice/flowr 2.7.6 → 2.8.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 (208) hide show
  1. package/README.md +67 -64
  2. package/cli/wiki.js +1 -1
  3. package/control-flow/extract-cfg.js +3 -3
  4. package/control-flow/useless-loop.d.ts +1 -1
  5. package/control-flow/useless-loop.js +2 -2
  6. package/dataflow/cluster.js +3 -3
  7. package/dataflow/environments/built-in-config.d.ts +8 -4
  8. package/dataflow/environments/built-in.d.ts +27 -14
  9. package/dataflow/environments/built-in.js +27 -12
  10. package/dataflow/environments/default-builtin-config.d.ts +614 -3
  11. package/dataflow/environments/default-builtin-config.js +50 -15
  12. package/dataflow/environments/environment.js +3 -2
  13. package/dataflow/environments/identifier.d.ts +5 -1
  14. package/dataflow/environments/reference-to-maybe.d.ts +2 -2
  15. package/dataflow/environments/reference-to-maybe.js +23 -14
  16. package/dataflow/environments/resolve-by-name.d.ts +6 -2
  17. package/dataflow/environments/resolve-by-name.js +5 -1
  18. package/dataflow/environments/scoping.js +1 -3
  19. package/dataflow/eval/resolve/alias-tracking.js +5 -1
  20. package/dataflow/extractor.js +3 -3
  21. package/dataflow/fn/exceptions-of-function.d.ts +13 -0
  22. package/dataflow/fn/exceptions-of-function.js +47 -0
  23. package/dataflow/fn/higher-order-function.d.ts +1 -1
  24. package/dataflow/fn/higher-order-function.js +3 -3
  25. package/dataflow/fn/recursive-function.d.ts +6 -0
  26. package/dataflow/fn/recursive-function.js +32 -0
  27. package/dataflow/graph/call-graph.d.ts +10 -0
  28. package/dataflow/graph/call-graph.js +209 -0
  29. package/dataflow/graph/dataflowgraph-builder.d.ts +7 -2
  30. package/dataflow/graph/dataflowgraph-builder.js +14 -9
  31. package/dataflow/graph/diff-dataflow-graph.js +96 -2
  32. package/dataflow/graph/graph.d.ts +10 -7
  33. package/dataflow/graph/graph.js +7 -8
  34. package/dataflow/graph/vertex.d.ts +6 -3
  35. package/dataflow/hooks.d.ts +30 -0
  36. package/dataflow/hooks.js +38 -0
  37. package/dataflow/info.d.ts +28 -5
  38. package/dataflow/info.js +66 -31
  39. package/dataflow/internal/linker.d.ts +13 -3
  40. package/dataflow/internal/linker.js +155 -53
  41. package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +4 -0
  42. package/dataflow/internal/process/functions/call/argument/unpack-argument.js +7 -0
  43. package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +1 -1
  44. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +19 -3
  45. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +14 -0
  46. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +30 -0
  47. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +2 -1
  48. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +24 -17
  49. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -1
  50. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +5 -1
  51. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +59 -21
  52. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +4 -3
  53. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.d.ts +34 -0
  54. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.js +92 -0
  55. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +1 -0
  56. package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.d.ts +21 -0
  57. package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.js +129 -0
  58. package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.d.ts +16 -0
  59. package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.js +127 -0
  60. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +5 -3
  61. package/dataflow/internal/process/functions/call/common.d.ts +13 -1
  62. package/dataflow/internal/process/functions/call/common.js +33 -2
  63. package/dataflow/internal/process/functions/call/known-call-handling.d.ts +13 -1
  64. package/dataflow/internal/process/functions/call/known-call-handling.js +29 -3
  65. package/dataflow/internal/process/functions/call/named-call-handling.js +2 -1
  66. package/dataflow/internal/process/functions/call/unnamed-call-handling.js +6 -4
  67. package/dataflow/internal/process/functions/process-argument.js +7 -6
  68. package/dataflow/internal/process/functions/process-parameter.js +2 -1
  69. package/dataflow/internal/process/process-named-call.d.ts +2 -2
  70. package/dataflow/internal/process/process-symbol.js +3 -2
  71. package/dataflow/internal/process/process-value.d.ts +3 -2
  72. package/dataflow/internal/process/process-value.js +8 -6
  73. package/dataflow/origin/dfg-get-origin.js +2 -1
  74. package/dataflow/origin/dfg-get-symbol-refs.js +1 -1
  75. package/documentation/doc-readme.d.ts +1 -1
  76. package/documentation/doc-readme.js +6 -6
  77. package/documentation/doc-util/doc-code.js +1 -1
  78. package/documentation/doc-util/doc-dfg.d.ts +1 -0
  79. package/documentation/doc-util/doc-dfg.js +7 -4
  80. package/documentation/doc-util/doc-query.d.ts +1 -0
  81. package/documentation/doc-util/doc-query.js +1 -1
  82. package/documentation/doc-util/doc-repl.d.ts +2 -1
  83. package/documentation/doc-util/doc-repl.js +11 -3
  84. package/documentation/wiki-analyzer.js +2 -0
  85. package/documentation/wiki-dataflow-graph.js +59 -16
  86. package/documentation/wiki-interface.js +33 -5
  87. package/documentation/wiki-mk/doc-context.d.ts +2 -1
  88. package/documentation/wiki-mk/doc-context.js +2 -2
  89. package/documentation/wiki-mk/doc-maker.js +4 -3
  90. package/documentation/wiki-normalized-ast.js +6 -0
  91. package/documentation/wiki-query.js +109 -1
  92. package/linter/linter-rules.d.ts +1 -1
  93. package/linter/rules/seeded-randomness.js +17 -12
  94. package/linter/rules/useless-loop.d.ts +1 -1
  95. package/package.json +9 -9
  96. package/project/cache/flowr-analyzer-cache.d.ts +11 -0
  97. package/project/cache/flowr-analyzer-cache.js +19 -0
  98. package/project/context/flowr-analyzer-dependencies-context.d.ts +6 -1
  99. package/project/context/flowr-analyzer-dependencies-context.js +6 -0
  100. package/project/context/flowr-analyzer-files-context.d.ts +5 -2
  101. package/project/context/flowr-analyzer-files-context.js +24 -17
  102. package/project/context/flowr-file.d.ts +9 -4
  103. package/project/context/flowr-file.js +20 -6
  104. package/project/flowr-analyzer.d.ts +11 -0
  105. package/project/flowr-analyzer.js +6 -0
  106. package/project/plugins/file-plugins/files/flowr-description-file.d.ts +8 -0
  107. package/project/plugins/file-plugins/files/flowr-description-file.js +36 -3
  108. package/project/plugins/file-plugins/files/flowr-jupyter-file.js +1 -1
  109. package/project/plugins/file-plugins/files/flowr-namespace-file.js +1 -1
  110. package/project/plugins/file-plugins/files/flowr-news-file.js +1 -1
  111. package/project/plugins/file-plugins/files/flowr-rmarkdown-file.js +1 -1
  112. package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.js +1 -1
  113. package/project/plugins/file-plugins/flowr-analyzer-file-plugin.d.ts +4 -1
  114. package/project/plugins/file-plugins/flowr-analyzer-file-plugin.js +3 -0
  115. package/project/plugins/file-plugins/{flowr-analyzer-namespace-file-plugin.d.ts → flowr-analyzer-namespace-files-plugin.d.ts} +1 -1
  116. package/project/plugins/file-plugins/{flowr-analyzer-namespace-file-plugin.js → flowr-analyzer-namespace-files-plugin.js} +4 -4
  117. package/project/plugins/file-plugins/flowr-analyzer-test-file-plugin.d.ts +26 -0
  118. package/project/plugins/file-plugins/flowr-analyzer-test-file-plugin.js +39 -0
  119. package/project/plugins/file-plugins/flowr-analyzer-vignette-file-plugin.d.ts +26 -0
  120. package/project/plugins/file-plugins/flowr-analyzer-vignette-file-plugin.js +39 -0
  121. package/project/plugins/flowr-analyzer-plugin-defaults.js +6 -2
  122. package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-description-file-plugin.js +3 -13
  123. package/project/plugins/package-version-plugins/package.d.ts +1 -1
  124. package/project/plugins/package-version-plugins/package.js +3 -3
  125. package/project/plugins/plugin-registry.d.ts +4 -2
  126. package/project/plugins/plugin-registry.js +6 -2
  127. package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.d.ts +11 -0
  128. package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.js +5 -2
  129. package/queries/catalog/call-context-query/call-context-query-format.d.ts +4 -12
  130. package/queries/catalog/call-graph-query/call-graph-query-executor.d.ts +6 -0
  131. package/queries/catalog/call-graph-query/call-graph-query-executor.js +21 -0
  132. package/queries/catalog/call-graph-query/call-graph-query-format.d.ts +21 -0
  133. package/queries/catalog/call-graph-query/call-graph-query-format.js +32 -0
  134. package/queries/catalog/dataflow-query/dataflow-query-executor.js +4 -3
  135. package/queries/catalog/dependencies-query/dependencies-query-executor.js +29 -3
  136. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -0
  137. package/queries/catalog/dependencies-query/function-info/function-info.d.ts +8 -1
  138. package/queries/catalog/dependencies-query/function-info/write-functions.js +13 -0
  139. package/queries/catalog/does-call-query/does-call-query-executor.d.ts +6 -0
  140. package/queries/catalog/does-call-query/does-call-query-executor.js +100 -0
  141. package/queries/catalog/does-call-query/does-call-query-format.d.ts +51 -0
  142. package/queries/catalog/does-call-query/does-call-query-format.js +102 -0
  143. package/queries/catalog/files-query/files-query-executor.js +4 -4
  144. package/queries/catalog/files-query/files-query-format.d.ts +2 -1
  145. package/queries/catalog/files-query/files-query-format.js +18 -2
  146. package/queries/catalog/id-map-query/id-map-query-executor.js +4 -3
  147. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +18 -0
  148. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +56 -0
  149. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +34 -0
  150. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.js +54 -0
  151. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -28
  152. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +6 -0
  153. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.js +12 -0
  154. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-executor.d.ts +6 -0
  155. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-executor.js +23 -0
  156. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +28 -0
  157. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.js +44 -0
  158. package/queries/catalog/linter-query/linter-query-format.js +4 -1
  159. package/queries/catalog/location-map-query/location-map-query-executor.js +1 -1
  160. package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.js +4 -3
  161. package/queries/catalog/project-query/project-query-executor.js +9 -3
  162. package/queries/catalog/project-query/project-query-format.d.ts +6 -1
  163. package/queries/catalog/project-query/project-query-format.js +35 -9
  164. package/queries/query.d.ts +34 -2
  165. package/queries/query.js +9 -0
  166. package/r-bridge/data/data.d.ts +10 -5
  167. package/r-bridge/data/data.js +11 -5
  168. package/r-bridge/lang-4.x/ast/model/model.d.ts +7 -7
  169. package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +2 -2
  170. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +2 -2
  171. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +2 -2
  172. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +5 -2
  173. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +8 -0
  174. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +2 -2
  175. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +2 -2
  176. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +3 -3
  177. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +2 -2
  178. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +2 -2
  179. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +2 -2
  180. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +2 -2
  181. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +2 -2
  182. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +2 -2
  183. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +2 -2
  184. package/r-bridge/lang-4.x/ast/parser/main/internal/other/normalize-comment.js +0 -1
  185. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +0 -2
  186. package/r-bridge/roxygen2/roxygen-ast.d.ts +218 -0
  187. package/r-bridge/roxygen2/roxygen-ast.js +82 -0
  188. package/r-bridge/roxygen2/roxygen-parse.d.ts +24 -0
  189. package/r-bridge/roxygen2/roxygen-parse.js +214 -0
  190. package/reconstruct/auto-select/magic-comments.js +4 -4
  191. package/slicing/static/slice-call.js +3 -4
  192. package/slicing/static/static-slicer.js +2 -2
  193. package/statistics/features/supported/defined-functions/defined-functions.js +1 -1
  194. package/util/collections/defaultmap.d.ts +3 -3
  195. package/util/mermaid/dfg.js +5 -5
  196. package/util/objects.js +1 -1
  197. package/util/r-author.d.ts +5 -0
  198. package/util/r-author.js +110 -0
  199. package/util/r-license.d.ts +10 -1
  200. package/util/r-license.js +27 -6
  201. package/util/r-version.d.ts +19 -0
  202. package/util/r-version.js +106 -0
  203. package/util/range.d.ts +6 -0
  204. package/util/range.js +7 -0
  205. package/util/simple-df/dfg-ascii.js +2 -2
  206. package/util/text/args.d.ts +9 -0
  207. package/util/text/args.js +65 -0
  208. package/util/version.js +1 -1
@@ -5,9 +5,10 @@ const graph_1 = require("../../graph/graph");
5
5
  const vertex_1 = require("../../graph/vertex");
6
6
  const identifier_1 = require("../../environments/identifier");
7
7
  /**
8
- *
8
+ * Processes a value node in the AST for dataflow analysis.
9
+ * For example, literals like numbers.
9
10
  */
10
- function processValue({ info: { id } }, { controlDependencies, completeAst: { idMap }, ctx: { env }, environment }) {
11
+ function processValue({ info: { id } }, { controlDependencies, completeAst: { idMap }, environment }) {
11
12
  return {
12
13
  unknownReferences: [],
13
14
  in: [{ nodeId: id, name: undefined, controlDependencies, type: identifier_1.ReferenceType.Constant }],
@@ -15,11 +16,12 @@ function processValue({ info: { id } }, { controlDependencies, completeAst: { id
15
16
  environment,
16
17
  graph: new graph_1.DataflowGraph(idMap).addVertex({
17
18
  tag: vertex_1.VertexType.Value,
18
- id: id,
19
- cds: controlDependencies
20
- }, env.makeCleanEnv()),
19
+ id,
20
+ controlDependencies
21
+ }, undefined),
21
22
  exitPoints: [{ nodeId: id, type: 0 /* ExitPointType.Default */, controlDependencies }],
22
- entryPoint: id
23
+ entryPoint: id,
24
+ hooks: []
23
25
  };
24
26
  }
25
27
  //# sourceMappingURL=process-value.js.map
@@ -91,7 +91,8 @@ function getCallTarget(dfg, call) {
91
91
  })) : undefined;
92
92
  const targets = new Set((0, linker_1.getAllFunctionCallTargets)(call.id, dfg));
93
93
  if (targets.size === 0) {
94
- return origins;
94
+ // resolve via variable use origin
95
+ return origins?.length === 0 ? getVariableUseOrigin(dfg, call) : origins;
95
96
  }
96
97
  origins = (origins ?? []).concat([...targets].map(target => {
97
98
  if ((0, built_in_1.isBuiltIn)(target)) {
@@ -26,7 +26,7 @@ function getAllRefsToSymbol(graph, nodeId) {
26
26
  if (origins === undefined) {
27
27
  return undefined;
28
28
  }
29
- const definitiveOrigins = origins.filter(o => (0, info_1.happensInEveryBranch)(graph.getVertex(o.id)?.cds));
29
+ const definitiveOrigins = origins.filter(o => (0, info_1.happensInEveryBranch)(graph.getVertex(o.id)?.controlDependencies));
30
30
  if (definitiveOrigins.length === 0) {
31
31
  return undefined;
32
32
  }
@@ -5,5 +5,5 @@ import { DocMaker } from './wiki-mk/doc-maker';
5
5
  */
6
6
  export declare class DocReadme extends DocMaker<'README.md'> {
7
7
  constructor();
8
- text({ treeSitter }: DocMakerArgs): Promise<string>;
8
+ text({ treeSitter, ctx }: DocMakerArgs): Promise<string>;
9
9
  }
@@ -119,7 +119,7 @@ class DocReadme extends doc_maker_1.DocMaker {
119
119
  constructor() {
120
120
  super('README.md', module.filename, 'flowR README', false);
121
121
  }
122
- async text({ treeSitter }) {
122
+ async text({ treeSitter, ctx }) {
123
123
  const dateOptions = { year: 'numeric', month: 'short', day: 'numeric' };
124
124
  return `
125
125
  [![flowR logo](https://raw.githubusercontent.com/wiki/flowr-analysis/flowr/img/flowR.png)](${doc_files_1.FlowrGithubBaseRef}/flowr/wiki)\\
@@ -183,7 +183,7 @@ ${await (0, doc_repl_1.documentReplSession)(treeSitter, [{
183
183
  `), ' ')}
184
184
 
185
185
  * 📚 **dependency analysis**\\
186
- Given your analysis project, flowR offers a plethora of so-called [queries](${doc_files_1.FlowrWikiBaseRef}/Query-API) to get more information about your code.
186
+ Given your analysis project, flowR offers a plethora of so-called ${ctx.linkPage('wiki/Query API', 'queries')} to get more information about your code.
187
187
  An important query is the [dependencies query](${doc_files_1.FlowrWikiBaseRef}/Query-API#dependencies-query), which shows you the library your project needs,
188
188
  the data files it reads, the scripts it sources, and the data it outputs.
189
189
 
@@ -192,12 +192,12 @@ The following showcases the dependency view of the [Visual Studio Code extension
192
192
 
193
193
  ![Dependency Analysis](https://raw.githubusercontent.com/flowr-analysis/vscode-flowr/refs/heads/main/media/dependencies.png)
194
194
 
195
- `), ' ')}
195
+ `), ' ')}
196
196
 
197
- * 🚀 **fast data- and control-flow graphs**\\
198
- Within just ${'<i>' + (0, html_hover_over_1.textWithTooltip)((0, numbers_1.roundToDecimals)(await (0, doc_benchmarks_1.getLatestDfAnalysisTime)('"social-science" Benchmark Suite (tree-sitter)'), 1) + ' ms', 'This measurement is automatically fetched from the latest benchmark!') + '</i>'} (as of ${new Date(await (0, doc_benchmarks_1.getLastBenchmarkUpdate)()).toLocaleDateString('en-US', dateOptions)}),
197
+ * 🚀 **fast call-graph, data-, and control-flow graphs**\\
198
+ Within just [${'<i>' + (0, html_hover_over_1.textWithTooltip)((0, numbers_1.roundToDecimals)(await (0, doc_benchmarks_1.getLatestDfAnalysisTime)('"social-science" Benchmark Suite (tree-sitter)'), 1) + ' ms', 'This measurement is automatically fetched from the latest benchmark!') + '</i>'} (as of ${new Date(await (0, doc_benchmarks_1.getLastBenchmarkUpdate)()).toLocaleDateString('en-US', dateOptions)})](${doc_files_1.FlowrSiteBaseRef}/wiki/stats/benchmark),
199
199
  _flowR_ can analyze the data- and control-flow of the average real-world R script. See the [benchmarks](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark) for more information,
200
- and consult the [wiki pages](${doc_files_1.FlowrWikiBaseRef}/Dataflow-Graph) for more details on the dataflow graph.
200
+ and consult the ${ctx.linkPage('wiki/Dataflow Graph', 'wiki pages')} for more details on the dataflow graphs as well as call graphs.
201
201
 
202
202
  ${(0, doc_general_1.prefixLines)((0, doc_structure_1.details)('Example: Generating a dataflow graph with flowR', `
203
203
  You can investigate flowR's analyses using the [REPL](${doc_files_1.FlowrWikiBaseRef}/Interface#using-the-repl).
@@ -18,7 +18,7 @@ const environment_1 = require("../../dataflow/environments/environment");
18
18
  * ```
19
19
  */
20
20
  function codeBlock(language, code) {
21
- return `\n\`\`\`${language}\n${code?.trim() ?? ''}\n\`\`\`\n`;
21
+ return `\n\`\`\`${language}\n${code?.trimEnd() ?? ''}\n\`\`\`\n`;
22
22
  }
23
23
  /**
24
24
  * Produces an inline code span in markdown format.
@@ -15,6 +15,7 @@ export interface PrintDataflowGraphOptions {
15
15
  readonly exposeResult?: boolean;
16
16
  readonly switchCodeAndGraph?: boolean;
17
17
  readonly simplified?: boolean;
18
+ readonly callGraph?: boolean;
18
19
  }
19
20
  /**
20
21
  * Visualizes a side effect for documentation purposes.
@@ -14,6 +14,7 @@ const time_1 = require("../../util/text/time");
14
14
  const doc_files_1 = require("./doc-files");
15
15
  const doc_code_1 = require("./doc-code");
16
16
  const flowr_analyzer_context_1 = require("../../project/context/flowr-analyzer-context");
17
+ const call_graph_1 = require("../../dataflow/graph/call-graph");
17
18
  /**
18
19
  * Visualizes the dataflow graph as a mermaid graph inside a markdown code block.
19
20
  * Please use this only for documentation purposes, for programmatic usage use {@link graphToMermaid} directly.
@@ -44,7 +45,7 @@ function formatSideEffect(ef) {
44
45
  * This function returns a markdown string containing the dataflow graph as a mermaid code block,
45
46
  * along with the R code itself in a collapsible section.
46
47
  */
47
- async function printDfGraphForCode(parser, code, { simplified = false, mark, showCode = true, codeOpen = false, exposeResult, switchCodeAndGraph = false } = {}) {
48
+ async function printDfGraphForCode(parser, code, { callGraph = false, simplified = false, mark, showCode = true, codeOpen = false, exposeResult, switchCodeAndGraph = false } = {}) {
48
49
  const now = performance.now();
49
50
  const result = await (0, default_pipelines_1.createDataflowPipeline)(parser, {
50
51
  context: (0, flowr_analyzer_context_1.contextFromInput)(code)
@@ -54,8 +55,10 @@ async function printDfGraphForCode(parser, code, { simplified = false, mark, sho
54
55
  (0, assert_1.guard)(showCode, 'can not switch code and graph if code is not shown');
55
56
  }
56
57
  const metaInfo = `The analysis required _${(0, time_1.printAsMs)(duration)}_ (including parse and normalize, using the [${parser.name}](${doc_files_1.FlowrWikiBaseRef}/Engines) engine) within the generation environment.`;
57
- const dfGraph = printDfGraph(result.dataflow.graph, mark, simplified);
58
+ const graph = callGraph ? (0, call_graph_1.computeCallGraph)(result.dataflow.graph) : result.dataflow.graph;
59
+ const dfGraph = printDfGraph(graph, mark, simplified);
58
60
  const simplyText = simplified ? '(simplified) ' : '';
61
+ const graphName = callGraph ? 'Call Graph' : 'Dataflow Graph';
59
62
  let resultText = '\n\n';
60
63
  if (showCode) {
61
64
  const codeText = (0, doc_code_1.codeBlock)('r', code);
@@ -63,10 +66,10 @@ async function printDfGraphForCode(parser, code, { simplified = false, mark, sho
63
66
  resultText += `
64
67
  <details${codeOpen ? ' open' : ''}>
65
68
 
66
- <summary style="color:gray">${switchCodeAndGraph ? `${simplyText}Dataflow Graph of the R Code` : `R Code of the ${simplyText}Dataflow Graph`}</summary>
69
+ <summary style="color:gray">${switchCodeAndGraph ? `${simplyText}${graphName} of the R Code` : `R Code of the ${simplyText}${graphName}`}</summary>
67
70
 
68
71
  ${metaInfo} ${mark ? `The following marks are used in the graph to highlight sub-parts (uses ids): {${[...mark].join(', ')}}.` : ''}
69
- We encountered ${result.dataflow.graph.unknownSideEffects.size > 0 ? 'unknown side effects (with ids: ' + [...result.dataflow.graph.unknownSideEffects].map(formatSideEffect).join(', ') + ')' : 'no unknown side effects'} during the analysis.
72
+ We encountered ${graph.unknownSideEffects.size > 0 ? 'unknown side effects (with ids: ' + [...graph.unknownSideEffects].map(formatSideEffect).join(', ') + ')' : 'no unknown side effects'} during the analysis.
70
73
 
71
74
  ${switchCodeAndGraph ? dfGraph : codeText}
72
75
 
@@ -20,6 +20,7 @@ export interface QueryDocumentation {
20
20
  readonly type: 'virtual' | 'active';
21
21
  readonly shortDescription: string;
22
22
  readonly functionName: string;
23
+ /** Path to the file implementing the query function, the wiki generation will fail if this isn't found */
23
24
  readonly functionFile: string;
24
25
  readonly buildExplanation: (shell: RShell, ctx: GeneralDocContext) => Promise<string>;
25
26
  }
@@ -35,7 +35,7 @@ ${(0, doc_code_1.codeBlock)('json', collapseQuery ? str.split('\n').join(' ').re
35
35
 
36
36
  ${(function () {
37
37
  if ((queries.length === 1 && Object.keys(queries[0]).length === 1) || shorthand) {
38
- return `(This query can be shortened to \`@${queries[0].type}${shorthand ? ' ' + shorthand : ''}\` when used within the REPL command ${(0, doc_cli_option_1.getReplCommand)('query')}).`;
38
+ return `(This can be shortened to \`@${queries[0].type}${shorthand ? ' ' + shorthand : ''}\` when used with the REPL command ${(0, doc_cli_option_1.getReplCommand)('query')}).`;
39
39
  }
40
40
  else {
41
41
  return '';
@@ -18,6 +18,7 @@ export interface DocumentReplCommand {
18
18
  description: string;
19
19
  }
20
20
  /**
21
- *
21
+ * Creates a documented REPL session for the given commands.
22
+ * This is intended for documentation purposes.
22
23
  */
23
24
  export declare function documentReplSession(parser: KnownParser, commands: readonly DocumentReplCommand[], options?: DocumentReplSessionOptions): Promise<string>;
@@ -42,8 +42,16 @@ function printReplHelpAsMarkdownTable() {
42
42
  ${scriptHelp.sort().join('\n')}
43
43
  `;
44
44
  }
45
+ function dropAnsiEscapeCodesAndCodeTags(input) {
46
+ // eslint-disable-next-line no-control-regex
47
+ return input.replace(/\x1B\[[0-9;]*[mK]/g, '')
48
+ .replace(/<\/?code>/g, '')
49
+ .replace(/\**([^*]+)\**/g, '$1')
50
+ .replace(/_([^_]+)_/g, '$1');
51
+ }
45
52
  /**
46
- *
53
+ * Creates a documented REPL session for the given commands.
54
+ * This is intended for documentation purposes.
47
55
  */
48
56
  async function documentReplSession(parser, commands, options) {
49
57
  const collect = [];
@@ -52,10 +60,10 @@ async function documentReplSession(parser, commands, options) {
52
60
  const collectingOutput = {
53
61
  formatter: ansi_1.voidFormatter,
54
62
  stdout(msg) {
55
- entry.lines.push(msg);
63
+ entry.lines.push(dropAnsiEscapeCodesAndCodeTags(msg));
56
64
  },
57
65
  stderr(msg) {
58
- entry.lines.push(msg);
66
+ entry.lines.push(dropAnsiEscapeCodesAndCodeTags(msg));
59
67
  }
60
68
  };
61
69
  const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder()
@@ -148,6 +148,8 @@ Likewise, ${ctx.linkM(flowr_analyzer_1.FlowrAnalyzer, 'peekNormalize', { codeFon
148
148
  Again, ${ctx.linkM(flowr_analyzer_1.FlowrAnalyzer, 'peekDataflow', { codeFont: true, realNameWrapper: 'i' })} allows you to inspect the dataflow graph if it was already computed (but without triggering a computation).
149
149
  * ${ctx.linkM(flowr_analyzer_1.FlowrAnalyzer, 'controlflow')} to compute the [Control Flow Graph](${doc_files_1.FlowrWikiBaseRef}/Control%20Flow%20Graph)\\
150
150
  Also, ${ctx.linkM(flowr_analyzer_1.FlowrAnalyzer, 'peekControlflow', { codeFont: true, realNameWrapper: 'i' })} returns the control flow graph if it was already computed but without triggering a computation.
151
+ * ${ctx.linkM(flowr_analyzer_1.FlowrAnalyzer, 'callGraph')} to compute the ${ctx.linkPage('wiki/Dataflow Graph', 'call graph', 'perspectives-cg')} of the analyzed code\\
152
+ Likewise, ${ctx.linkM(flowr_analyzer_1.FlowrAnalyzer, 'peekCallGraph', { codeFont: true, realNameWrapper: 'i' })} allows you to inspect the call graph if it was already computed (but without triggering a computation).
151
153
  * ${ctx.linkM(flowr_analyzer_1.FlowrAnalyzer, 'query')} to run [queries](${doc_files_1.FlowrWikiBaseRef}/Query-API) on the analyzed code.
152
154
  * ${ctx.linkM(flowr_analyzer_1.FlowrAnalyzer, 'runSearch')} to run a search query on the analyzed code using the [search API](${doc_files_1.FlowrWikiBaseRef}/Search%20API)
153
155
 
@@ -37,6 +37,7 @@ const environment_builder_1 = require("../../test/functionality/_helper/dataflow
37
37
  const flowr_analyzer_builder_1 = require("../project/flowr-analyzer-builder");
38
38
  const flowr_analyzer_context_1 = require("../project/context/flowr-analyzer-context");
39
39
  const doc_maker_1 = require("./wiki-mk/doc-maker");
40
+ const flowr_analyzer_1 = require("../project/flowr-analyzer");
40
41
  async function subExplanation(parser, { description, code, expectedSubgraph }) {
41
42
  expectedSubgraph = await (0, doc_dfg_1.verifyExpectedSubgraph)(parser, code, expectedSubgraph);
42
43
  const marks = [];
@@ -70,6 +71,7 @@ async function explanation({ name, type, description, code, expectedSubgraph },
70
71
  await (0, doc_dfg_1.verifyExpectedSubgraph)(parser, code, expectedSubgraph);
71
72
  return `
72
73
  <a id='${name.toLowerCase().replaceAll(' ', '-')}'> </a>
74
+ <a id='${String(type).toLowerCase().replaceAll(' ', '-')}-vertex'> </a>
73
75
  ### ${index}) ${name}
74
76
 
75
77
  Type: \`${type}\` (this is the bit-flag value, e.g., when looking at the serialization)
@@ -425,7 +427,7 @@ As you can see, _flowR_ is able to recognize that the initial definition of \`x\
425
427
  name: 'Function Definition Vertex',
426
428
  type: vertex_1.VertexType.FunctionDefinition,
427
429
  description: `
428
- Defining a function does do a lot of things: 1) it creates a new scope, 2) it may introduce parameters which act as promises and which are only evaluated if they are actually required in the body, 3) it may access the enclosing environments and the callstack.
430
+ Defining a function does do a lot of things: 1) it creates a new scope, 2) it may introduce parameters which act as promises and which are only evaluated if they are actually required in the body, 3) it may access the enclosing environments and the callstack.
429
431
  The vertex object in the dataflow graph stores multiple things, including all exit points, the enclosing environment if necessary, and the information of the subflow (the "body" of the function).
430
432
 
431
433
  ${ctx.hierarchy('DataflowGraphVertexFunctionDefinition')}
@@ -434,7 +436,6 @@ ${ctx.hierarchy('DataflowFunctionFlowInformation')}
434
436
  And if you are interested in the exit points, they are defined like this:
435
437
  ${ctx.hierarchy('ExitPoint')}
436
438
 
437
-
438
439
  Whenever we visualize a function definition, we use a dedicated node to represent the anonymous function object,
439
440
  and a subgraph (usually with the name \`"function <id>"\`) to encompass the body of the function (they are linked with a dotted line).
440
441
 
@@ -498,7 +499,7 @@ Besides this being a theoretically "shorter" way of defining a function, this be
498
499
 
499
500
  `,
500
501
  code: 'function() 1',
501
- expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().defineFunction('1@function', [0], { graph: new Set('0'), in: [], out: [], unknownReferences: [], entryPoint: 0, environment: (0, environment_builder_1.defaultEnv)() })
502
+ expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().defineFunction('1@function', [0], { hooks: [], graph: new Set('0'), in: [{ nodeId: 0, controlDependencies: [], type: identifier_1.ReferenceType.Constant, name: undefined }], out: [], unknownReferences: [], entryPoint: 0, environment: (0, environment_builder_1.defaultEnv)() })
502
503
  }, []]);
503
504
  const results = [];
504
505
  let i = 0;
@@ -581,7 +582,9 @@ However, nested definitions can carry it (in the nested case, \`x\` is defined b
581
582
  name: 'Calls Edge',
582
583
  type: edge_1.EdgeType.Calls,
583
584
  description: `Link the [function call](#function-call-vertex) to the [function definition](#function-definition-vertex) that is called. To find all called definitions,
584
- please use the ${ctx.link(dfg_get_origin_1.getOriginInDfg.name)} function, as explained in [working with the dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Working%20with%20the%20Dataflow%20Graph).`,
585
+ please use the ${ctx.link(dfg_get_origin_1.getOriginInDfg.name)} function, as explained in ${ctx.linkPage('wiki/Dataflow Graph', 'working with the dataflow graph', 'Working-with-the-Dataflow-Graph')}.
586
+ If you are interested in the call graph, refer to ${ctx.linkM(flowr_analyzer_1.FlowrAnalyzer, 'callGraph')} and consult the ${ctx.linkPage('wiki/Dataflow Graph', 'call graph wiki', 'perspectives-cg')} for more information.
587
+ `,
585
588
  code: 'foo <- function() {}\nfoo()',
586
589
  expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().calls('2@foo', '1@function')
587
590
  }, []]);
@@ -747,6 +750,8 @@ In summary, we discuss the following topics:
747
750
  - [Control Dependencies](#control-dependencies)
748
751
  - [Dataflow Information](#dataflow-information)
749
752
  - [Unknown Side Effects](#unknown-side-effects)
753
+ - [Perspectives on the Dataflow Graph](#perspectives)
754
+ - [Call Graph Perspective](#perspectives-cg)
750
755
  - [Working with the Dataflow Graph](#dfg-working)
751
756
 
752
757
  Please be aware that the accompanied [dataflow information](#dataflow-information) (${ctx.link('DataflowInformation')}) returned by _flowR_ contains things besides the graph,
@@ -761,6 +766,8 @@ wiki page if you are unsure.
761
766
  > you can either use the [Visual Studio Code extension](${doc_files_1.FlowrVsCode}) or the ${ctx.replCmd('dataflow*')}
762
767
  > command in the REPL (see the ${ctx.linkPage('wiki/Interface', 'Interface wiki page')} for more information).
763
768
  > There is also a simplified perspective available with ${ctx.replCmd('dataflowsimple*')} that does not show everything but is easier to read.
769
+ > For small graphs, you can also use ${ctx.replCmd('dataflowascii')} to print the graph as ASCII art.
770
+ >
764
771
  > When using _flowR_ as a library, you may use the functions in ${(0, doc_files_1.getFilePathMd)('../util/mermaid/dfg.ts')}.
765
772
  >
766
773
  > If you receive a dataflow graph in its serialized form (e.g., by talking to a [_flowR_ server](${doc_files_1.FlowrWikiBaseRef}/Interface)), you can use ${ctx.linkM(graph_1.DataflowGraph, 'fromJson', { realNameWrapper: 'i', codeFont: true })} to retrieve the graph from the JSON representation.
@@ -821,7 +828,7 @@ ${(0, doc_general_1.prefixLines)((0, doc_code_1.codeBlock)('ts', `const name = $
821
828
 
822
829
  ${(0, doc_structure_1.section)('Vertices', 2, 'vertices')}
823
830
 
824
- 1. ${(0, doc_data_dfg_util_1.getAllVertices)().map(([k, v], index) => `[\`${k}\`](#${index + 1}-${v.toLowerCase().replace(/\s/g, '-')}-vertex)`).join('\n1. ')}
831
+ 1. ${(0, doc_data_dfg_util_1.getAllVertices)().map(([k, v]) => `[\`${k}\`](#${v.toLowerCase().replace(/\s/g, '-')}-vertex)`).join('\n1. ')}
825
832
 
826
833
  ${await getVertexExplanations(treeSitter, ctx)}
827
834
 
@@ -949,18 +956,55 @@ Additionally, we express this by a ${linkEdgeName(edge_1.EdgeType.Reads)} edge.
949
956
  `;
950
957
  })()}
951
958
 
959
+ ${(0, doc_structure_1.section)('Perspectives on the Dataflow Graph', 2, 'perspectives')}
960
+
961
+ For certain questions, handling the *full* dataflow graph may be too complex or unnecessary, given that you might have to consider edge interactions, or trace
962
+ transitive relationships by yourself.
963
+ Perspectives are simplified views on the dataflow graph, tailored to specific questions, which still comply with the ${ctx.link(graph_1.DataflowGraph)} interface
964
+ so you can use them as drop-in replacements for the full dataflow graph. Although, please be aware that this does not mean that every function will work correctly&mdash;a
965
+ call graph will no longer contain information on variables, for example.
966
+
967
+ ${(0, doc_structure_1.section)('Call Graphs', 3, 'perspectives-cg')}
968
+
969
+ These are simplified views on the dataflow graph, following the ${ctx.link('CallGraph')} type.
970
+ It can be obtained, e.g., by ${ctx.linkM(flowr_analyzer_1.FlowrAnalyzer, 'callGraph')}.
971
+ These graphs only contain function definitions and function calls as vertices, and ${linkEdgeName(edge_1.EdgeType.Calls)} edges.
972
+ Consider the following example:
973
+
974
+ ${(0, doc_code_1.codeBlock)('r', 'f <- function() f()')}
975
+
976
+ The resulting call graph looks like this:
977
+
978
+ ${await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'f <- function() f()', { callGraph: true })}
979
+
980
+ Please note, that, due to the over-approximative nature of call-graphs, the call-graph may label some function calls that are *not*
981
+ marked as such in the full dataflow graph (which may have more precise information).
982
+ For example, if we call an unknown alias:
983
+
984
+ ${(0, doc_code_1.codeBlock)('r', 'alias <- unknown\nalias(print)')}
985
+
986
+ The resulting call graph looks like this:
987
+
988
+ ${await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'alias <- unknown\nalias()', { callGraph: true })}
989
+
990
+ Here, \`unknown\` is a function call, while it is a symbol in the full dataflow graph (as we cannot resolve it):
991
+
992
+ ${await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'alias <- unknown\nalias()', { callGraph: false })}
993
+
994
+
952
995
  ${(0, doc_structure_1.section)('Working with the Dataflow Graph', 2, 'dfg-working')}
953
996
 
954
997
  The ${ctx.link('DataflowInformation')} is the core result of _flowR_ and summarizes a lot of information.
955
998
  Depending on what you are interested in, there exists a plethora of functions and queries to help you out, answering the most important questions:
956
999
 
957
- * The **[Query API](${doc_files_1.FlowrWikiBaseRef}/Query%20API)** provides many functions to query the dataflow graph for specific information (dependencies, calls, slices, clusters, ...)
958
- * The **[Search API](${doc_files_1.FlowrWikiBaseRef}/Search%20API)** allows you to search for specific vertices or edges in the dataflow graph or the original program
959
- * ${ctx.link(node_id_1.recoverName.name)} and ${ctx.link(node_id_1.recoverContent.name)} to get the name or content of a vertex in the dataflow graph
960
- * ${ctx.link(alias_tracking_1.resolveIdToValue.name)} to resolve the value of a variable or id (if possible, see [below](#dfg-resolving-values))
961
- * ${ctx.link(edge_1.edgeIncludesType.name)} to check if an edge includes a specific type and ${ctx.link(edge_1.splitEdgeTypes.name)} to split the bitmask of edges into its types (see [below](#dfg-resolving-values))
962
- * ${ctx.link(identify_link_to_last_call_relation_1.getValueOfArgument.name)} to get the (syntactical) value of an argument in a function call
963
- * ${ctx.link(dfg_get_origin_1.getOriginInDfg.name)} to get information about where a read, call, ... comes from (see [below](#dfg-resolving-values))
1000
+ * The **${ctx.linkPage('wiki/Query API')}** provides many functions to query the dataflow graph for specific information (dependencies, calls, slices, clusters, ...)
1001
+ * The **${ctx.linkPage('wiki/Search API')}** allows you to search for specific vertices or edges in the dataflow graph or the original program
1002
+ * ${ctx.link(node_id_1.recoverName)} and ${ctx.link(node_id_1.recoverContent)} to get the name or content of a vertex in the dataflow graph
1003
+ * ${ctx.link(alias_tracking_1.resolveIdToValue)} to resolve the value of a variable or id (if possible, see [below](#dfg-resolving-values))
1004
+ * ${ctx.link(alias_tracking_1.getAliases)} to get all (potentially currently) aliases of a given definition
1005
+ * ${ctx.link(edge_1.edgeIncludesType)} to check if an edge includes a specific type and ${ctx.link(edge_1.splitEdgeTypes)} to split the bitmask of edges into its types (see [below](#dfg-resolving-values))
1006
+ * ${ctx.link(identify_link_to_last_call_relation_1.getValueOfArgument)} to get the (syntactical) value of an argument in a function call
1007
+ * ${ctx.link(dfg_get_origin_1.getOriginInDfg)} to get information about where a read, call, ... comes from (see [below](#dfg-resolving-values))
964
1008
 
965
1009
  Some of these functions have been explained in their respective wiki pages. However, some are part of the [Dataflow Graph API](${doc_files_1.FlowrWikiBaseRef}/Dataflow-Graph) and so we explain them here.
966
1010
  If you are interested in which features we support and which features are still to be worked on, please refer to our [capabilities](${doc_files_1.FlowrWikiBaseRef}/Capabilities) page.
@@ -970,12 +1014,12 @@ ${(0, doc_structure_1.section)('Resolving Values', 3, 'dfg-resolving-values')}
970
1014
  FlowR supports a [configurable](${doc_files_1.FlowrWikiBaseRef}/Interface#configuring-flowr) level of value tracking&mdash;all with the goal of knowing the static value domain of a variable.
971
1015
  These capabilities are exposed by the [resolve value Query](${doc_files_1.FlowrWikiBaseRef}/Query-API#resolve-value-query) and backed by two important functions:
972
1016
 
973
- ${ctx.link(alias_tracking_1.resolveIdToValue.name)} provides an environment-sensitive (see ${ctx.link('REnvironmentInformation')})
1017
+ ${ctx.link(alias_tracking_1.resolveIdToValue)} provides an environment-sensitive (see ${ctx.link('REnvironmentInformation')})
974
1018
  value resolution depending on if the environment is provided.
975
- The idea of ${ctx.link(alias_tracking_1.resolveIdToValue.name)} is to provide a compromise between precision and performance, to
1019
+ The idea of ${ctx.link(alias_tracking_1.resolveIdToValue)} is to provide a compromise between precision and performance, to
976
1020
  be used _during_ and _after_ the core analysis. After the dataflow analysis completes, there are much more expensive queries possible (such as the resolution of the data frame shape, see the [Query API](${doc_files_1.FlowrWikiBaseRef}/Query-API)).
977
1021
 
978
- Additionally, to ${ctx.link(alias_tracking_1.resolveIdToValue.name)}, we offer the aforementioned ${ctx.link(identify_link_to_last_call_relation_1.getValueOfArgument.name)} to retrieve the value of an argument in a function call.
1022
+ Additionally, to ${ctx.link(alias_tracking_1.resolveIdToValue)}, we offer the aforementioned ${ctx.link(identify_link_to_last_call_relation_1.getValueOfArgument)} to retrieve the value of an argument in a function call.
979
1023
  Be aware, that this function is currently not optimized for speed, so if you frequently require the values of multiple arguments of the same function call, you may want to open [an issue](${doc_issue_1.NewIssueUrl}) to request support for resolving
980
1024
  multiple arguments at once.
981
1025
 
@@ -1019,7 +1063,6 @@ ${['SimpleOrigin', 'FunctionCallOrigin', 'BuiltInFunctionOrigin'].sort().map(key
1019
1063
  Please note, the current structure of this function is biased by what implementations already exist in flowR.
1020
1064
  Hence, we do not just track definitions and constants, but also the origins of function calls, albeit we do not yet track the origins of values (only resorting to
1021
1065
  a constant origin). If you are confused by this please start a discussion&mdash;in a way we are still deciding on a good API for this.
1022
-
1023
1066
  `;
1024
1067
  })()}
1025
1068
 
@@ -139,6 +139,10 @@ the REPL will re-use previously obtained information and not re-parse the code a
139
139
  `
140
140
  })}
141
141
 
142
+ Generally, many commands offer shortcut versions in the REPL. Many queries, for example, offer a shortened format (see the example below).
143
+ Of special note, the ${ctx.linkPage('wiki/Query API', 'Config Query', 'Config-Query')}
144
+ can be used to also modify the currently active configuration of _flowR_ within the REPL (see the ${ctx.linkPage('wiki/Query API', 'wiki page', 'Config-Query')} for more information).
145
+
142
146
  ### Example: Retrieving the Dataflow Graph
143
147
 
144
148
  To retrieve a URL to the [mermaid](https://mermaid.js.org/) diagram of the dataflow of a given expression,
@@ -149,6 +153,13 @@ ${await (0, doc_repl_1.documentReplSession)(parser, [{
149
153
  description: `Retrieve the dataflow graph of the expression \`y <- 1 + x\`. It looks like this:\n${await (0, doc_dfg_1.printDfGraphForCode)(parser, 'y <- 1 + x')}`
150
154
  }])}
151
155
 
156
+ For small graphs like this, ${ctx.replCmd('dataflowascii')} also provides an ASCII representation directly in the REPL:
157
+
158
+ ${await (0, doc_repl_1.documentReplSession)(parser, [{
159
+ command: ':df! y <- 1 + x',
160
+ description: 'Retrieve the dataflow graph of the expression `y <- 1 + x` as ASCII art.'
161
+ }], { openOutput: true })}
162
+
152
163
  For the slicing with ${ctx.replCmd('slicer')}, you have access to the same [magic comments](#slice-magic-comments) as with the [slice request](#message-request-slice).
153
164
 
154
165
  ### Example: Interfacing with the File System
@@ -172,6 +183,22 @@ ${(0, doc_code_1.codeBlock)('r', (0, doc_files_1.getFileContentFromRoot)('test/t
172
183
  As _flowR_ directly transforms this AST the output focuses on being human-readable instead of being machine-readable.
173
184
  `
174
185
  }])}
186
+
187
+ ### Example: Run a Query
188
+
189
+ You can run any query supported by _flowR_ using the ${ctx.replCmd('query')} command.
190
+ For example, to obtain the shapes of all data frames in a given piece of code, you can run:
191
+ ${await (0, doc_repl_1.documentReplSession)(parser, [{
192
+ command: ':query @df-shape "x <- data.frame(a = 1:10, b = 1:10)\\ny <- x$a"',
193
+ description: 'Retrieve the shapes of all data frames in the given code.'
194
+ }], { openOutput: true })}
195
+ To run the linter on a file, you can use (in this example, we just issue the \`dead-code\` linter on a small piece of code):
196
+ ${await (0, doc_repl_1.documentReplSession)(parser, [{
197
+ command: ':query @linter rules:dead-code "if(FALSE) x <- 2"',
198
+ description: 'Run the linter on the given code, with only the `dead-code` rule enabled.'
199
+ }], { openOutput: true })}
200
+
201
+ For more information on the available queries, please check out the ${ctx.linkPage('wiki/Query API', 'Query API')}.
175
202
  `;
176
203
  }
177
204
  function explainConfigFile() {
@@ -443,20 +470,21 @@ Although far from being as detailed as the in-depth explanation of ${ctx.linkPag
443
470
  this wiki page explains how to interface with _flowR_ in more detail.
444
471
  In general, command line arguments and other options provide short descriptions on hover over.
445
472
 
446
- * [💬 Communicating with the Server](#communicating-with-the-server)
447
473
  * [💻 Using the REPL](#using-the-repl)
474
+ * [💬 Communicating with the Server](#communicating-with-the-server)
448
475
  * [⚙️ Configuring FlowR](#configuring-flowr)
449
476
  * [⚒️ Writing Code](#writing-code)
450
477
 
478
+ <a id='using-the-repl'></a>
479
+ ## 💻 Using the REPL
480
+
481
+ ${await explainRepl(treeSitter, ctx)}
482
+
451
483
  <a id='communicating-with-the-server'></a>
452
484
  ## 💬 Communicating with the Server
453
485
 
454
486
  ${await explainServer(shell)}
455
487
 
456
- <a id='using-the-repl'></a>
457
- ## 💻 Using the REPL
458
-
459
- ${await explainRepl(treeSitter, ctx)}
460
488
 
461
489
  <a id='configuring-flowr'></a>
462
490
  ## ⚙️ Configuring FlowR
@@ -186,8 +186,9 @@ export interface GeneralDocContext {
186
186
  * Creates a link to the `wiki/Setup` wiki page with the link text `Setup`.
187
187
  * @param pageName - The name of the wiki page to link to.
188
188
  * @param linkText - Optional text to display for the link. If not provided, the page name will be used.
189
+ * @param segment - An optional segment within the page to link to (e.g., a header anchor).
189
190
  */
190
- linkPage(pageName: ValidWikiDocumentTargetsNoSuffix, linkText?: string): string;
191
+ linkPage(pageName: ValidWikiDocumentTargetsNoSuffix, linkText?: string, segment?: string): string;
191
192
  /**
192
193
  * Generates a link to a code file in the code base.
193
194
  * @param path - The path to the code file.
@@ -81,10 +81,10 @@ function makeDocContextForTypes(shell, ...rootFolders) {
81
81
  inlineTypes
82
82
  });
83
83
  },
84
- linkPage(pageName, linkText) {
84
+ linkPage(pageName, linkText, segment) {
85
85
  const text = linkText ?? pageName.split('/').pop() ?? pageName;
86
86
  const link = pageName.toLowerCase().replace(/ /g, '-');
87
- return `[${text}](${doc_files_1.FlowrGithubRef}/${link})`;
87
+ return `[${text}](${doc_files_1.FlowrGithubRef}/${link}${segment ? `#${segment}` : ''})`;
88
88
  },
89
89
  linkCode(path, lineNumber) {
90
90
  const lnk = lineNumber ? `${path.toString()}#L${lineNumber}` : path.toString();
@@ -11,7 +11,7 @@ const DefaultReplacementPatterns = [
11
11
  // eslint-disable-next-line no-irregular-whitespace -- we may produce it in output
12
12
  [/[0-9]+(\.[0-9]+)?( |\s*)?ms/g, ''],
13
13
  [/tmp[%A-Za-z0-9-]+/g, ''],
14
- [/"(timing|searchTimeMs|processTimeMs|id|treeSitterId)":\s*[0-9]+(\.[0-9])?,?/g, ''],
14
+ [/"?(timing|searchTimeMs|processTimeMs|id|treeSitterId)"?:\s*[0-9]+(\.[0-9])?,?/g, ''],
15
15
  [/"format":"compact".+/gmius, ''],
16
16
  [/%%\s*\d*-+/g, ''],
17
17
  [/"[rR]": "\d+\.\d+\.\d+.*?"/g, ''],
@@ -19,8 +19,9 @@ const DefaultReplacementPatterns = [
19
19
  [/v\d+\.\d+\.\d+/g, ''],
20
20
  // clean paths
21
21
  [/%2Fhome%2F([a-zA-Z0-9._-]+%2F)*/g, ''],
22
- // async wrapper depends on whether the promise got forfilled already
23
- [/async|%20/g, '']
22
+ // async wrapper depends on whether the promise got fulfilled already
23
+ [/async|%20/g, ''],
24
+ [/\s*Copied mermaid url to clipboard\s*\([^)]+\)/gmi, '']
24
25
  ];
25
26
  /**
26
27
  * Abstract base class for generating wiki files.
@@ -17,6 +17,7 @@ const flowr_analyzer_1 = require("../project/flowr-analyzer");
17
17
  const flowr_analyzer_builder_1 = require("../project/flowr-analyzer-builder");
18
18
  const flowr_file_1 = require("../project/context/flowr-file");
19
19
  const doc_maker_1 = require("./wiki-mk/doc-maker");
20
+ const roxygen_parse_1 = require("../r-bridge/roxygen2/roxygen-parse");
20
21
  async function quickNormalizedAstMultipleFiles() {
21
22
  const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder()
22
23
  .setEngine('tree-sitter')
@@ -95,6 +96,11 @@ The following segments intend to give you an overview of how to work with the no
95
96
  * [How to get a Normalized AST](#how-to-get-a-normalized-ast)
96
97
  * [Visitors and Folds](#visitors-and-folds)
97
98
 
99
+ > [!TIP]
100
+ > If you want to get more information on roxygen comments attached to AST nodes,
101
+ > check out ${ctx.link(roxygen_parse_1.parseRoxygenCommentsOfNode)}.
102
+
103
+
98
104
  ## How to Get a Normalized AST
99
105
 
100
106
  As explained alongside the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface#creating-flowr-analyses) wiki page, you can use an instance of