@eagleoutice/flowr 2.2.15 → 2.2.16

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 (212) hide show
  1. package/README.md +210 -6
  2. package/benchmark/slicer.d.ts +3 -1
  3. package/benchmark/slicer.js +8 -5
  4. package/benchmark/summarizer/first-phase/process.d.ts +2 -1
  5. package/benchmark/summarizer/first-phase/process.js +2 -2
  6. package/cli/benchmark-app.d.ts +1 -0
  7. package/cli/benchmark-app.js +4 -1
  8. package/cli/benchmark-helper-app.d.ts +1 -0
  9. package/cli/benchmark-helper-app.js +7 -8
  10. package/cli/common/options.js +2 -0
  11. package/cli/export-quads-app.js +2 -1
  12. package/cli/flowr.js +58 -57
  13. package/cli/repl/commands/repl-cfg.js +13 -13
  14. package/cli/repl/commands/repl-commands.js +2 -2
  15. package/cli/repl/commands/repl-dataflow.js +10 -10
  16. package/cli/repl/commands/repl-execute.d.ts +2 -3
  17. package/cli/repl/commands/repl-execute.js +4 -4
  18. package/cli/repl/commands/repl-lineage.js +4 -4
  19. package/cli/repl/commands/repl-main.d.ts +12 -1
  20. package/cli/repl/commands/repl-normalize.js +6 -6
  21. package/cli/repl/commands/repl-parse.js +2 -2
  22. package/cli/repl/commands/repl-query.js +9 -9
  23. package/cli/repl/commands/repl-version.js +1 -1
  24. package/cli/repl/core.d.ts +5 -2
  25. package/cli/repl/core.js +10 -8
  26. package/cli/repl/server/connection.d.ts +3 -1
  27. package/cli/repl/server/connection.js +7 -5
  28. package/cli/repl/server/server.d.ts +3 -2
  29. package/cli/repl/server/server.js +4 -2
  30. package/cli/script-core/statistics-core.d.ts +2 -1
  31. package/cli/script-core/statistics-core.js +2 -2
  32. package/cli/script-core/statistics-helper-core.d.ts +2 -1
  33. package/cli/script-core/statistics-helper-core.js +5 -4
  34. package/cli/slicer-app.js +4 -2
  35. package/cli/statistics-app.js +2 -1
  36. package/cli/statistics-helper-app.js +2 -1
  37. package/config.d.ts +12 -10
  38. package/config.js +26 -42
  39. package/control-flow/cfg-dead-code.js +45 -2
  40. package/control-flow/cfg-simplification.d.ts +2 -0
  41. package/control-flow/control-flow-graph.d.ts +1 -0
  42. package/control-flow/control-flow-graph.js +4 -0
  43. package/control-flow/dfg-cfg-guided-visitor.d.ts +5 -3
  44. package/control-flow/dfg-cfg-guided-visitor.js +15 -4
  45. package/control-flow/extract-cfg.d.ts +4 -2
  46. package/control-flow/extract-cfg.js +4 -3
  47. package/control-flow/semantic-cfg-guided-visitor.d.ts +19 -1
  48. package/control-flow/semantic-cfg-guided-visitor.js +23 -3
  49. package/core/pipeline-executor.d.ts +4 -1
  50. package/core/pipeline-executor.js +6 -5
  51. package/core/steps/all/core/10-normalize.d.ts +2 -0
  52. package/core/steps/all/core/10-normalize.js +1 -1
  53. package/core/steps/all/core/11-normalize-tree-sitter.d.ts +2 -1
  54. package/core/steps/all/core/11-normalize-tree-sitter.js +2 -2
  55. package/core/steps/all/core/20-dataflow.d.ts +2 -1
  56. package/core/steps/all/core/20-dataflow.js +2 -2
  57. package/core/steps/all/static-slicing/00-slice.d.ts +2 -1
  58. package/core/steps/all/static-slicing/00-slice.js +2 -2
  59. package/core/steps/pipeline/default-pipelines.d.ts +32 -31
  60. package/core/steps/pipeline/default-pipelines.js +8 -8
  61. package/core/steps/pipeline-step.d.ts +2 -1
  62. package/dataflow/environments/built-in-config.d.ts +3 -3
  63. package/dataflow/environments/built-in.d.ts +7 -1
  64. package/dataflow/environments/built-in.js +2 -2
  65. package/dataflow/environments/default-builtin-config.js +4 -2
  66. package/dataflow/environments/define.d.ts +2 -1
  67. package/dataflow/environments/define.js +4 -5
  68. package/dataflow/environments/remove.d.ts +6 -0
  69. package/dataflow/environments/remove.js +29 -0
  70. package/dataflow/eval/resolve/alias-tracking.d.ts +7 -2
  71. package/dataflow/eval/resolve/alias-tracking.js +9 -6
  72. package/dataflow/eval/resolve/resolve-argument.d.ts +8 -0
  73. package/dataflow/eval/resolve/resolve-argument.js +118 -0
  74. package/dataflow/eval/resolve/resolve.d.ts +18 -15
  75. package/dataflow/eval/resolve/resolve.js +20 -18
  76. package/dataflow/eval/values/string/string-constants.d.ts +1 -1
  77. package/dataflow/eval/values/string/string-constants.js +7 -2
  78. package/dataflow/extractor.d.ts +2 -1
  79. package/dataflow/extractor.js +2 -1
  80. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -6
  81. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +1 -1
  82. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +4 -2
  83. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +11 -11
  84. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +10 -11
  85. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +7 -2
  86. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -3
  87. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +1 -1
  88. package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
  89. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +2 -3
  90. package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +5 -3
  91. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +15 -15
  92. package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
  93. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +1 -1
  94. package/dataflow/internal/process/functions/call/common.js +1 -1
  95. package/dataflow/internal/process/functions/process-parameter.js +1 -1
  96. package/dataflow/origin/dfg-get-symbol-refs.d.ts +21 -0
  97. package/dataflow/origin/dfg-get-symbol-refs.js +50 -0
  98. package/dataflow/processor.d.ts +5 -0
  99. package/documentation/doc-util/doc-cfg.js +4 -3
  100. package/documentation/doc-util/doc-code.d.ts +1 -1
  101. package/documentation/doc-util/doc-dfg.js +3 -2
  102. package/documentation/doc-util/doc-functions.d.ts +24 -0
  103. package/documentation/doc-util/doc-functions.js +65 -0
  104. package/documentation/doc-util/doc-normalized-ast.js +3 -2
  105. package/documentation/doc-util/doc-print.d.ts +5 -0
  106. package/documentation/doc-util/doc-print.js +36 -0
  107. package/documentation/doc-util/doc-query.js +3 -2
  108. package/documentation/doc-util/doc-repl.js +2 -1
  109. package/documentation/doc-util/doc-search.js +3 -2
  110. package/documentation/doc-util/doc-types.d.ts +28 -6
  111. package/documentation/doc-util/doc-types.js +89 -45
  112. package/documentation/print-cfg-wiki.js +6 -7
  113. package/documentation/print-core-wiki.js +5 -5
  114. package/documentation/print-dataflow-graph-wiki.js +10 -10
  115. package/documentation/print-engines-wiki.js +1 -2
  116. package/documentation/print-faq-wiki.js +8 -2
  117. package/documentation/print-interface-wiki.js +1 -2
  118. package/documentation/print-linter-issue.d.ts +1 -0
  119. package/documentation/print-linter-issue.js +71 -0
  120. package/documentation/print-linter-wiki.js +219 -34
  121. package/documentation/print-linting-and-testing-wiki.js +2 -4
  122. package/documentation/print-normalized-ast-wiki.js +3 -3
  123. package/documentation/print-query-wiki.js +1 -2
  124. package/documentation/print-readme.js +24 -1
  125. package/documentation/print-search-wiki.js +1 -2
  126. package/linter/linter-executor.d.ts +3 -1
  127. package/linter/linter-executor.js +3 -2
  128. package/linter/linter-format.d.ts +67 -7
  129. package/linter/linter-format.js +12 -1
  130. package/linter/linter-rules.d.ts +155 -16
  131. package/linter/linter-rules.js +12 -4
  132. package/linter/linter-tags.d.ts +80 -0
  133. package/linter/linter-tags.js +85 -0
  134. package/linter/rules/absolute-path.d.ts +71 -0
  135. package/linter/rules/absolute-path.js +177 -0
  136. package/linter/rules/deprecated-functions.d.ts +43 -0
  137. package/linter/rules/deprecated-functions.js +58 -0
  138. package/linter/rules/{2-file-path-validity.d.ts → file-path-validity.d.ts} +16 -6
  139. package/linter/rules/{2-file-path-validity.js → file-path-validity.js} +21 -13
  140. package/linter/rules/naming-convention.d.ts +71 -0
  141. package/linter/rules/naming-convention.js +164 -0
  142. package/linter/rules/seeded-randomness.d.ts +65 -0
  143. package/linter/rules/seeded-randomness.js +122 -0
  144. package/linter/rules/unused-definition.d.ts +41 -0
  145. package/linter/rules/unused-definition.js +105 -0
  146. package/package.json +4 -1
  147. package/queries/base-query-format.d.ts +2 -0
  148. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  149. package/queries/catalog/call-context-query/call-context-query-executor.js +2 -2
  150. package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
  151. package/queries/catalog/config-query/config-query-executor.d.ts +1 -1
  152. package/queries/catalog/config-query/config-query-executor.js +2 -3
  153. package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +1 -1
  154. package/queries/catalog/control-flow-query/control-flow-query-executor.js +2 -2
  155. package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +1 -1
  156. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
  157. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
  158. package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -116
  159. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -1
  160. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
  161. package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
  162. package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -1
  163. package/queries/catalog/linter-query/linter-query-executor.d.ts +1 -1
  164. package/queries/catalog/linter-query/linter-query-executor.js +2 -2
  165. package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
  166. package/queries/catalog/linter-query/linter-query-format.js +16 -12
  167. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
  168. package/queries/catalog/origin-query/origin-query-format.d.ts +1 -1
  169. package/queries/catalog/project-query/project-query-format.d.ts +1 -1
  170. package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +1 -1
  171. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +2 -2
  172. package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +1 -1
  173. package/queries/catalog/search-query/search-query-executor.d.ts +1 -1
  174. package/queries/catalog/search-query/search-query-executor.js +2 -2
  175. package/queries/catalog/search-query/search-query-format.d.ts +1 -1
  176. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  177. package/queries/catalog/static-slice-query/static-slice-query-executor.js +2 -2
  178. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -1
  179. package/queries/query.d.ts +15 -15
  180. package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -1
  181. package/r-bridge/lang-4.x/ast/parser/json/parser.js +4 -2
  182. package/r-bridge/lang-4.x/convert-values.js +2 -1
  183. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +3 -1
  184. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
  185. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.d.ts +1 -1
  186. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +7 -5
  187. package/r-bridge/shell.d.ts +3 -2
  188. package/r-bridge/shell.js +4 -5
  189. package/search/flowr-search-builder.d.ts +6 -2
  190. package/search/flowr-search-builder.js +7 -0
  191. package/search/flowr-search-filters.d.ts +32 -8
  192. package/search/flowr-search-filters.js +42 -15
  193. package/search/flowr-search.d.ts +4 -0
  194. package/search/search-executor/search-enrichers.d.ts +7 -3
  195. package/search/search-executor/search-enrichers.js +29 -20
  196. package/search/search-executor/search-generators.js +1 -1
  197. package/search/search-executor/search-transformer.d.ts +2 -0
  198. package/search/search-executor/search-transformer.js +10 -1
  199. package/slicing/static/static-slicer.d.ts +1 -1
  200. package/slicing/static/static-slicer.js +2 -3
  201. package/statistics/statistics.d.ts +3 -1
  202. package/statistics/statistics.js +5 -4
  203. package/util/containers.d.ts +12 -9
  204. package/util/containers.js +12 -9
  205. package/util/objects.d.ts +5 -4
  206. package/util/range.d.ts +5 -1
  207. package/util/range.js +11 -3
  208. package/util/text/strings.d.ts +6 -0
  209. package/util/text/strings.js +35 -0
  210. package/util/version.js +1 -1
  211. package/linter/rules/1-deprecated-functions.d.ts +0 -34
  212. package/linter/rules/1-deprecated-functions.js +0 -54
@@ -32,6 +32,7 @@ const semantic_cfg_guided_visitor_1 = require("../control-flow/semantic-cfg-guid
32
32
  const doc_issue_1 = require("./doc-util/doc-issue");
33
33
  const edge_1 = require("../dataflow/graph/edge");
34
34
  const assert_1 = require("../util/assert");
35
+ const config_1 = require("../config");
35
36
  const CfgLongExample = `f <- function(a, b = 3) {
36
37
  if(a > b) {
37
38
  return(a * b);
@@ -103,8 +104,8 @@ class CollectNumbersDataflowVisitor extends dfg_cfg_guided_visitor_1.DataflowAwa
103
104
  }
104
105
  class CollectSourcesSemanticVisitor extends semantic_cfg_guided_visitor_1.SemanticCfgGuidedVisitor {
105
106
  sources = [];
106
- constructor(controlFlow, normalizedAst, dataflow) {
107
- super({ controlFlow, normalizedAst, dfg: dataflow, defaultVisitingOrder: 'forward' });
107
+ constructor(controlFlow, normalizedAst, dataflow, config) {
108
+ super({ controlFlow, normalizedAst, dfg: dataflow, flowrConfig: config, defaultVisitingOrder: 'forward' });
108
109
  }
109
110
  onAssignmentCall({ source }) {
110
111
  if (source) {
@@ -117,14 +118,12 @@ class CollectSourcesSemanticVisitor extends semantic_cfg_guided_visitor_1.Semant
117
118
  }
118
119
  async function getText(shell) {
119
120
  const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
120
- const types = (0, doc_types_1.getTypesFromFolderAsMermaid)({
121
+ const types = (0, doc_types_1.getTypesFromFolder)({
121
122
  rootFolder: path_1.default.resolve('./src'),
122
- typeName: 'RNode',
123
123
  inlineTypes: doc_types_1.mermaidHide
124
124
  });
125
- const testTypes = (0, doc_types_1.getTypesFromFolderAsMermaid)({
125
+ const testTypes = (0, doc_types_1.getTypesFromFolder)({
126
126
  rootFolder: path_1.default.resolve('./test'),
127
- typeName: 'assertCfg',
128
127
  inlineTypes: doc_types_1.mermaidHide
129
128
  });
130
129
  return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'control flow graph', rVersion: rversion })}
@@ -500,7 +499,7 @@ Executing it with the CFG and Dataflow of the expression \`x <- 2; 3 -> x; assig
500
499
 
501
500
  ${await (async () => {
502
501
  const res = await (0, doc_cfg_1.getCfg)(shell, 'x <- 2; 3 -> x; assign("x", 42 + 21)');
503
- const visitor = new CollectSourcesSemanticVisitor(res.info, res.ast, res.dataflow.graph);
502
+ const visitor = new CollectSourcesSemanticVisitor(res.info, res.ast, res.dataflow.graph, config_1.defaultConfigOptions);
504
503
  visitor.start();
505
504
  const collected = visitor.getSources();
506
505
  return collected.map(n => '\n- `' + n + '`').join('');
@@ -42,12 +42,12 @@ const normalize_for_1 = require("../r-bridge/lang-4.x/ast/parser/main/internal/l
42
42
  const doc_issue_1 = require("./doc-util/doc-issue");
43
43
  const pipeline_executor_1 = require("../core/pipeline-executor");
44
44
  const pipeline_1 = require("../core/steps/pipeline/pipeline");
45
+ const config_1 = require("../config");
45
46
  async function getText(shell) {
46
47
  const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
47
48
  const sampleCode = 'x <- 1; print(x)';
48
- const { info, program } = (0, doc_types_1.getTypesFromFolderAsMermaid)({
49
+ const { info, program } = (0, doc_types_1.getTypesFromFolder)({
49
50
  rootFolder: path_1.default.resolve('./src'),
50
- typeName: shell_1.RShell.name,
51
51
  inlineTypes: doc_types_1.mermaidHide
52
52
  });
53
53
  return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'core', rVersion: rversion })}
@@ -112,7 +112,7 @@ const result = await executor.allRemainingSteps();
112
112
  `)}
113
113
 
114
114
  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).
115
- 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)('') }).allRemainingSteps.name}`, info)}
115
+ 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)}
116
116
  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).
117
117
  ${(0, doc_types_1.shortLink)(retriever_1.requestFromInput.name, info)} is merely a convenience function to create a request object from a code string.
118
118
 
@@ -254,7 +254,7 @@ While looking at the mermaid visualization of such an AST is nice and usually su
254
254
 
255
255
  Let's have a look at the normalized AST for the sample code \`${sampleCode}\` (please refer to the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized-AST) wiki page for more information):
256
256
 
257
- ${(0, doc_structure_1.details)('Normalized AST for <code>x <- 1; print(x)</code>', (0, doc_code_1.codeBlock)('json', JSON.stringify((await (0, default_pipelines_1.createNormalizePipeline)(shell, { request: (0, retriever_1.requestFromInput)(sampleCode) }).allRemainingSteps()).normalize.ast, json_1.jsonReplacer, 4)))}
257
+ ${(0, doc_structure_1.details)('Normalized AST for <code>x <- 1; print(x)</code>', (0, doc_code_1.codeBlock)('json', JSON.stringify((await (0, default_pipelines_1.createNormalizePipeline)(shell, { request: (0, retriever_1.requestFromInput)(sampleCode) }, config_1.defaultConfigOptions).allRemainingSteps()).normalize.ast, json_1.jsonReplacer, 4)))}
258
258
 
259
259
  This is… a lot! We get the type from the ${(0, doc_types_1.shortLink)('RType', info)} enum, the lexeme, location information, an id, the children of the node, and their parents.
260
260
  While the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized-AST) wiki page provides you with information on how to interpret this data, we will focus on how we get it from the
@@ -275,7 +275,7 @@ For single nodes, we use ${(0, doc_types_1.shortLink)(normalize_single_node_1.no
275
275
 
276
276
  The output of just this pass is listed below (using the ${(0, doc_types_1.shortLink)(parser_2.normalizeButNotDecorated.name, info)} function):
277
277
 
278
- ${(0, doc_structure_1.details)('Ast for <code>x <- 1; print(x)</code> after the first normalization', (0, doc_code_1.codeBlock)('json', JSON.stringify((0, parser_2.normalizeButNotDecorated)((await (0, default_pipelines_1.createParsePipeline)(shell, { request: (0, retriever_1.requestFromInput)(sampleCode) }).allRemainingSteps()).parse), json_1.jsonReplacer, 4)))}
278
+ ${(0, doc_structure_1.details)('Ast for <code>x <- 1; print(x)</code> after the first normalization', (0, doc_code_1.codeBlock)('json', JSON.stringify((0, parser_2.normalizeButNotDecorated)((await (0, default_pipelines_1.createParsePipeline)(shell, { request: (0, retriever_1.requestFromInput)(sampleCode) }, config_1.defaultConfigOptions).allRemainingSteps()).parse), json_1.jsonReplacer, 4)))}
279
279
 
280
280
 
281
281
  #### Decorating the AST
@@ -38,6 +38,7 @@ const alias_tracking_1 = require("../dataflow/eval/resolve/alias-tracking");
38
38
  const doc_issue_1 = require("./doc-util/doc-issue");
39
39
  const unnamed_call_handling_1 = require("../dataflow/internal/process/functions/call/unnamed-call-handling");
40
40
  const environment_builder_1 = require("../../test/functionality/_helper/dataflow/environment-builder");
41
+ const config_1 = require("../config");
41
42
  async function subExplanation(shell, { description, code, expectedSubgraph }) {
42
43
  expectedSubgraph = await (0, doc_dfg_1.verifyExpectedSubgraph)(shell, code, expectedSubgraph);
43
44
  const marks = [];
@@ -204,9 +205,8 @@ ${(0, doc_structure_1.details)('Example: Simple Function Call (unresolved)', awa
204
205
  (0, assert_1.guard)(callInfo !== undefined, () => `Could not find call vertex for ${code}`);
205
206
  const [callId, callVert] = callInfo;
206
207
  const inverseMapReferenceTypes = Object.fromEntries(Object.entries(identifier_1.ReferenceType).map(([k, v]) => [v, k]));
207
- const identifierType = (0, doc_types_1.getTypesFromFolderAsMermaid)({
208
+ const identifierType = (0, doc_types_1.getTypesFromFolder)({
208
209
  files: [path_1.default.resolve('./src/dataflow/environments/identifier.ts')],
209
- typeName: 'IdentifierReference',
210
210
  inlineTypes: ['ControlDependency']
211
211
  });
212
212
  return `
@@ -745,21 +745,21 @@ async function dummyDataflow() {
745
745
  const result = await new pipeline_executor_1.PipelineExecutor(default_pipelines_1.DEFAULT_DATAFLOW_PIPELINE, {
746
746
  parser: shell,
747
747
  request: (0, retriever_1.requestFromInput)('x <- 1\nx + 1')
748
- }).allRemainingSteps();
748
+ }, config_1.defaultConfigOptions).allRemainingSteps();
749
749
  shell.close();
750
750
  return result;
751
751
  }
752
752
  async function getText(shell) {
753
753
  const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
754
754
  /* we collect type information on the graph */
755
- const vertexType = (0, doc_types_1.getTypesFromFolderAsMermaid)({
755
+ const vertexType = (0, doc_types_1.getTypesFromFolder)({
756
756
  rootFolder: path_1.default.resolve('./src/'),
757
- typeName: 'DataflowGraphVertexInfo',
757
+ typeNameForMermaid: 'DataflowGraphVertexInfo',
758
758
  inlineTypes: ['MergeableRecord']
759
759
  });
760
- const edgeType = (0, doc_types_1.getTypesFromFolderAsMermaid)({
760
+ const edgeType = (0, doc_types_1.getTypesFromFolder)({
761
761
  files: [path_1.default.resolve('./src/dataflow/graph/edge.ts'), path_1.default.resolve('./src/dataflow/graph/graph.ts'), path_1.default.resolve('./src/dataflow/environments/identifier.ts'), path_1.default.resolve('./src/dataflow/info.ts')],
762
- typeName: 'EdgeType',
762
+ typeNameForMermaid: 'EdgeType',
763
763
  inlineTypes: ['MergeableRecord']
764
764
  });
765
765
  return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'dataflow graph', rVersion: rversion })}
@@ -807,7 +807,7 @@ The following vertices types exist:
807
807
 
808
808
  1. ${(0, doc_data_dfg_util_1.getAllVertices)().map(([k, v], index) => `[\`${k}\`](#${index + 1}-${v.toLowerCase().replace(/\s/g, '-')}-vertex)`).join('\n1. ')}
809
809
 
810
- ${vertexType.text.trim().length > 0 ? (0, doc_structure_1.details)('Class Diagram', 'All boxes should link to their respective implementation:\n' + (0, doc_code_1.codeBlock)('mermaid', vertexType.text)) : ''}
810
+ ${vertexType.mermaid.trim().length > 0 ? (0, doc_structure_1.details)('Class Diagram', 'All boxes should link to their respective implementation:\n' + (0, doc_code_1.codeBlock)('mermaid', vertexType.mermaid)) : ''}
811
811
 
812
812
  </details>
813
813
 
@@ -819,7 +819,7 @@ The following edges types exist, internally we use bitmasks to represent multipl
819
819
 
820
820
  1. ${(0, doc_data_dfg_util_1.getAllEdges)().map(([k, v], index) => `[\`${k}\` (${v})](#${index + 1}-${k.toLowerCase().replace(/\s/g, '-')}-edge)`).join('\n1. ')}
821
821
 
822
- ${edgeType.text.trim().length > 0 ? (0, doc_structure_1.details)('Class Diagram', 'All boxes should link to their respective implementation:\n' + (0, doc_code_1.codeBlock)('mermaid', edgeType.text)) : ''}
822
+ ${edgeType.mermaid.trim().length > 0 ? (0, doc_structure_1.details)('Class Diagram', 'All boxes should link to their respective implementation:\n' + (0, doc_code_1.codeBlock)('mermaid', edgeType.mermaid)) : ''}
823
823
 
824
824
  </details>
825
825
 
@@ -1005,7 +1005,7 @@ Retrieving the _types_ of the edge from the print call to its argument returns:
1005
1005
  ${await (async () => {
1006
1006
  const dfg = await (0, default_pipelines_1.createDataflowPipeline)(shell, {
1007
1007
  request: (0, retriever_1.requestFromInput)('print(x)')
1008
- }).allRemainingSteps();
1008
+ }, config_1.defaultConfigOptions).allRemainingSteps();
1009
1009
  const edge = dfg.dataflow.graph.outgoingEdges(3);
1010
1010
  if (edge) {
1011
1011
  const wanted = edge.get(1);
@@ -15,10 +15,9 @@ const doc_cli_option_1 = require("./doc-util/doc-cli-option");
15
15
  const doc_structure_1 = require("./doc-util/doc-structure");
16
16
  async function getText(shell) {
17
17
  const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
18
- const types = (0, doc_types_1.getTypesFromFolderAsMermaid)({
18
+ const types = (0, doc_types_1.getTypesFromFolder)({
19
19
  rootFolder: path_1.default.resolve('src/r-bridge/lang-4.x/tree-sitter/'),
20
20
  files: [path_1.default.resolve('./src/config.ts'), path_1.default.resolve('./src/r-bridge/shell.ts'), path_1.default.resolve('./src/r-bridge/shell-executor.ts')],
21
- typeName: 'FlowrConfigOptions',
22
21
  inlineTypes: doc_types_1.mermaidHide
23
22
  });
24
23
  return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'engines', rVersion: rversion })}
@@ -24,14 +24,20 @@ There are several ways to generate mermaid diagrams based on the input data that
24
24
 
25
25
  ${qAndA('How do I create new wiki pages?', `
26
26
  To create an automatically generated wiki page, you can follow these steps:
27
- - Createa a new file in \`src/documentation\` with a name like \`print-my-page-wiki.ts\`.
27
+ - Create a new file in \`src/documentation\` with a name like \`print-my-page-wiki.ts\`.
28
28
  - Add a new wiki generation script to the ${(0, doc_files_1.getFilePathMd)('../../package.json')}. You can copy one of the existing ones of the form \`"wiki:my-page": "ts-node src/documentation/print-my-page-wiki.ts"\`.
29
29
  - Add the wiki generation script to the \`broken-links-and-wiki.yml\` GitHub workflow file to enable automatic generation through the CI. You can copy one of the existing ones of the form \`update_page wiki/"My page" wiki:my-page\`.
30
30
 
31
31
  You can test your page by piping the wiki generation script to a file. For example, you can run the following command:
32
32
  ${(0, doc_code_1.codeBlock)('shell', 'npm run --silent wiki:my-page > __my-page.md')}
33
- `)}
33
+
34
34
  Remember not to commit this file, as it's only meant for testing.
35
+ `)}
36
+
37
+ ${qAndA('Why can\'t I pass arguments when running flowR with npm?', `
38
+ With \`npm\` you have to pass arguments in a specific way. The \`--\` operator is used to separate the \`npm\` arguments from the script arguments. For example, if you want to run \`flowR\` with the \`--help\` argument, you can use the following command:
39
+ ${(0, doc_code_1.codeBlock)('shell', 'npm run flowR -- --help')}
40
+ `)}
35
41
 
36
42
  ## 🇷 R FAQ
37
43
 
@@ -249,10 +249,9 @@ ${(0, schema_1.describeSchema)(config_1.flowrConfigFileSchema, ansi_1.markdownFo
249
249
  `;
250
250
  }
251
251
  function explainWritingCode(shell) {
252
- const types = (0, doc_types_1.getTypesFromFolderAsMermaid)({
252
+ const types = (0, doc_types_1.getTypesFromFolder)({
253
253
  rootFolder: path_1.default.resolve('./src/'),
254
254
  files: [path_1.default.resolve('./src/core/pipeline-executor.ts'), path_1.default.resolve('./src/core/steps/pipeline/default-pipelines.ts')],
255
- typeName: 'RShell',
256
255
  inlineTypes: doc_types_1.mermaidHide
257
256
  });
258
257
  return `
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,71 @@
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 log_1 = require("../../test/functionality/_helper/log");
7
+ const doc_types_1 = require("./doc-util/doc-types");
8
+ const path_1 = __importDefault(require("path"));
9
+ const linter_tags_1 = require("../linter/linter-tags");
10
+ const doc_general_1 = require("./doc-util/doc-general");
11
+ const doc_files_1 = require("./doc-util/doc-files");
12
+ const linter_rules_1 = require("../linter/linter-rules");
13
+ /* this prints the yaml configuration for the GitHub issue template to request a new linter rule / an update */
14
+ function summarizeIfTooLong(text, maxLength = 52) {
15
+ if (text.length <= maxLength) {
16
+ return text;
17
+ }
18
+ return text.slice(0, maxLength - 1) + '…';
19
+ }
20
+ function getText() {
21
+ const types = (0, doc_types_1.getTypesFromFolder)({
22
+ rootFolder: path_1.default.resolve('./src/linter/')
23
+ });
24
+ return `
25
+ name: Linting Rule
26
+ description: Suggest either a new linting rule or an improvement to an existing one.
27
+ title: "[Linter]: "
28
+ labels: ["flowr linter"]
29
+ body:
30
+ - type: markdown
31
+ attributes:
32
+ value: |
33
+ Thank you for suggesting a new linting rule or an improvement to an existing one. Please provide as much detail as possible to help us understand your request. See the [Linter Wiki Page](${doc_files_1.FlowrWikiBaseRef}/Linter) for more information.
34
+ - type: textarea
35
+ id: description
36
+ attributes:
37
+ label: Description
38
+ description: |
39
+ Please provide a detailed description of the linting rule you are suggesting or the improvement you would like to see. Include examples if possible.
40
+ validations:
41
+ required: true
42
+ - type: dropdown
43
+ id: linting-rule
44
+ attributes:
45
+ label: Linting Rule
46
+ description: |
47
+ Select the linting rule that you are suggesting or improving. If it is a new rule, select "New Rule".
48
+ options:
49
+ - New Rule
50
+ ${(0, doc_general_1.prefixLines)(Object.keys(linter_rules_1.LintingRules).sort().map(name => {
51
+ const rule = linter_rules_1.LintingRules[name];
52
+ return `- ${rule.info.name}`;
53
+ }).join('\n'), ' ')}
54
+ default: 0
55
+ - type: checkboxes
56
+ id: tags
57
+ attributes:
58
+ label: Meta Information
59
+ description: Select any tags that you think apply to the linting rule you are suggesting. If you try to suggest a new linting rule, please only select those that you think apply after your suggestions.
60
+ options:
61
+ ${(0, doc_general_1.prefixLines)(Object.entries(linter_tags_1.LintingRuleTag).map(([name]) => {
62
+ return `- label: '**${name}**: ${summarizeIfTooLong((0, doc_types_1.getDocumentationForType)('LintingRuleTag::' + name, types.info).replaceAll(/\n/g, ' ').replaceAll('\'', '\\\'').trim())}'\n required: false`;
63
+ }).join('\n'), ' ')}
64
+ `.trim();
65
+ }
66
+ /** if we run this script, we want a Markdown representation of the capabilities */
67
+ if (require.main === module) {
68
+ (0, log_1.setMinLevelOfAllLogs)(6 /* LogLevel.Fatal */);
69
+ console.log(getText());
70
+ }
71
+ //# sourceMappingURL=print-linter-issue.js.map
@@ -12,48 +12,147 @@ const shell_1 = require("../r-bridge/shell");
12
12
  const doc_query_1 = require("./doc-util/doc-query");
13
13
  const doc_types_1 = require("./doc-util/doc-types");
14
14
  const path_1 = __importDefault(require("path"));
15
- async function getText(shell) {
16
- const rVersion = (await shell.usedRVersion())?.format() ?? 'unknown';
17
- return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'linter', rVersion })}
18
-
19
- This page describes the flowR linter, which is a tool that utilizes flowR's dataflow analysis to find common issues in R scripts. The linter can currently be used through the linter [query](${doc_files_1.FlowrWikiBaseRef}/Query%20API).
15
+ const doc_repl_1 = require("./doc-util/doc-repl");
16
+ const doc_structure_1 = require("./doc-util/doc-structure");
17
+ const linter_tags_1 = require("../linter/linter-tags");
18
+ const html_hover_over_1 = require("../util/html-hover-over");
19
+ const strings_1 = require("../util/text/strings");
20
+ const assert_1 = require("../util/assert");
21
+ const doc_print_1 = require("./doc-util/doc-print");
22
+ const doc_functions_1 = require("./doc-util/doc-functions");
23
+ const SpecialTagColors = {
24
+ [linter_tags_1.LintingRuleTag.Bug]: 'red',
25
+ [linter_tags_1.LintingRuleTag.Security]: 'orange',
26
+ [linter_tags_1.LintingRuleTag.Smell]: 'yellow',
27
+ [linter_tags_1.LintingRuleTag.QuickFix]: 'lightgray',
28
+ };
29
+ function makeTagBadge(name, info) {
30
+ const doc = (0, doc_types_1.getDocumentationForType)('LintingRuleTag::' + name, info, '', true).replaceAll('\n', ' ');
31
+ return (0, html_hover_over_1.textWithTooltip)(`<a href='#${name}'>![` + name + '](https://img.shields.io/badge/' + name.toLowerCase() + `-${SpecialTagColors[name] ?? 'teal'}) </a>`, doc);
32
+ }
33
+ function prettyPrintExpectedOutput(expected) {
34
+ if (expected.trim() === '[]') {
35
+ return '* no lints';
36
+ }
37
+ let lines = expected.trim().split('\n');
38
+ if (lines.length <= 1) {
39
+ return expected;
40
+ }
41
+ //
42
+ lines = expected.trim().replace(/^\s*\[+\s*{*/m, '').replace(/\s*}*\s*]+\s*$/, '').split('\n').filter(l => l.trim() !== '');
43
+ /* take the indentation of the last line and remove it from all but the first: */
44
+ const indentation = lines[lines.length - 1].match(/^\s*/)?.[0] ?? '';
45
+ return lines.map((line, i) => {
46
+ if (i === 0) {
47
+ return line;
48
+ }
49
+ return line.replace(new RegExp('^' + indentation, 'g'), '');
50
+ }).join('\n');
51
+ }
52
+ function buildSamplesFromLinterTestCases(shell, testFile) {
53
+ const reports = (0, doc_functions_1.getFunctionsFromFolder)({ files: [path_1.default.resolve('test/functionality/linter/' + testFile)], fname: /assertLinter/ });
54
+ if (reports.info.length === 0) {
55
+ return '';
56
+ }
57
+ let result = `#### Additional Examples
58
+
59
+ These examples are synthesized from the test cases in: ${(0, doc_files_1.linkFlowRSourceFile)('test/functionality/linter/' + testFile)}\n\n`;
60
+ for (const report of reports.info) {
61
+ const args = report.arguments;
62
+ if (args.length < 5) {
63
+ console.error('Test case for linter rule ' + report.name + ' does not have enough arguments! Expected at least 5, got ' + args.length);
64
+ continue;
65
+ }
66
+ const testName = args[0].getText(report.source);
67
+ if (report.comments?.some(c => c.includes('@ignore-in-wiki'))) {
68
+ console.warn(`Skipping test case for linter rule ${testName} (${testFile}) as it is marked with @ignore-in-wiki`);
69
+ continue;
70
+ }
71
+ // drop any quotes around the test name
72
+ const testNameClean = testName.replace(/^['"]|['"]$/g, '');
73
+ result += `\n${(0, doc_structure_1.section)('Test Case: ' + testNameClean, 4)}
20
74
 
21
- ## Linting Rules
75
+ ${report.comments ? report.comments.map(c => `> ${c}`).join('\n') + '\n' : ''}
76
+ Given the following input:
77
+ ${(0, doc_code_1.codeBlock)('r', args[2].getText(report.source).replace(/^['"]|['"]$/g, '').replace(/\\n/g, '\n'))}
78
+ ${args.length >= 7 ? `\nAnd using the following [configuration](#configuration): ${(0, doc_code_1.codeBlock)('ts', prettyPrintExpectedOutput(args[6].getText(report.source)))}` : ''}
22
79
 
23
- The following linting rules are available:
80
+ We expect the linter to report the following:
81
+ ${(0, doc_code_1.codeBlock)('ts', prettyPrintExpectedOutput(args[4].getText(report.source)))}
24
82
 
25
- ${await rule(shell, 'deprecated-functions', 'DeprecatedFunctionsConfig', 'Deprecated Functions', 'This rule detects the usage of deprecated functions in code based on a predefined list of known deprecated functions.', `
83
+ See [here](${(0, doc_types_1.getTypePathLink)({ filePath: report.source.fileName, lineNumber: report.lineNumber })}) for the test-case implementation.
84
+ `;
85
+ }
86
+ return result;
87
+ }
88
+ function registerRules(rVersion, shell, tagTypes, format = 'short') {
89
+ const ruleExplanations = new Map();
90
+ rule(shell, 'deprecated-functions', 'DeprecatedFunctionsConfig', 'DEPRECATED_FUNCTIONS', 'lint-deprecated-functions', `
26
91
  first <- data.frame(x = c(1, 2, 3), y = c(1, 2, 3))
27
92
  second <- data.frame(x = c(1, 3, 2), y = c(1, 3, 2))
28
93
  dplyr::all_equal(first, second)
29
- `)}
30
-
31
- ${await rule(shell, 'file-path-validity', 'FilePathValidityConfig', 'File Path Validity', 'This rule finds places in the code where files are being read from. In such places, it checks whether the file path is valid and whether the file exists on disk.', `
94
+ `, tagTypes);
95
+ rule(shell, 'file-path-validity', 'FilePathValidityConfig', 'FILE_PATH_VALIDITY', 'lint-file-path-validity', `
32
96
  my_data <- read.csv("C:/Users/me/Documents/My R Scripts/Reproducible.csv")
33
- `)}
97
+ `, tagTypes);
98
+ rule(shell, 'absolute-file-paths', 'AbsoluteFilePathConfig', 'ABSOLUTE_PATH', 'lint-absolute-path', `
99
+ read.csv("C:/Users/me/Documents/My R Scripts/Reproducible.csv")
100
+ `, tagTypes);
101
+ rule(shell, 'unused-definitions', 'UnusedDefinitionConfig', 'UNUSED_DEFINITION', 'lint-unused-definition', `
102
+ x <- 42
103
+ y <- 3
104
+ print(x)
105
+ `, tagTypes);
106
+ rule(shell, 'seeded-randomness', 'SeededRandomnessConfig', 'SEEDED_RANDOMNESS', 'lint-seeded-randomness', 'runif(1)', tagTypes);
107
+ rule(shell, 'naming-convention', 'NamingConventionConfig', 'NAMING_CONVENTION', 'lint-naming-convention', `
108
+ myVar <- 42
109
+ print(myVar)
110
+ `, tagTypes);
111
+ function rule(shell, name, configType, ruleType, testfile, example, types) {
112
+ const rule = linter_rules_1.LintingRules[name];
113
+ const tags = rule.info.tags.toSorted((a, b) => {
114
+ // sort but specials first
115
+ if (a === b) {
116
+ return 0;
117
+ }
118
+ if (SpecialTagColors[a] && SpecialTagColors[b]) {
119
+ return SpecialTagColors[b].localeCompare(SpecialTagColors[a]);
120
+ }
121
+ else if (SpecialTagColors[a]) {
122
+ return -1;
123
+ }
124
+ else if (SpecialTagColors[b]) {
125
+ return 1;
126
+ }
127
+ return a.localeCompare(b);
128
+ }).map(t => makeTagBadge(t, types)).join(' ');
129
+ if (format === 'short') {
130
+ ruleExplanations.set(name, () => Promise.resolve(`
131
+ **[${rule.info.name}](${doc_files_1.FlowrWikiBaseRef}/lint-${name}):** ${rule.info.description} [see ${(0, doc_types_1.shortLinkFile)(ruleType, types)}]\\
132
+ ${tags}
34
133
 
35
- `.trim();
36
- }
37
- async function rule(shell, name, configType, friendlyName, description, example) {
38
- const types = (0, doc_types_1.getTypesFromFolderAsMermaid)({
39
- rootFolder: path_1.default.resolve('./src/linter/'),
40
- typeName: configType,
41
- inlineTypes: doc_types_1.mermaidHide
42
- });
43
- return `
44
- ### ${friendlyName} (\`${name}\`)
45
-
46
- ${description}
134
+ `.trim()));
135
+ }
136
+ else {
137
+ ruleExplanations.set(name, async () => `
47
138
 
48
- <details>
139
+ ${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'linter', rVersion })}
140
+ ${(0, doc_structure_1.section)(rule.info.name + `&emsp;<sup>[<a href="${doc_files_1.FlowrWikiBaseRef}/Linter">overview</a>]</sup>`, 2, name)}
49
141
 
50
- #### Configuration
142
+ ${tags}
143
+
144
+ ${rule.info.description}\\
145
+ _This linting rule is implemented in ${(0, doc_types_1.shortLinkFile)(ruleType, types)}._
51
146
 
52
- Linting rules can be configured by passing a configuration object to the linter query as shown in the example below. The \`${name}\` rule accepts the following configuration options:
53
147
 
54
- ${Object.getOwnPropertyNames(linter_rules_1.LintingRules[name].defaultConfig).sort().map(key => `- ${(0, doc_types_1.shortLink)(`${configType}:::${key}`, types.info)}\\\n${(0, doc_types_1.getDocumentationForType)(`${configType}::${key}`, types.info)}`).join('\n')}
148
+ ### Configuration
55
149
 
56
- #### Example
150
+ Linting rules can be configured by passing a configuration object to the linter query as shown in the example below.
151
+ The \`${name}\` rule accepts the following configuration options:
152
+
153
+ ${Object.getOwnPropertyNames(linter_rules_1.LintingRules[name].info.defaultConfig).sort().map(key => `- ${(0, doc_types_1.shortLink)(`${configType}:::${key}`, types)}\\\n${(0, doc_types_1.getDocumentationForType)(`${configType}::${key}`, types)}`).join('\n')}
154
+
155
+ ### Examples
57
156
 
58
157
  ${(0, doc_code_1.codeBlock)('r', example)}
59
158
 
@@ -61,16 +160,102 @@ The linting query can be used to run this rule on the above example:
61
160
 
62
161
  ${await (0, doc_query_1.showQuery)(shell, example, [{ type: 'linter', rules: [{ name, config: {} }] }], { collapseQuery: true })}
63
162
 
64
- </details>
65
- `.trim();
163
+ ${buildSamplesFromLinterTestCases(shell, `${testfile}.test.ts`)}
164
+
165
+ `.trim());
166
+ }
167
+ }
168
+ return ruleExplanations;
169
+ }
170
+ function getAllLintingRulesWitTag(tag) {
171
+ return Object.entries(linter_rules_1.LintingRules).filter(([_, rule]) => rule.info.tags.includes(tag)).map(([name]) => name);
172
+ }
173
+ function linkToRule(name) {
174
+ return `[${name}](${doc_files_1.FlowrWikiBaseRef}/lint-${name})`;
175
+ }
176
+ async function getTextMainPage(shell, tagTypes, rVersion) {
177
+ const rules = registerRules(rVersion, shell, tagTypes.info);
178
+ return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'linter', rVersion })}
179
+
180
+ This page describes the flowR linter, which is a tool that utilizes flowR's dataflow analysis to find common issues in R scripts. The linter can currently be used through the linter [query](${doc_files_1.FlowrWikiBaseRef}/Query%20API).
181
+ For example:
182
+
183
+ ${await (async () => {
184
+ const code = 'read.csv("/root/x.txt")';
185
+ const res = await (0, doc_query_1.showQuery)(shell, code, [{ type: 'linter' }], { showCode: false, collapseQuery: true, collapseResult: false });
186
+ return await (0, doc_repl_1.documentReplSession)(shell, [{
187
+ command: `:query @linter ${JSON.stringify(code)}`,
188
+ description: `
189
+ The linter will analyze the code and return any issues found.
190
+ Formatted more nicely, this returns:
191
+
192
+ ${res}
193
+ `
194
+ }]);
195
+ })()}
196
+
197
+ ${(0, doc_structure_1.section)('Linting Rules', 2, 'linting-rules')}
198
+
199
+ The following linting rules are available:
200
+
201
+ ${await (async () => {
202
+ let result = '';
203
+ for (const k of Object.keys(linter_rules_1.LintingRules).sort()) {
204
+ const rule = rules.get(k);
205
+ (0, assert_1.guard)(rule !== undefined, `Linting rule ${k} is not documented!`);
206
+ result += '\n\n' + await rule();
207
+ }
208
+ return result;
209
+ })()}
210
+
211
+ ${(0, doc_structure_1.section)('Tags', 2, 'tags')}
212
+
213
+ We use tags to categorize linting rules. The following tags are available:
214
+
215
+ | Tag/Badge&emsp;&emsp; | Description |
216
+ | --- | :-- |
217
+ ${Object.entries(linter_tags_1.LintingRuleTag).map(([name, tag]) => {
218
+ return `| <a id="${tag}"></a> ${makeTagBadge(tag, tagTypes.info)} | ${(0, doc_types_1.getDocumentationForType)('LintingRuleTag::' + name, tagTypes.info).replaceAll(/\n/g, ' ')} (rule${getAllLintingRulesWitTag(tag).length === 1 ? '' : 's'}: ${(0, strings_1.joinWithLast)(getAllLintingRulesWitTag(tag).map(l => linkToRule(l))) || '_none_'}) | `;
219
+ }).join('\n')}
220
+
221
+ `.trim();
222
+ }
223
+ async function getRulesPages(shell, tagTypes, rVersion) {
224
+ const rules = registerRules(rVersion, shell, tagTypes.info, 'long');
225
+ const result = {};
226
+ for (const [name, rule] of rules) {
227
+ const filepath = path_1.default.resolve('./wiki', `lint-${name}.md`);
228
+ result[filepath] = await rule();
229
+ }
230
+ return result;
231
+ }
232
+ /** Maps file-names to their content, the 'main' file is named 'main' */
233
+ async function getTexts(shell) {
234
+ const rVersion = (await shell.usedRVersion())?.format() ?? 'unknown';
235
+ const tagTypes = (0, doc_types_1.getTypesFromFolder)({
236
+ rootFolder: path_1.default.resolve('./src/linter/'),
237
+ inlineTypes: doc_types_1.mermaidHide
238
+ });
239
+ return {
240
+ 'main': await getTextMainPage(shell, tagTypes, rVersion),
241
+ ...await getRulesPages(shell, tagTypes, rVersion)
242
+ };
66
243
  }
244
+ /* As an intermediary solution to changing the wiki system, we make this script generate separate files for each linter rule using fixed paths */
67
245
  if (require.main === module) {
68
246
  (0, log_1.setMinLevelOfAllLogs)(6 /* LogLevel.Fatal */);
69
247
  const shell = new shell_1.RShell();
70
- void getText(shell).then(str => {
71
- console.log(str);
248
+ void (getTexts(shell).then(data => {
249
+ console.log(data['main']);
250
+ for (const [file, content] of Object.entries(data)) {
251
+ if (file === 'main') {
252
+ continue; // main is printed above
253
+ }
254
+ const filepath = path_1.default.resolve('./wiki', file);
255
+ (0, doc_print_1.writeWikiTo)(content, filepath);
256
+ }
72
257
  }).finally(() => {
73
258
  shell.close();
74
- });
259
+ }));
75
260
  }
76
261
  //# sourceMappingURL=print-linter-wiki.js.map
@@ -11,10 +11,10 @@ const doc_types_1 = require("./doc-util/doc-types");
11
11
  const path_1 = __importDefault(require("path"));
12
12
  const doc_auto_gen_1 = require("./doc-util/doc-auto-gen");
13
13
  function getText() {
14
- const { info } = (0, doc_types_1.getTypesFromFolderAsMermaid)({
14
+ const { info } = (0, doc_types_1.getTypesFromFolder)({
15
15
  rootFolder: path_1.default.resolve('./test'),
16
16
  files: [path_1.default.resolve('./src/dataflow/graph/dataflowgraph-builder.ts')],
17
- typeName: 'parameter',
17
+ typeNameForMermaid: 'parameter',
18
18
  inlineTypes: doc_types_1.mermaidHide
19
19
  });
20
20
  return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'linting and testing definitions' })}
@@ -188,8 +188,6 @@ See [test/performance](${doc_files_1.RemoteFlowrFilePathBaseRef}test/performance
188
188
  Using the vitest Extension for Visual Studio Code, you can start tests directly from the definition and explore your suite in the Testing tab.
189
189
  To get started, install the [vitest Extension](https://marketplace.visualstudio.com/items?itemName=vitest.explorer).
190
190
 
191
- ![vscode market place](img/vs-code-vitest.png)
192
-
193
191
  | Testing Tab | In Code |
194
192
  |:---------------------------------------:|:-------------------------------------:|
195
193
  | ![testing tab](img/testing-vs-code.png) | ![in code](img/testing-vs-code-2.png) |
@@ -23,9 +23,9 @@ const default_pipelines_1 = require("../core/steps/pipeline/default-pipelines");
23
23
  async function getText(shell) {
24
24
  const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
25
25
  const now = performance.now();
26
- const types = (0, doc_types_1.getTypesFromFolderAsMermaid)({
26
+ const types = (0, doc_types_1.getTypesFromFolder)({
27
27
  rootFolder: path_1.default.resolve('./src'),
28
- typeName: 'RNode',
28
+ typeNameForMermaid: 'RNode',
29
29
  inlineTypes: doc_types_1.mermaidHide
30
30
  });
31
31
  const elapsed = performance.now() - now;
@@ -70,7 +70,7 @@ In general, we provide node types for:
70
70
  Every node is a link, which directly refers to the implementation in the source code.
71
71
  Grayed-out parts are used for structuring the AST, grouping together related nodes.
72
72
 
73
- ${(0, doc_code_1.codeBlock)('mermaid', types.text)}
73
+ ${(0, doc_code_1.codeBlock)('mermaid', types.mermaid)}
74
74
 
75
75
  _The generation of the class diagram required ${(0, time_1.printAsMs)(elapsed)}._
76
76
  </details>
@@ -564,9 +564,8 @@ ${await (0, doc_cfg_1.printCfgCode)(shell, exampleCode, { showCode: false, prefi
564
564
  functionName: location_map_query_executor_1.executeLocationMapQuery.name,
565
565
  functionFile: '../queries/catalog/location-map-query/location-map-query-executor.ts',
566
566
  buildExplanation: async (shell) => {
567
- const types = (0, doc_types_1.getTypesFromFolderAsMermaid)({
567
+ const types = (0, doc_types_1.getTypesFromFolder)({
568
568
  files: [path_1.default.resolve('./src/util/range.ts')],
569
- typeName: 'SourceRange'
570
569
  });
571
570
  const exampleCode = 'x + 1\nx * 2';
572
571
  return `