@eagleoutice/flowr 2.2.14 → 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 (245) 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 +3 -3
  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 +5 -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 +27 -43
  39. package/control-flow/basic-cfg-guided-visitor.d.ts +3 -3
  40. package/control-flow/cfg-dead-code.d.ts +4 -0
  41. package/control-flow/cfg-dead-code.js +124 -0
  42. package/control-flow/cfg-simplification.d.ts +19 -6
  43. package/control-flow/cfg-simplification.js +23 -19
  44. package/control-flow/control-flow-graph.d.ts +3 -1
  45. package/control-flow/control-flow-graph.js +5 -0
  46. package/control-flow/dfg-cfg-guided-visitor.d.ts +9 -7
  47. package/control-flow/dfg-cfg-guided-visitor.js +16 -5
  48. package/control-flow/extract-cfg.d.ts +4 -2
  49. package/control-flow/extract-cfg.js +63 -59
  50. package/control-flow/semantic-cfg-guided-visitor.d.ts +36 -9
  51. package/control-flow/semantic-cfg-guided-visitor.js +73 -20
  52. package/control-flow/simple-visitor.d.ts +4 -0
  53. package/control-flow/simple-visitor.js +14 -0
  54. package/control-flow/syntax-cfg-guided-visitor.d.ts +2 -2
  55. package/core/pipeline-executor.d.ts +4 -1
  56. package/core/pipeline-executor.js +6 -5
  57. package/core/steps/all/core/10-normalize.d.ts +2 -0
  58. package/core/steps/all/core/10-normalize.js +1 -1
  59. package/core/steps/all/core/11-normalize-tree-sitter.d.ts +2 -1
  60. package/core/steps/all/core/11-normalize-tree-sitter.js +2 -2
  61. package/core/steps/all/core/20-dataflow.d.ts +2 -1
  62. package/core/steps/all/core/20-dataflow.js +2 -2
  63. package/core/steps/all/static-slicing/00-slice.d.ts +2 -1
  64. package/core/steps/all/static-slicing/00-slice.js +2 -2
  65. package/core/steps/pipeline/default-pipelines.d.ts +32 -31
  66. package/core/steps/pipeline/default-pipelines.js +8 -8
  67. package/core/steps/pipeline-step.d.ts +2 -1
  68. package/dataflow/environments/built-in-config.d.ts +4 -3
  69. package/dataflow/environments/built-in.d.ts +16 -1
  70. package/dataflow/environments/built-in.js +11 -5
  71. package/dataflow/environments/default-builtin-config.js +5 -3
  72. package/dataflow/environments/define.d.ts +2 -1
  73. package/dataflow/environments/define.js +4 -5
  74. package/dataflow/environments/remove.d.ts +6 -0
  75. package/dataflow/environments/remove.js +29 -0
  76. package/dataflow/environments/resolve-by-name.d.ts +0 -36
  77. package/dataflow/environments/resolve-by-name.js +0 -240
  78. package/dataflow/eval/resolve/alias-tracking.d.ts +92 -0
  79. package/dataflow/eval/resolve/alias-tracking.js +352 -0
  80. package/dataflow/eval/resolve/resolve-argument.d.ts +8 -0
  81. package/dataflow/eval/resolve/resolve-argument.js +118 -0
  82. package/dataflow/eval/resolve/resolve.d.ts +37 -0
  83. package/dataflow/eval/resolve/resolve.js +95 -0
  84. package/dataflow/eval/values/general.d.ts +27 -0
  85. package/dataflow/eval/values/general.js +73 -0
  86. package/dataflow/eval/values/intervals/interval-constants.d.ts +4 -0
  87. package/dataflow/eval/values/intervals/interval-constants.js +27 -0
  88. package/dataflow/eval/values/logical/logical-constants.d.ts +7 -0
  89. package/dataflow/eval/values/logical/logical-constants.js +31 -0
  90. package/dataflow/eval/values/r-value.d.ts +58 -0
  91. package/dataflow/eval/values/r-value.js +90 -0
  92. package/dataflow/eval/values/scalar/scalar-consatnts.d.ts +15 -0
  93. package/dataflow/eval/values/scalar/scalar-consatnts.js +35 -0
  94. package/dataflow/eval/values/sets/set-constants.d.ts +7 -0
  95. package/dataflow/eval/values/sets/set-constants.js +34 -0
  96. package/dataflow/eval/values/string/string-constants.d.ts +8 -0
  97. package/dataflow/eval/values/string/string-constants.js +45 -0
  98. package/dataflow/eval/values/vectors/vector-constants.d.ts +14 -0
  99. package/dataflow/eval/values/vectors/vector-constants.js +35 -0
  100. package/dataflow/extractor.d.ts +2 -1
  101. package/dataflow/extractor.js +2 -1
  102. package/dataflow/graph/unknown-replacement.d.ts +11 -0
  103. package/dataflow/graph/unknown-replacement.js +12 -0
  104. package/dataflow/graph/unknown-side-effect.d.ts +7 -0
  105. package/dataflow/graph/unknown-side-effect.js +13 -0
  106. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -6
  107. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +8 -5
  108. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +4 -2
  109. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +15 -13
  110. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +20 -18
  111. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +7 -2
  112. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -3
  113. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +5 -4
  114. package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
  115. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +11 -5
  116. package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +5 -3
  117. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +26 -29
  118. package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
  119. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +23 -0
  120. package/dataflow/internal/process/functions/call/common.js +1 -1
  121. package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
  122. package/dataflow/internal/process/functions/process-parameter.js +1 -1
  123. package/dataflow/origin/dfg-get-symbol-refs.d.ts +21 -0
  124. package/dataflow/origin/dfg-get-symbol-refs.js +50 -0
  125. package/dataflow/processor.d.ts +5 -0
  126. package/documentation/doc-util/doc-cfg.js +4 -3
  127. package/documentation/doc-util/doc-code.d.ts +1 -1
  128. package/documentation/doc-util/doc-dfg.js +3 -2
  129. package/documentation/doc-util/doc-functions.d.ts +24 -0
  130. package/documentation/doc-util/doc-functions.js +65 -0
  131. package/documentation/doc-util/doc-normalized-ast.js +3 -2
  132. package/documentation/doc-util/doc-print.d.ts +5 -0
  133. package/documentation/doc-util/doc-print.js +36 -0
  134. package/documentation/doc-util/doc-query.d.ts +6 -3
  135. package/documentation/doc-util/doc-query.js +6 -3
  136. package/documentation/doc-util/doc-repl.js +2 -1
  137. package/documentation/doc-util/doc-search.js +3 -2
  138. package/documentation/doc-util/doc-types.d.ts +28 -6
  139. package/documentation/doc-util/doc-types.js +89 -45
  140. package/documentation/print-cfg-wiki.js +10 -11
  141. package/documentation/print-core-wiki.js +5 -5
  142. package/documentation/print-dataflow-graph-wiki.js +14 -13
  143. package/documentation/print-engines-wiki.js +2 -3
  144. package/documentation/print-faq-wiki.js +8 -2
  145. package/documentation/print-interface-wiki.js +1 -2
  146. package/documentation/print-linter-issue.d.ts +1 -0
  147. package/documentation/print-linter-issue.js +71 -0
  148. package/documentation/print-linter-wiki.js +219 -34
  149. package/documentation/print-linting-and-testing-wiki.js +2 -4
  150. package/documentation/print-normalized-ast-wiki.js +3 -3
  151. package/documentation/print-query-wiki.js +81 -2
  152. package/documentation/print-readme.js +24 -1
  153. package/documentation/print-search-wiki.js +1 -2
  154. package/linter/linter-executor.d.ts +3 -1
  155. package/linter/linter-executor.js +3 -2
  156. package/linter/linter-format.d.ts +67 -7
  157. package/linter/linter-format.js +12 -1
  158. package/linter/linter-rules.d.ts +155 -16
  159. package/linter/linter-rules.js +12 -4
  160. package/linter/linter-tags.d.ts +80 -0
  161. package/linter/linter-tags.js +85 -0
  162. package/linter/rules/absolute-path.d.ts +71 -0
  163. package/linter/rules/absolute-path.js +177 -0
  164. package/linter/rules/deprecated-functions.d.ts +43 -0
  165. package/linter/rules/deprecated-functions.js +58 -0
  166. package/linter/rules/{2-file-path-validity.d.ts → file-path-validity.d.ts} +16 -6
  167. package/linter/rules/{2-file-path-validity.js → file-path-validity.js} +21 -13
  168. package/linter/rules/naming-convention.d.ts +71 -0
  169. package/linter/rules/naming-convention.js +164 -0
  170. package/linter/rules/seeded-randomness.d.ts +65 -0
  171. package/linter/rules/seeded-randomness.js +122 -0
  172. package/linter/rules/unused-definition.d.ts +41 -0
  173. package/linter/rules/unused-definition.js +105 -0
  174. package/package.json +4 -1
  175. package/queries/base-query-format.d.ts +2 -0
  176. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  177. package/queries/catalog/call-context-query/call-context-query-executor.js +2 -2
  178. package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
  179. package/queries/catalog/config-query/config-query-executor.d.ts +1 -1
  180. package/queries/catalog/config-query/config-query-executor.js +2 -3
  181. package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +3 -0
  182. package/queries/catalog/control-flow-query/control-flow-query-executor.js +20 -0
  183. package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +81 -0
  184. package/queries/catalog/control-flow-query/control-flow-query-format.js +34 -0
  185. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
  186. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
  187. package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -115
  188. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -1
  189. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
  190. package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
  191. package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -1
  192. package/queries/catalog/linter-query/linter-query-executor.d.ts +1 -1
  193. package/queries/catalog/linter-query/linter-query-executor.js +2 -2
  194. package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
  195. package/queries/catalog/linter-query/linter-query-format.js +17 -12
  196. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
  197. package/queries/catalog/origin-query/origin-query-format.d.ts +1 -1
  198. package/queries/catalog/project-query/project-query-format.d.ts +1 -1
  199. package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +1 -1
  200. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +4 -4
  201. package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +3 -2
  202. package/queries/catalog/resolve-value-query/resolve-value-query-format.js +2 -22
  203. package/queries/catalog/search-query/search-query-executor.d.ts +1 -1
  204. package/queries/catalog/search-query/search-query-executor.js +2 -2
  205. package/queries/catalog/search-query/search-query-format.d.ts +1 -1
  206. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  207. package/queries/catalog/static-slice-query/static-slice-query-executor.js +2 -2
  208. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -1
  209. package/queries/query.d.ts +75 -15
  210. package/queries/query.js +2 -0
  211. package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -1
  212. package/r-bridge/lang-4.x/ast/parser/json/parser.js +4 -2
  213. package/r-bridge/lang-4.x/convert-values.js +2 -1
  214. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +3 -1
  215. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
  216. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.d.ts +1 -1
  217. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +18 -9
  218. package/r-bridge/shell.d.ts +3 -2
  219. package/r-bridge/shell.js +4 -5
  220. package/search/flowr-search-builder.d.ts +6 -2
  221. package/search/flowr-search-builder.js +7 -0
  222. package/search/flowr-search-filters.d.ts +32 -8
  223. package/search/flowr-search-filters.js +42 -15
  224. package/search/flowr-search.d.ts +4 -0
  225. package/search/search-executor/search-enrichers.d.ts +7 -3
  226. package/search/search-executor/search-enrichers.js +32 -20
  227. package/search/search-executor/search-generators.js +1 -1
  228. package/search/search-executor/search-transformer.d.ts +2 -0
  229. package/search/search-executor/search-transformer.js +10 -1
  230. package/slicing/criterion/parse.d.ts +8 -0
  231. package/slicing/criterion/parse.js +20 -0
  232. package/slicing/static/static-slicer.d.ts +1 -1
  233. package/slicing/static/static-slicer.js +2 -3
  234. package/statistics/statistics.d.ts +3 -1
  235. package/statistics/statistics.js +5 -4
  236. package/util/containers.d.ts +12 -9
  237. package/util/containers.js +12 -9
  238. package/util/objects.d.ts +5 -4
  239. package/util/range.d.ts +5 -1
  240. package/util/range.js +11 -3
  241. package/util/text/strings.d.ts +6 -0
  242. package/util/text/strings.js +35 -0
  243. package/util/version.js +1 -1
  244. package/linter/rules/1-deprecated-functions.d.ts +0 -34
  245. package/linter/rules/1-deprecated-functions.js +0 -54
@@ -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>
@@ -34,6 +34,8 @@ const flowr_search_builder_1 = require("../search/flowr-search-builder");
34
34
  const vertex_1 = require("../dataflow/graph/vertex");
35
35
  const doc_types_1 = require("./doc-util/doc-types");
36
36
  const path_1 = __importDefault(require("path"));
37
+ const control_flow_query_executor_1 = require("../queries/catalog/control-flow-query/control-flow-query-executor");
38
+ const doc_cfg_1 = require("./doc-util/doc-cfg");
37
39
  (0, doc_query_1.registerQueryDocumentation)('call-context', {
38
40
  name: 'Call-Context Query',
39
41
  type: 'active',
@@ -477,6 +479,84 @@ Here, \`resolveValue\` tells the dependency query to resolve the value of this a
477
479
  `;
478
480
  }
479
481
  });
482
+ (0, doc_query_1.registerQueryDocumentation)('linter', {
483
+ name: 'Linter Query',
484
+ type: 'active',
485
+ shortDescription: 'Lints a given R script for common issues.',
486
+ functionName: dependencies_query_executor_1.executeDependenciesQuery.name,
487
+ functionFile: '../queries/catalog/linter-query/linter-query-executor.ts',
488
+ buildExplanation: async (shell) => {
489
+ const exampleCode = 'read.csv("i_do_not_exist.csv")';
490
+ return `
491
+ This query lints a given R script for common issues, such as missing files, unused variables, and more.
492
+
493
+ In other words, if you have a script simply reading: \`${exampleCode}\`, the following query returns all smells detected:
494
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
495
+ type: 'linter'
496
+ }], { showCode: false, collapseQuery: true })}
497
+
498
+ You can also configure which rules to apply and what settings to use for these rules.
499
+ We welcome any feedback and suggestions for new rules on this (consider opening a [new issue](${doc_issue_1.NewIssueUrl})).
500
+ `;
501
+ }
502
+ });
503
+ (0, doc_query_1.registerQueryDocumentation)('control-flow', {
504
+ name: 'Control-Flow Query',
505
+ type: 'active',
506
+ shortDescription: 'Provides the control-flow of the program.',
507
+ functionName: control_flow_query_executor_1.executeControlFlowQuery.name,
508
+ functionFile: '../queries/catalog/control-flow-query/control-flow-query-executor.ts',
509
+ buildExplanation: async (shell) => {
510
+ const exampleCode = 'if(TRUE) 1 else 2';
511
+ return `
512
+ This control-flow query provides you access to the control flow graph.
513
+
514
+ In other words, if you have a script simply reading: \`${exampleCode}\`, the following query returns the CFG:
515
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
516
+ type: 'control-flow'
517
+ }], { showCode: false, collapseQuery: true, collapseResult: true })}
518
+
519
+ You can also overwrite the simplification passes to tune the perspective. for example, if you want to have basic blocks:
520
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
521
+ type: 'control-flow',
522
+ config: {
523
+ simplificationPasses: ['unique-cf-sets', 'to-basic-blocks']
524
+ }
525
+ }], { showCode: false, collapseResult: true })}
526
+
527
+ this produces:
528
+
529
+ ${await (0, doc_cfg_1.printCfgCode)(shell, exampleCode, { showCode: false, prefix: 'flowchart RL\n', simplifications: ['to-basic-blocks'] })}
530
+
531
+
532
+ If, on the other hand, you want to prune dead code edges:
533
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
534
+ type: 'control-flow',
535
+ config: {
536
+ simplificationPasses: ['unique-cf-sets', 'analyze-dead-code']
537
+ }
538
+ }], { showCode: false, collapseResult: true })}
539
+
540
+ this produces:
541
+
542
+ ${await (0, doc_cfg_1.printCfgCode)(shell, exampleCode, { showCode: false, prefix: 'flowchart RL\n', simplifications: ['analyze-dead-code'] })}
543
+
544
+
545
+ Or, completely remove dead code:
546
+ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
547
+ type: 'control-flow',
548
+ config: {
549
+ simplificationPasses: ['unique-cf-sets', 'analyze-dead-code', 'remove-dead-code']
550
+ }
551
+ }], { showCode: false, collapseResult: true })}
552
+
553
+ this produces:
554
+
555
+ ${await (0, doc_cfg_1.printCfgCode)(shell, exampleCode, { showCode: false, prefix: 'flowchart RL\n', simplifications: ['analyze-dead-code', 'remove-dead-code'] })}
556
+
557
+ `;
558
+ }
559
+ });
480
560
  (0, doc_query_1.registerQueryDocumentation)('location-map', {
481
561
  name: 'Location Map Query',
482
562
  type: 'active',
@@ -484,9 +564,8 @@ Here, \`resolveValue\` tells the dependency query to resolve the value of this a
484
564
  functionName: location_map_query_executor_1.executeLocationMapQuery.name,
485
565
  functionFile: '../queries/catalog/location-map-query/location-map-query-executor.ts',
486
566
  buildExplanation: async (shell) => {
487
- const types = (0, doc_types_1.getTypesFromFolderAsMermaid)({
567
+ const types = (0, doc_types_1.getTypesFromFolder)({
488
568
  files: [path_1.default.resolve('./src/util/range.ts')],
489
- typeName: 'SourceRange'
490
569
  });
491
570
  const exampleCode = 'x + 1\nx * 2';
492
571
  return `
@@ -14,6 +14,7 @@ const doc_repl_1 = require("./doc-util/doc-repl");
14
14
  const doc_auto_gen_1 = require("./doc-util/doc-auto-gen");
15
15
  const doc_general_1 = require("./doc-util/doc-general");
16
16
  const doc_dfg_1 = require("./doc-util/doc-dfg");
17
+ const doc_query_1 = require("./doc-util/doc-query");
17
18
  async function getText(shell) {
18
19
  const dateOptions = { year: 'numeric', month: 'short', day: 'numeric' };
19
20
  return `
@@ -31,6 +32,28 @@ available for [VSCode](${doc_files_1.FlowrVsCode}), [Positron](${doc_files_1.Flo
31
32
  and [Docker](${doc_files_1.FlowrDockerRef}).
32
33
  It offers a wide variety of features, for example:
33
34
 
35
+ * 🐞 **code linting**\\
36
+ Analyze your R scripts for common issues and potential bugs (see the [wiki page](${doc_files_1.FlowrGithubBaseRef}/flowr/wiki/Linter) for more information on the currently supported linters).
37
+
38
+ ${(0, doc_general_1.prefixLines)((0, doc_structure_1.details)('Example: Linting code with flowR', `To lint your code, you can use the [REPL](${doc_files_1.FlowrWikiBaseRef}/Interface#using-the-repl) or the [Visual Studio Code extension](${doc_files_1.FlowrVsCode}) (see [vscode-flowr#283](https://github.com/flowr-analysis/vscode-flowr/pull/283)).
39
+
40
+ ${await (async () => {
41
+ const code = 'read.csv("/root/x.txt")';
42
+ const res = await (0, doc_query_1.showQuery)(shell, code, [{ type: 'linter' }], { showCode: false, collapseQuery: true, collapseResult: false });
43
+ return await (0, doc_repl_1.documentReplSession)(shell, [{
44
+ command: `:query @linter ${JSON.stringify(code)}`,
45
+ description: `
46
+ The linter will analyze the code and return any issues found.
47
+ Formatted more nicely, this returns:
48
+
49
+ ${res}
50
+ `
51
+ }]);
52
+ })()}
53
+
54
+ `), ' ')}
55
+
56
+
34
57
  * 🍕 **program slicing**\\
35
58
  Given a point of interest like the visualization of a plot, _flowR_ reduces the program to just the parts which are relevant
36
59
  for the computation of the point of interest.
@@ -117,7 +140,7 @@ You can enter ${(0, doc_cli_option_1.getReplCommand)('help')} to gain more infor
117
140
 
118
141
  <summary>Example REPL session</summary>
119
142
 
120
- ![Example of a simple REPL session](wiki/gif/repl-demo.gif)
143
+ ![Example of a simple REPL session](wiki/gif/repl-demo-opt.gif)
121
144
 
122
145
  </details>
123
146
 
@@ -15,9 +15,8 @@ const path_1 = __importDefault(require("path"));
15
15
  const flowr_search_executor_1 = require("../search/flowr-search-executor");
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/search/'),
20
- typeName: 'FlowrSearchGenerator',
21
20
  inlineTypes: doc_types_1.mermaidHide
22
21
  });
23
22
  return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'search API', rVersion: rversion })}
@@ -3,7 +3,9 @@ import type { NormalizedAst } from '../r-bridge/lang-4.x/ast/model/processing/de
3
3
  import type { DataflowInformation } from '../dataflow/info';
4
4
  import type { LintingResults } from './linter-format';
5
5
  import type { DeepPartial } from 'ts-essentials';
6
+ import type { FlowrConfigOptions } from '../config';
6
7
  export declare function executeLintingRule<Name extends LintingRuleNames>(ruleName: Name, input: {
7
8
  normalize: NormalizedAst;
8
9
  dataflow: DataflowInformation;
9
- }, config?: DeepPartial<LintingRuleConfig<Name>>): LintingResults<Name>;
10
+ config: FlowrConfigOptions;
11
+ }, lintingRuleConfig?: DeepPartial<LintingRuleConfig<Name>>): LintingResults<Name>;
@@ -4,9 +4,10 @@ exports.executeLintingRule = executeLintingRule;
4
4
  const linter_rules_1 = require("./linter-rules");
5
5
  const flowr_search_executor_1 = require("../search/flowr-search-executor");
6
6
  const flowr_search_1 = require("../search/flowr-search");
7
- function executeLintingRule(ruleName, input, config) {
7
+ const objects_1 = require("../util/objects");
8
+ function executeLintingRule(ruleName, input, lintingRuleConfig) {
8
9
  const rule = linter_rules_1.LintingRules[ruleName];
9
- const fullConfig = { ...rule.defaultConfig, ...config };
10
+ const fullConfig = (0, objects_1.deepMergeObject)(rule.info.defaultConfig, lintingRuleConfig);
10
11
  const ruleSearch = rule.createSearch(fullConfig, input);
11
12
  const searchStart = Date.now();
12
13
  const searchResult = (0, flowr_search_executor_1.runSearch)(ruleSearch, input);