@eagleoutice/flowr 2.9.13 → 2.10.1

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 (237) hide show
  1. package/README.md +52 -28
  2. package/abstract-interpretation/absint-visitor.d.ts +1 -1
  3. package/abstract-interpretation/absint-visitor.js +20 -20
  4. package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +2 -2
  5. package/benchmark/slicer.d.ts +1 -1
  6. package/benchmark/slicer.js +7 -5
  7. package/benchmark/stats/stats.d.ts +2 -2
  8. package/cli/repl/commands/repl-dataflow.js +5 -5
  9. package/cli/repl/parser/slice-query-parser.d.ts +3 -3
  10. package/cli/repl/parser/slice-query-parser.js +2 -2
  11. package/cli/repl/server/connection.js +2 -2
  12. package/cli/repl/server/messages/message-slice.d.ts +1 -1
  13. package/cli/repl/server/messages/message-slice.js +2 -2
  14. package/config.d.ts +12 -8
  15. package/config.js +5 -3
  16. package/control-flow/extract-cfg.js +2 -2
  17. package/control-flow/semantic-cfg-guided-visitor.d.ts +1 -1
  18. package/control-flow/semantic-cfg-guided-visitor.js +43 -43
  19. package/control-flow/useless-loop.d.ts +1 -1
  20. package/control-flow/useless-loop.js +3 -3
  21. package/core/print/dataflow-printer.d.ts +0 -14
  22. package/core/print/dataflow-printer.js +0 -21
  23. package/core/steps/all/core/20-dataflow.d.ts +3 -3
  24. package/core/steps/all/core/20-dataflow.js +3 -2
  25. package/core/steps/all/static-slicing/00-slice.d.ts +2 -5
  26. package/core/steps/all/static-slicing/00-slice.js +6 -8
  27. package/core/steps/pipeline/default-pipelines.d.ts +89 -89
  28. package/dataflow/environments/built-in-proc-name.d.ts +83 -0
  29. package/dataflow/environments/built-in-proc-name.js +88 -0
  30. package/dataflow/environments/built-in.d.ts +1 -83
  31. package/dataflow/environments/built-in.js +37 -120
  32. package/dataflow/environments/default-builtin-config.d.ts +1 -1
  33. package/dataflow/environments/default-builtin-config.js +75 -75
  34. package/dataflow/environments/identifier.d.ts +5 -0
  35. package/dataflow/environments/identifier.js +18 -0
  36. package/dataflow/eval/resolve/resolve.js +2 -2
  37. package/dataflow/fn/exceptions-of-function.d.ts +1 -1
  38. package/dataflow/fn/exceptions-of-function.js +2 -2
  39. package/dataflow/graph/call-graph.d.ts +46 -19
  40. package/dataflow/graph/call-graph.js +95 -114
  41. package/dataflow/graph/dataflowgraph-builder.d.ts +1 -1
  42. package/dataflow/graph/dataflowgraph-builder.js +2 -2
  43. package/dataflow/graph/df-helper.d.ts +133 -0
  44. package/dataflow/graph/df-helper.js +138 -0
  45. package/dataflow/graph/diff-dataflow-graph.d.ts +5 -10
  46. package/dataflow/graph/diff-dataflow-graph.js +3 -28
  47. package/dataflow/graph/edge.d.ts +1 -0
  48. package/dataflow/graph/edge.js +1 -0
  49. package/dataflow/graph/graph-helper.d.ts +60 -0
  50. package/dataflow/graph/graph-helper.js +128 -0
  51. package/dataflow/graph/graph.d.ts +19 -3
  52. package/dataflow/graph/graph.js +32 -5
  53. package/dataflow/graph/vertex.d.ts +3 -1
  54. package/dataflow/info.d.ts +14 -4
  55. package/dataflow/info.js +28 -16
  56. package/dataflow/internal/linker.d.ts +14 -10
  57. package/dataflow/internal/linker.js +29 -32
  58. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -5
  59. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +5 -4
  60. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +8 -7
  61. package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +1 -1
  62. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +3 -3
  63. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +2 -2
  64. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +3 -3
  65. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +6 -6
  66. package/dataflow/internal/process/functions/call/built-in/built-in-get.js +2 -2
  67. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +3 -3
  68. package/dataflow/internal/process/functions/call/built-in/built-in-library.js +2 -2
  69. package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
  70. package/dataflow/internal/process/functions/call/built-in/built-in-local.d.ts +1 -1
  71. package/dataflow/internal/process/functions/call/built-in/built-in-local.js +5 -5
  72. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +2 -2
  73. package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +2 -2
  74. package/dataflow/internal/process/functions/call/built-in/built-in-recall.js +2 -2
  75. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.js +5 -5
  76. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +2 -2
  77. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +1 -1
  78. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +5 -4
  79. package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +2 -2
  80. package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-dispatch.js +3 -3
  81. package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.js +3 -3
  82. package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.d.ts +1 -1
  83. package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.js +7 -7
  84. package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +1 -1
  85. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +3 -3
  86. package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.js +3 -3
  87. package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.js +2 -2
  88. package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.js +6 -9
  89. package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
  90. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +2 -2
  91. package/dataflow/internal/process/functions/call/common.js +2 -1
  92. package/dataflow/internal/process/functions/call/known-call-handling.js +2 -2
  93. package/dataflow/internal/process/functions/call/named-call-handling.d.ts +1 -1
  94. package/dataflow/internal/process/functions/call/named-call-handling.js +1 -1
  95. package/dataflow/internal/process/functions/call/unnamed-call-handling.js +2 -2
  96. package/dataflow/internal/process/functions/process-parameter.js +1 -1
  97. package/dataflow/internal/process/process-uninteresting-leaf.d.ts +1 -1
  98. package/dataflow/internal/process/process-uninteresting-leaf.js +1 -1
  99. package/dataflow/origin/dfg-get-origin.d.ts +1 -1
  100. package/dataflow/origin/dfg-get-symbol-refs.js +6 -6
  101. package/documentation/doc-readme.js +2 -1
  102. package/documentation/doc-util/doc-dfg.d.ts +3 -0
  103. package/documentation/doc-util/doc-dfg.js +5 -7
  104. package/documentation/doc-util/doc-normalized-ast.d.ts +0 -6
  105. package/documentation/doc-util/doc-normalized-ast.js +0 -23
  106. package/documentation/doc-util/doc-structure.js +3 -3
  107. package/documentation/doc-util/doc-types.js +3 -3
  108. package/documentation/wiki-core.js +5 -4
  109. package/documentation/wiki-dataflow-graph.js +14 -12
  110. package/documentation/wiki-interface.js +3 -3
  111. package/documentation/wiki-linter.js +6 -0
  112. package/documentation/wiki-normalized-ast.js +5 -4
  113. package/documentation/wiki-query.js +28 -3
  114. package/linter/linter-rules.d.ts +49 -1
  115. package/linter/linter-rules.js +5 -1
  116. package/linter/rules/problematic-eval.d.ts +44 -0
  117. package/linter/rules/problematic-eval.js +83 -0
  118. package/linter/rules/seeded-randomness.js +2 -2
  119. package/linter/rules/stop-with-call-arg.d.ts +35 -0
  120. package/linter/rules/stop-with-call-arg.js +72 -0
  121. package/linter/rules/useless-loop.d.ts +1 -1
  122. package/package.json +7 -7
  123. package/project/cache/flowr-analyzer-cache.d.ts +1 -1
  124. package/project/cache/flowr-analyzer-cache.js +1 -1
  125. package/project/flowr-analyzer-builder.d.ts +3 -0
  126. package/project/flowr-analyzer.d.ts +1 -1
  127. package/queries/catalog/call-context-query/identify-link-to-nested-call-relation.js +2 -2
  128. package/queries/catalog/call-graph-query/call-graph-query-format.d.ts +1 -1
  129. package/queries/catalog/call-graph-query/call-graph-query-format.js +2 -2
  130. package/queries/catalog/cluster-query/cluster-query-format.js +2 -2
  131. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +2 -2
  132. package/queries/catalog/dataflow-query/dataflow-query-format.js +2 -2
  133. package/queries/catalog/df-shape-query/df-shape-query-executor.js +1 -2
  134. package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +3 -3
  135. package/queries/catalog/does-call-query/does-call-query-executor.js +2 -2
  136. package/queries/catalog/does-call-query/does-call-query-format.d.ts +2 -2
  137. package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -2
  138. package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +3 -3
  139. package/queries/catalog/input-sources-query/input-sources-query-executor.d.ts +6 -0
  140. package/queries/catalog/input-sources-query/input-sources-query-executor.js +66 -0
  141. package/queries/catalog/input-sources-query/input-sources-query-format.d.ts +36 -0
  142. package/queries/catalog/input-sources-query/input-sources-query-format.js +63 -0
  143. package/queries/catalog/input-sources-query/simple-input-classifier.d.ts +90 -0
  144. package/queries/catalog/input-sources-query/simple-input-classifier.js +308 -0
  145. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +2 -2
  146. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +1 -1
  147. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +2 -2
  148. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -3
  149. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +2 -2
  150. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +2 -2
  151. package/queries/catalog/location-map-query/location-map-query-executor.js +2 -2
  152. package/queries/catalog/location-map-query/location-map-query-format.d.ts +2 -2
  153. package/queries/catalog/origin-query/origin-query-executor.d.ts +2 -2
  154. package/queries/catalog/origin-query/origin-query-executor.js +3 -3
  155. package/queries/catalog/origin-query/origin-query-format.d.ts +3 -3
  156. package/queries/catalog/provenance-query/provenance-query-executor.d.ts +6 -0
  157. package/queries/catalog/provenance-query/provenance-query-executor.js +34 -0
  158. package/queries/catalog/provenance-query/provenance-query-format.d.ts +35 -0
  159. package/queries/catalog/provenance-query/provenance-query-format.js +62 -0
  160. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +2 -2
  161. package/queries/catalog/search-query/search-query-format.js +1 -1
  162. package/queries/catalog/static-slice-query/static-slice-query-executor.js +4 -2
  163. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +2 -2
  164. package/queries/catalog/static-slice-query/static-slice-query-format.js +3 -3
  165. package/queries/query.d.ts +17 -1
  166. package/queries/query.js +4 -0
  167. package/r-bridge/lang-4.x/ast/model/model.d.ts +9 -0
  168. package/r-bridge/lang-4.x/ast/model/model.js +10 -1
  169. package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +16 -1
  170. package/r-bridge/lang-4.x/ast/model/nodes/r-access.js +2 -0
  171. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +16 -1
  172. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +2 -0
  173. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +16 -1
  174. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.js +2 -0
  175. package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +15 -0
  176. package/r-bridge/lang-4.x/ast/model/nodes/r-break.js +2 -0
  177. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +15 -0
  178. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +2 -0
  179. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +16 -1
  180. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.js +2 -0
  181. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +16 -1
  182. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.js +2 -0
  183. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +16 -1
  184. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.js +2 -0
  185. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +29 -1
  186. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +29 -0
  187. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +16 -1
  188. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.js +2 -0
  189. package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +16 -1
  190. package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.js +2 -0
  191. package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +16 -1
  192. package/r-bridge/lang-4.x/ast/model/nodes/r-logical.js +2 -0
  193. package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +16 -1
  194. package/r-bridge/lang-4.x/ast/model/nodes/r-next.js +2 -0
  195. package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +16 -1
  196. package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +2 -0
  197. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +16 -1
  198. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.js +2 -0
  199. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +16 -1
  200. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +2 -0
  201. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +16 -1
  202. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.js +2 -0
  203. package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +16 -1
  204. package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +2 -0
  205. package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +16 -1
  206. package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.js +2 -0
  207. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +16 -1
  208. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.js +2 -0
  209. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +16 -1
  210. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.js +2 -0
  211. package/search/flowr-search-filters.d.ts +1 -1
  212. package/search/flowr-search-printer.js +3 -3
  213. package/search/search-executor/search-enrichers.js +2 -2
  214. package/search/search-executor/search-generators.js +1 -1
  215. package/slicing/criterion/parse.d.ts +43 -18
  216. package/slicing/criterion/parse.js +68 -63
  217. package/slicing/static/slicer-types.d.ts +2 -3
  218. package/slicing/static/static-slicer.d.ts +3 -4
  219. package/slicing/static/static-slicer.js +32 -12
  220. package/util/collections/arrays.d.ts +4 -0
  221. package/util/collections/arrays.js +7 -0
  222. package/util/diff.d.ts +2 -2
  223. package/util/mermaid/ast.js +4 -4
  224. package/util/mermaid/cfg.js +5 -5
  225. package/util/mermaid/dfg.d.ts +33 -18
  226. package/util/mermaid/dfg.js +47 -31
  227. package/util/mermaid/mermaid.d.ts +57 -12
  228. package/util/mermaid/mermaid.js +74 -67
  229. package/util/range.d.ts +8 -0
  230. package/util/range.js +13 -1
  231. package/util/slice-direction.d.ts +7 -0
  232. package/util/slice-direction.js +12 -0
  233. package/util/version.js +1 -1
  234. package/dataflow/graph/invert-dfg.d.ts +0 -6
  235. package/dataflow/graph/invert-dfg.js +0 -20
  236. package/dataflow/graph/resolve-graph.d.ts +0 -8
  237. package/dataflow/graph/resolve-graph.js +0 -59
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PROBLEMATIC_EVAL = void 0;
4
+ const linter_format_1 = require("../linter-format");
5
+ const flowr_search_builder_1 = require("../../search/flowr-search-builder");
6
+ const range_1 = require("../../util/range");
7
+ const linter_tags_1 = require("../linter-tags");
8
+ const simple_input_classifier_1 = require("../../queries/catalog/input-sources-query/simple-input-classifier");
9
+ const query_1 = require("../../queries/query");
10
+ const parse_1 = require("../../slicing/criterion/parse");
11
+ /**
12
+ * Format a list of input sources either as a single-line string (inline) or a block.
13
+ * - inline: returns a semicolon-separated single-line summary
14
+ * - block: returns an array of lines (to be joined with newlines by the caller)
15
+ */
16
+ function formatInputSources(inputs, inline = true) {
17
+ if (!inputs || inputs.length === 0) {
18
+ return inline ? '' : [];
19
+ }
20
+ if (inline) {
21
+ return inputs.map(s => `${s.id} (type: ${Array.isArray(s.type) ? '[' + s.type.join(',') + ']' : s.type}, trace: ${s.trace}${s.cds ? ', cds: [' + s.cds.join(',') + ']' : ''})`).join('; ');
22
+ }
23
+ return inputs.map(s => `- ${s.id}: type=${Array.isArray(s.type) ? '[' + s.type.join(',') + ']' : s.type}, trace=${s.trace}${s.cds ? ', cds=[' + s.cds.join(',') + ']' : ''}`);
24
+ }
25
+ exports.PROBLEMATIC_EVAL = {
26
+ /* create a search that finds calls that look like eval-like functions */
27
+ createSearch: config => flowr_search_builder_1.Q.fromQuery({
28
+ type: 'call-context',
29
+ callName: config.considerAsEval,
30
+ callNameExact: false
31
+ }),
32
+ processSearchResult: async (elements, _config, data) => {
33
+ const results = [];
34
+ for (const element of elements.getElements()) {
35
+ const nid = element.node.info.id;
36
+ // run an input-sources query for this eval-like call
37
+ const criterion = parse_1.SlicingCriterion.fromId(nid);
38
+ const q = { type: 'input-sources', criterion };
39
+ const all = await (0, query_1.executeQueries)({ analyzer: data.analyzer }, [q]);
40
+ const inputSourcesResult = all['input-sources'];
41
+ const sources = inputSourcesResult?.results?.[criterion] ?? [];
42
+ // if any input is not a constant or derived constant, flag it
43
+ const problematic = sources.some(s => Array.isArray(s.type)
44
+ ? s.type.some(t => t !== simple_input_classifier_1.InputType.Constant && t !== simple_input_classifier_1.InputType.DerivedConstant)
45
+ : (s.type !== simple_input_classifier_1.InputType.Constant && s.type !== simple_input_classifier_1.InputType.DerivedConstant));
46
+ if (problematic) {
47
+ results.push({
48
+ involvedId: nid,
49
+ certainty: sources.some(s => Array.isArray(s.type) ? s.type.includes(simple_input_classifier_1.InputType.Unknown) : s.type === simple_input_classifier_1.InputType.Unknown) ? linter_format_1.LintingResultCertainty.Uncertain : linter_format_1.LintingResultCertainty.Certain,
50
+ loc: range_1.SourceLocation.fromNode(element.node) ?? range_1.SourceLocation.invalid(),
51
+ sources
52
+ });
53
+ }
54
+ }
55
+ return {
56
+ results,
57
+ '.meta': {}
58
+ };
59
+ },
60
+ /* helper to format input sources for pretty printing */
61
+ prettyPrint: {
62
+ [linter_format_1.LintingPrettyPrintContext.Query]: result => {
63
+ const inputs = result.sources ?? [];
64
+ const srcStr = formatInputSources(inputs, true);
65
+ return `Use of eval-like function at ${range_1.SourceLocation.format(result.loc)}${srcStr ? `; inputs: ${srcStr}` : ''}`;
66
+ },
67
+ [linter_format_1.LintingPrettyPrintContext.Full]: result => {
68
+ const inputs = result.sources ?? [];
69
+ const srcLines = formatInputSources(inputs, false);
70
+ return `Use of eval-like function at ${range_1.SourceLocation.format(result.loc)} is potentially problematic${srcLines.length ? '\nInputs:\n' + srcLines.join('\n') : ''}`;
71
+ }
72
+ },
73
+ info: {
74
+ name: 'Problematic eval',
75
+ description: 'Detects uses of eval-like functions whose inputs are not statically constant. Prints the computed input-sources for the eval and flags usages that depend on non-constant/trusted inputs.',
76
+ tags: [linter_tags_1.LintingRuleTag.Security, linter_tags_1.LintingRuleTag.Smell, linter_tags_1.LintingRuleTag.Readability, linter_tags_1.LintingRuleTag.Performance],
77
+ certainty: linter_format_1.LintingRuleCertainty.BestEffort,
78
+ defaultConfig: {
79
+ considerAsEval: '^eval$'
80
+ }
81
+ }
82
+ };
83
+ //# sourceMappingURL=problematic-eval.js.map
@@ -19,7 +19,7 @@ const vertex_1 = require("../../dataflow/graph/vertex");
19
19
  const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
20
20
  const r_value_1 = require("../../dataflow/eval/values/r-value");
21
21
  const info_1 = require("../../dataflow/info");
22
- const built_in_1 = require("../../dataflow/environments/built-in");
22
+ const built_in_proc_name_1 = require("../../dataflow/environments/built-in-proc-name");
23
23
  exports.SEEDED_RANDOMNESS = {
24
24
  createSearch: (config) => flowr_search_builder_1.Q.all().filter(vertex_1.VertexType.FunctionCall)
25
25
  .with(search_enrichers_1.Enrichment.CallTargets, { onlyBuiltin: true })
@@ -140,7 +140,7 @@ exports.SEEDED_RANDOMNESS = {
140
140
  }
141
141
  };
142
142
  function getDefaultAssignments() {
143
- return default_builtin_config_1.DefaultBuiltinConfig.filter(b => b.type === 'function' && (b.processor === built_in_1.BuiltInProcName.Assignment || b.processor === built_in_1.BuiltInProcName.AssignmentLike));
143
+ return default_builtin_config_1.DefaultBuiltinConfig.filter(b => b.type === 'function' && (b.processor === built_in_proc_name_1.BuiltInProcName.Assignment || b.processor === built_in_proc_name_1.BuiltInProcName.AssignmentLike));
144
144
  }
145
145
  function isConstantArgument(graph, call, argIndex, ctx) {
146
146
  const args = call.args.filter(arg => arg !== r_function_call_1.EmptyArgument && !arg.name).map(graph_1.FunctionArgument.getReference);
@@ -0,0 +1,35 @@
1
+ import { type LintingResult, LintingRuleCertainty } from '../linter-format';
2
+ import { SourceLocation } from '../../util/range';
3
+ import type { MergeableRecord } from '../../util/objects';
4
+ import { LintingRuleTag } from '../linter-tags';
5
+ import type { Writable } from 'ts-essentials';
6
+ export interface StopWithCallResult extends LintingResult {
7
+ readonly loc: SourceLocation;
8
+ }
9
+ export type StopWithCallConfig = MergeableRecord;
10
+ export interface StopWithCallMetadata extends MergeableRecord {
11
+ consideredNodes: number;
12
+ }
13
+ export declare const STOP_WITH_CALL_ARG: {
14
+ readonly createSearch: () => import("../../search/flowr-search-builder").FlowrSearchBuilder<"get", ["filter"], import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, Promise<import("../../search/flowr-search").FlowrSearchElements<import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, [] | import("../../search/flowr-search").FlowrSearchElement<import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>>>;
15
+ readonly processSearchResult: (elements: import("../../search/flowr-search").FlowrSearchElements<import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../../search/flowr-search").FlowrSearchElement<import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>, _config: MergeableRecord, { dataflow, analyzer }: {
16
+ normalize: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
17
+ dataflow: import("../../dataflow/info").DataflowInformation;
18
+ cfg: import("../../control-flow/control-flow-graph").ControlFlowInformation;
19
+ analyzer: import("../../project/flowr-analyzer").ReadonlyFlowrAnalysisProvider;
20
+ }) => {
21
+ results: Writable<StopWithCallResult>[];
22
+ '.meta': StopWithCallMetadata;
23
+ };
24
+ readonly prettyPrint: {
25
+ readonly query: (result: StopWithCallResult) => string;
26
+ readonly full: (result: StopWithCallResult) => string;
27
+ };
28
+ readonly info: {
29
+ readonly name: "Stop without call.=False argument";
30
+ readonly tags: readonly [LintingRuleTag.Smell];
31
+ readonly certainty: LintingRuleCertainty.BestEffort;
32
+ readonly description: "Checks whether stop calls without call. argument set to FALSE are used.";
33
+ readonly defaultConfig: {};
34
+ };
35
+ };
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.STOP_WITH_CALL_ARG = void 0;
4
+ const linter_format_1 = require("../linter-format");
5
+ const range_1 = require("../../util/range");
6
+ const flowr_search_builder_1 = require("../../search/flowr-search-builder");
7
+ const linter_tags_1 = require("../linter-tags");
8
+ const assert_1 = require("../../util/assert");
9
+ const vertex_1 = require("../../dataflow/graph/vertex");
10
+ const alias_tracking_1 = require("../../dataflow/eval/resolve/alias-tracking");
11
+ const dfg_get_origin_1 = require("../../dataflow/origin/dfg-get-origin");
12
+ const linker_1 = require("../../dataflow/internal/linker");
13
+ const general_1 = require("../../dataflow/eval/values/general");
14
+ exports.STOP_WITH_CALL_ARG = {
15
+ createSearch: () => flowr_search_builder_1.Q.var('stop').filter(vertex_1.VertexType.FunctionCall),
16
+ processSearchResult: (elements, _config, { dataflow, analyzer }) => {
17
+ const meta = {
18
+ consideredNodes: 0
19
+ };
20
+ return {
21
+ results: elements.getElements()
22
+ .filter(element => {
23
+ //only built-in functions
24
+ const origins = (0, dfg_get_origin_1.getOriginInDfg)(dataflow.graph, element.node.info.id);
25
+ if ((0, assert_1.isNotUndefined)(origins)) {
26
+ const builtIn = origins.every(e => e.type === 3 /* OriginType.BuiltInFunctionOrigin */);
27
+ if (!builtIn) {
28
+ return false;
29
+ }
30
+ }
31
+ const fCall = dataflow.graph.getVertex(element.node.info.id);
32
+ //filter out function calls with argument "call." set to false
33
+ const stopParamMap = {
34
+ '...': '...',
35
+ 'call.': 'call.',
36
+ 'domain': 'domain'
37
+ };
38
+ const mapping = (0, linker_1.pMatch)(fCall.args, stopParamMap);
39
+ const mappedToStop = mapping.get('call.') ?? [];
40
+ for (const argId of mappedToStop) {
41
+ const res = (0, alias_tracking_1.resolveIdToValue)(argId, { graph: dataflow.graph, environment: fCall.environment, ctx: analyzer.inspectContext() });
42
+ const values = (0, general_1.valueSetGuard)(res);
43
+ if (values?.type === 'set' && values.elements.length !== 0) {
44
+ if (values.elements[0].type === 'logical') {
45
+ return values.elements[0].value;
46
+ }
47
+ }
48
+ }
49
+ return true;
50
+ })
51
+ .map(element => ({
52
+ certainty: linter_format_1.LintingResultCertainty.Uncertain,
53
+ involvedId: element.node.info.id,
54
+ loc: range_1.SourceLocation.fromNode(element.node)
55
+ }))
56
+ .filter(element => (0, assert_1.isNotUndefined)(element.loc)),
57
+ '.meta': meta
58
+ };
59
+ },
60
+ prettyPrint: {
61
+ [linter_format_1.LintingPrettyPrintContext.Query]: result => `Code at ${range_1.SourceLocation.format(result.loc)}`,
62
+ [linter_format_1.LintingPrettyPrintContext.Full]: result => `Code at ${range_1.SourceLocation.format(result.loc)} does call stop without setting call. to FALSE`,
63
+ },
64
+ info: {
65
+ name: 'Stop without call.=False argument',
66
+ tags: [linter_tags_1.LintingRuleTag.Smell],
67
+ certainty: linter_format_1.LintingRuleCertainty.BestEffort,
68
+ description: 'Checks whether stop calls without call. argument set to FALSE are used.',
69
+ defaultConfig: {}
70
+ }
71
+ };
72
+ //# sourceMappingURL=stop-with-call-arg.js.map
@@ -1,8 +1,8 @@
1
- import type { BuiltInProcName } from '../../dataflow/environments/built-in';
2
1
  import type { MergeableRecord } from '../../util/objects';
3
2
  import { SourceLocation } from '../../util/range';
4
3
  import { type LintingResult, LintingResultCertainty, LintingRuleCertainty } from '../linter-format';
5
4
  import { LintingRuleTag } from '../linter-tags';
5
+ import type { BuiltInProcName } from '../../dataflow/environments/built-in-proc-name';
6
6
  export interface UselessLoopResult extends LintingResult {
7
7
  name: string;
8
8
  loc: SourceLocation;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eagleoutice/flowr",
3
- "version": "2.9.13",
3
+ "version": "2.10.1",
4
4
  "description": "Static Dataflow Analyzer and Program Slicer for the R Programming Language",
5
5
  "types": "dist/src/index.d.ts",
6
6
  "repository": {
@@ -165,8 +165,8 @@
165
165
  }
166
166
  },
167
167
  "devDependencies": {
168
- "@commitlint/cli": "^19.7.1",
169
- "@commitlint/config-angular": "^19.7.1",
168
+ "@commitlint/cli": "^20.5.0",
169
+ "@commitlint/config-angular": "^20.5.0",
170
170
  "@eagleoutice/eslint-config-flowr": "^1.0.36",
171
171
  "@eslint/eslintrc": "^3.3.3",
172
172
  "@eslint/js": "^9.39.2",
@@ -191,11 +191,11 @@
191
191
  "npm-run-all": "^4.1.5",
192
192
  "release-it": "^19.2.3",
193
193
  "ts-node": "^10.9.2",
194
- "typedoc": "^0.27.7",
195
- "typedoc-plugin-missing-exports": "^3.1.0",
196
- "typedoc-theme-hierarchy": "^5.0.4",
194
+ "typedoc": "^0.28.17",
195
+ "typedoc-plugin-missing-exports": "^4.1.2",
196
+ "typedoc-theme-hierarchy": "^6.0.0",
197
197
  "typedoc-umlclass": "^0.10.2",
198
- "typescript": "^5.7.3",
198
+ "typescript": "^5.9.3",
199
199
  "vitest": "^3.2.4"
200
200
  },
201
201
  "dependencies": {
@@ -9,7 +9,7 @@ import type { CfgSimplificationPassName } from '../../control-flow/cfg-simplific
9
9
  import type { ControlFlowInformation } from '../../control-flow/control-flow-graph';
10
10
  import type { CfgKind } from '../cfg-kind';
11
11
  import type { FlowrAnalyzerContext } from '../context/flowr-analyzer-context';
12
- import type { CallGraph } from '../../dataflow/graph/call-graph';
12
+ import { CallGraph } from '../../dataflow/graph/call-graph';
13
13
  interface FlowrAnalyzerCacheOptions<Parser extends KnownParser> {
14
14
  parser: Parser;
15
15
  context: FlowrAnalyzerContext;
@@ -141,7 +141,7 @@ class FlowrAnalyzerCache extends flowr_cache_1.FlowrCache {
141
141
  */
142
142
  async callGraph(force) {
143
143
  if (!this.callGraphCache || force) {
144
- this.callGraphCache = (0, call_graph_1.computeCallGraph)((await this.dataflow(force)).graph);
144
+ this.callGraphCache = call_graph_1.CallGraph.compute((await this.dataflow(force)).graph);
145
145
  }
146
146
  return this.callGraphCache;
147
147
  }
@@ -56,6 +56,9 @@ export declare class FlowrAnalyzerBuilder {
56
56
  * @param config - The new configuration.
57
57
  */
58
58
  setConfig(config: FlowrConfig): this;
59
+ /**
60
+ * Set a specific value in the configuration used by the resulting analyzer.
61
+ */
59
62
  configure<K extends AutocompletablePaths<FlowrConfig>>(key: K, value: PathValue<FlowrConfig, K>): this;
60
63
  /**
61
64
  * Set the parser instance used by the analyzer.
@@ -15,8 +15,8 @@ import type { RAnalysisRequest } from './context/flowr-analyzer-files-context';
15
15
  import type { RParseRequest, RParseRequestFromFile } from '../r-bridge/retriever';
16
16
  import { fileProtocol } from '../r-bridge/retriever';
17
17
  import type { FlowrFileProvider } from './context/flowr-file';
18
- import type { CallGraph } from '../dataflow/graph/call-graph';
19
18
  import type { Tree } from 'web-tree-sitter';
19
+ import type { CallGraph } from '../dataflow/graph/call-graph';
20
20
  /**
21
21
  * Extends the {@link ReadonlyFlowrAnalysisProvider} with methods that allow modifying the analyzer state.
22
22
  */
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.identifyLinkToNestedRelation = identifyLinkToNestedRelation;
4
- const call_graph_1 = require("../../../dataflow/graph/call-graph");
5
4
  const vertex_1 = require("../../../dataflow/graph/vertex");
6
5
  const identifier_1 = require("../../../dataflow/environments/identifier");
6
+ const call_graph_1 = require("../../../dataflow/graph/call-graph");
7
7
  /**
8
8
  * **Please refer to {@link identifyLinkToRelation}.**
9
9
  *
@@ -19,7 +19,7 @@ async function identifyLinkToNestedRelation(from, analyzer, { callName, ignoreIf
19
19
  const test = callName instanceof RegExp ? (t) => callName.test(t) : callName;
20
20
  const found = [];
21
21
  const cg = await analyzer.callGraph();
22
- const subCg = (0, call_graph_1.getSubCallGraph)(cg, new Set([from]));
22
+ const subCg = call_graph_1.CallGraph.computeSubCallGraph(cg, new Set([from]));
23
23
  for (const [, t] of subCg.vertices(true)) {
24
24
  if (!(0, vertex_1.isFunctionCallVertex)(t)) {
25
25
  continue;
@@ -2,7 +2,7 @@ import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
2
2
  import { executeCallGraphQuery } from './call-graph-query-executor';
3
3
  import Joi from 'joi';
4
4
  import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
5
- import type { CallGraph } from '../../../dataflow/graph/call-graph';
5
+ import { CallGraph } from '../../../dataflow/graph/call-graph';
6
6
  /**
7
7
  * Computes the Call Graph of the analyzed project.
8
8
  */
@@ -7,14 +7,14 @@ exports.CallGraphQueryDefinition = void 0;
7
7
  const call_graph_query_executor_1 = require("./call-graph-query-executor");
8
8
  const ansi_1 = require("../../../util/text/ansi");
9
9
  const time_1 = require("../../../util/text/time");
10
- const dfg_1 = require("../../../util/mermaid/dfg");
11
10
  const joi_1 = __importDefault(require("joi"));
11
+ const call_graph_1 = require("../../../dataflow/graph/call-graph");
12
12
  exports.CallGraphQueryDefinition = {
13
13
  executor: call_graph_query_executor_1.executeCallGraphQuery,
14
14
  asciiSummarizer: (formatter, _analyzer, queryResults, result) => {
15
15
  const out = queryResults;
16
16
  result.push(`Query: ${(0, ansi_1.bold)('call-graph', formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
17
- result.push(` ╰ [Call Graph](${(0, dfg_1.graphToMermaidUrl)(out.graph)})`);
17
+ result.push(` ╰ [Call Graph](${call_graph_1.CallGraph.visualize.mermaid.url(out.graph)})`);
18
18
  return true;
19
19
  },
20
20
  schema: joi_1.default.object({
@@ -7,8 +7,8 @@ exports.ClusterQueryDefinition = void 0;
7
7
  const ansi_1 = require("../../../util/text/ansi");
8
8
  const joi_1 = __importDefault(require("joi"));
9
9
  const cluster_query_executor_1 = require("./cluster-query-executor");
10
- const dfg_1 = require("../../../util/mermaid/dfg");
11
10
  const query_print_1 = require("../../query-print");
11
+ const df_helper_1 = require("../../../dataflow/graph/df-helper");
12
12
  exports.ClusterQueryDefinition = {
13
13
  executor: cluster_query_executor_1.executeDataflowClusterQuery,
14
14
  asciiSummarizer: async (formatter, analyzer, queryResults, result) => {
@@ -19,7 +19,7 @@ exports.ClusterQueryDefinition = {
19
19
  const unknownSideEffects = cluster.hasUnknownSideEffects ? '(has unknown side effect)' : '';
20
20
  let suffix = '';
21
21
  if (formatter === ansi_1.markdownFormatter) {
22
- suffix = `([marked](${(0, dfg_1.graphToMermaidUrl)((await analyzer.dataflow()).graph, false, new Set(cluster.members))}))`;
22
+ suffix = `([marked](${df_helper_1.Dataflow.visualize.mermaid.url((await analyzer.dataflow()).graph, false, new Set(cluster.members))}))`;
23
23
  }
24
24
  result.push(` ╰ ${unknownSideEffects} {${(0, query_print_1.summarizeIdsIfTooLong)(formatter, cluster.members)}} ${suffix}`);
25
25
  }
@@ -7,14 +7,14 @@ exports.DataflowLensQueryDefinition = void 0;
7
7
  const dataflow_lens_query_executor_1 = require("./dataflow-lens-query-executor");
8
8
  const ansi_1 = require("../../../util/text/ansi");
9
9
  const time_1 = require("../../../util/text/time");
10
- const dfg_1 = require("../../../util/mermaid/dfg");
11
10
  const joi_1 = __importDefault(require("joi"));
11
+ const df_helper_1 = require("../../../dataflow/graph/df-helper");
12
12
  exports.DataflowLensQueryDefinition = {
13
13
  executor: dataflow_lens_query_executor_1.executeDataflowLensQuery,
14
14
  asciiSummarizer: (formatter, _analyzer, queryResults, result) => {
15
15
  const out = queryResults;
16
16
  result.push(`Query: ${(0, ansi_1.bold)('dataflow-lens', formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
17
- result.push(` ╰ [Simplified Graph](${(0, dfg_1.graphToMermaidUrl)(out.simplifiedGraph, false, undefined, true)})`);
17
+ result.push(` ╰ [Simplified Graph](${df_helper_1.Dataflow.visualize.mermaid.url(out.simplifiedGraph, false, undefined, true)})`);
18
18
  return true;
19
19
  },
20
20
  schema: joi_1.default.object({
@@ -7,14 +7,14 @@ exports.DataflowQueryDefinition = void 0;
7
7
  const dataflow_query_executor_1 = require("./dataflow-query-executor");
8
8
  const ansi_1 = require("../../../util/text/ansi");
9
9
  const time_1 = require("../../../util/text/time");
10
- const dfg_1 = require("../../../util/mermaid/dfg");
11
10
  const joi_1 = __importDefault(require("joi"));
11
+ const df_helper_1 = require("../../../dataflow/graph/df-helper");
12
12
  exports.DataflowQueryDefinition = {
13
13
  executor: dataflow_query_executor_1.executeDataflowQuery,
14
14
  asciiSummarizer: (formatter, _analyzer, queryResults, result) => {
15
15
  const out = queryResults;
16
16
  result.push(`Query: ${(0, ansi_1.bold)('dataflow', formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
17
- result.push(` ╰ [Dataflow Graph](${(0, dfg_1.graphToMermaidUrl)(out.graph)})`);
17
+ result.push(` ╰ [Dataflow Graph](${df_helper_1.Dataflow.visualize.mermaid.url(out.graph)})`);
18
18
  return true;
19
19
  },
20
20
  schema: joi_1.default.object({
@@ -39,14 +39,13 @@ async function executeDfShapeQuery({ analyzer }, queries) {
39
39
  continue;
40
40
  }
41
41
  try {
42
- const nodeId = (0, parse_1.slicingCriterionToId)(query.criterion, ast.idMap);
42
+ const nodeId = parse_1.SlicingCriterion.parse(query.criterion, ast.idMap);
43
43
  const node = ast.idMap.get(nodeId);
44
44
  const value = inference.getAbstractValue(node?.info.id);
45
45
  result.set(query.criterion, value);
46
46
  }
47
47
  catch (e) {
48
48
  console.error(e instanceof Error ? e.message : e);
49
- continue;
50
49
  }
51
50
  }
52
51
  return {
@@ -3,17 +3,17 @@ import type { DataFrameDomain } from '../../../abstract-interpretation/data-fram
3
3
  import type { StateAbstractDomain } from '../../../abstract-interpretation/domains/state-abstract-domain';
4
4
  import type { ReplOutput } from '../../../cli/repl/commands/repl-main';
5
5
  import type { FlowrConfig } from '../../../config';
6
- import type { SingleSlicingCriterion } from '../../../slicing/criterion/parse';
6
+ import type { SlicingCriterion } from '../../../slicing/criterion/parse';
7
7
  import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
8
8
  import type { ParsedQueryLine } from '../../query';
9
9
  import { executeDfShapeQuery } from './df-shape-query-executor';
10
10
  /** Infer the shape of data frames using abstract interpretation. */
11
11
  export interface DfShapeQuery extends BaseQueryFormat {
12
12
  readonly type: 'df-shape';
13
- readonly criterion?: SingleSlicingCriterion;
13
+ readonly criterion?: SlicingCriterion;
14
14
  }
15
15
  export interface DfShapeQueryResult extends BaseQueryResult {
16
- domains: StateAbstractDomain<DataFrameDomain> | Map<SingleSlicingCriterion, DataFrameDomain | undefined>;
16
+ domains: StateAbstractDomain<DataFrameDomain> | Map<SlicingCriterion, DataFrameDomain | undefined>;
17
17
  }
18
18
  declare function dfShapeQueryLineParser(_output: ReplOutput, line: readonly string[], _config: FlowrConfig): ParsedQueryLine<'df-shape'>;
19
19
  export declare const DfShapeQueryDefinition: {
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.executeDoesCallQuery = executeDoesCallQuery;
4
4
  const log_1 = require("../../../util/log");
5
5
  const node_id_1 = require("../../../r-bridge/lang-4.x/ast/model/processing/node-id");
6
- const parse_1 = require("../../../slicing/criterion/parse");
7
6
  const identifier_1 = require("../../../dataflow/environments/identifier");
7
+ const parse_1 = require("../../../slicing/criterion/parse");
8
8
  /**
9
9
  * Execute does call queries on the given analyzer.
10
10
  */
@@ -19,7 +19,7 @@ async function executeDoesCallQuery({ analyzer }, queries) {
19
19
  log_1.log.warn(`Duplicate query id '${id}' in does-call queries, SKIP.`);
20
20
  continue;
21
21
  }
22
- const nodeId = (0, parse_1.tryResolveSliceCriterionToId)(query.call, idMap);
22
+ const nodeId = parse_1.SlicingCriterion.tryParse(query.call, idMap);
23
23
  if (!nodeId) {
24
24
  results[id] = false;
25
25
  continue;
@@ -3,7 +3,7 @@ import Joi from 'joi';
3
3
  import type { ParsedQueryLine } from '../../query';
4
4
  import { executeDoesCallQuery } from './does-call-query-executor';
5
5
  import { type NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
6
- import type { SingleSlicingCriterion } from '../../../slicing/criterion/parse';
6
+ import type { SlicingCriterion } from '../../../slicing/criterion/parse';
7
7
  import type { ReplOutput } from '../../../cli/repl/commands/repl-main';
8
8
  import type { FlowrConfig } from '../../../config';
9
9
  interface CallsIdConstraint {
@@ -30,7 +30,7 @@ export type CallsConstraint = CallsIdConstraint | CallsWithNameConstraint | Call
30
30
  export interface DoesCallQuery extends BaseQueryFormat {
31
31
  readonly type: 'does-call';
32
32
  readonly queryId?: string;
33
- readonly call: SingleSlicingCriterion;
33
+ readonly call: SlicingCriterion;
34
34
  readonly calls: CallsConstraint;
35
35
  }
36
36
  export interface FindAllCallsResult {
@@ -22,8 +22,8 @@ async function executeHappensBefore({ analyzer }, queries) {
22
22
  log_1.log.warn('Duplicate happens-before query', query, 'ignoring');
23
23
  }
24
24
  try {
25
- const resolvedA = (0, parse_1.slicingCriterionToId)(a, ast.idMap);
26
- const resolvedB = (0, parse_1.slicingCriterionToId)(b, ast.idMap);
25
+ const resolvedA = parse_1.SlicingCriterion.parse(a, ast.idMap);
26
+ const resolvedB = parse_1.SlicingCriterion.parse(b, ast.idMap);
27
27
  results[fingerprint] = (0, happens_before_1.happensBefore)(cfg.graph, resolvedA, resolvedB);
28
28
  }
29
29
  catch (e) {
@@ -1,12 +1,12 @@
1
1
  import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
2
2
  import Joi from 'joi';
3
3
  import { executeHappensBefore } from './happens-before-query-executor';
4
- import type { SingleSlicingCriterion } from '../../../slicing/criterion/parse';
4
+ import type { SlicingCriterion } from '../../../slicing/criterion/parse';
5
5
  import type { Ternary } from '../../../util/logic';
6
6
  export interface HappensBeforeQuery extends BaseQueryFormat {
7
7
  readonly type: 'happens-before';
8
- readonly a: SingleSlicingCriterion;
9
- readonly b: SingleSlicingCriterion;
8
+ readonly a: SlicingCriterion;
9
+ readonly b: SlicingCriterion;
10
10
  }
11
11
  export interface HappensBeforeQueryResult extends BaseQueryResult {
12
12
  readonly results: Record<string, Ternary>;
@@ -0,0 +1,6 @@
1
+ import type { BasicQueryData } from '../../base-query-format';
2
+ import type { InputSourcesQuery, InputSourcesQueryResult } from './input-sources-query-format';
3
+ /**
4
+ * Execute an input sources query
5
+ */
6
+ export declare function executeInputSourcesQuery({ analyzer }: BasicQueryData, queries: readonly InputSourcesQuery[]): Promise<InputSourcesQueryResult>;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeInputSourcesQuery = executeInputSourcesQuery;
4
+ const log_1 = require("../../../util/log");
5
+ const parse_1 = require("../../../slicing/criterion/parse");
6
+ const r_function_definition_1 = require("../../../r-bridge/lang-4.x/ast/model/nodes/r-function-definition");
7
+ const model_1 = require("../../../r-bridge/lang-4.x/ast/model/model");
8
+ const df_helper_1 = require("../../../dataflow/graph/df-helper");
9
+ const simple_input_classifier_1 = require("./simple-input-classifier");
10
+ const network_functions_1 = require("../../../linter/rules/network-functions");
11
+ const seeded_randomness_1 = require("../../../linter/rules/seeded-randomness");
12
+ const read_functions_1 = require("../dependencies-query/function-info/read-functions");
13
+ /**
14
+ * Execute an input sources query
15
+ */
16
+ async function executeInputSourcesQuery({ analyzer }, queries) {
17
+ const start = Date.now();
18
+ const results = {};
19
+ const nast = await analyzer.normalize();
20
+ const df = await analyzer.dataflow();
21
+ for (const query of queries) {
22
+ const key = query.criterion;
23
+ if (results[key]) {
24
+ log_1.log.warn(`Duplicate key for input-sources query: ${key}, skipping...`);
25
+ }
26
+ const criterionId = parse_1.SlicingCriterion.tryParse(key, nast.idMap) ?? key;
27
+ const provenanceNode = nast.idMap.get(criterionId);
28
+ const fdef = r_function_definition_1.RFunctionDefinition.rootFunctionDefinition(provenanceNode, nast.idMap);
29
+ const provenance = df_helper_1.Dataflow.provenanceGraph(criterionId, df.graph, fdef ? model_1.RNode.collectAllIds(fdef) : undefined);
30
+ results[key] = (0, simple_input_classifier_1.classifyInput)(criterionId, provenance, {
31
+ networkFns: query.config?.networkFns ?? network_functions_1.NETWORK_FUNCTIONS.info.defaultConfig.fns,
32
+ randomFns: query.config?.randomFns ?? seeded_randomness_1.SEEDED_RANDOMNESS.info.defaultConfig.randomnessConsumers,
33
+ pureFns: query.config?.pureFns ?? ['paste', 'paste0', 'parse', '+', '-', '*',
34
+ '/', '^', '%%', '%/%', '&', '|', '!', '&&', '||',
35
+ '<', '>', '<=', '>=', '==', '!=', ':',
36
+ 'abs', 'sign', 'sqrt', 'exp', 'log', 'log10', 'log2',
37
+ 'sin', 'cos', 'tan', 'asin', 'acos', 'atan',
38
+ 'length', 'nchar', 'dim', 'nrow', 'ncol',
39
+ 'c', 'list', 'data.frame',
40
+ 'ifelse', 'switch', 'factor', 'as.factor',
41
+ 'round', 'floor', 'ceiling', 'trunc',
42
+ 'substr', 'substring', 'strsplit',
43
+ 'min', 'max', 'range', 'sum', 'prod', 'mean', 'median', 'var', 'sd',
44
+ 'head', 'tail', 'seq', 'rep',
45
+ 'apply', 'lapply', 'sapply', 'vapply', 'tapply',
46
+ 'matrix', 'array', 'substitute', 'quote', 'bquote', 'enquote', 'enexpr', 'enexprs', 'enquo', 'enquos',
47
+ 'expression', 'call', 'as.call', 'as.expression',
48
+ 'rownames', 'colnames',
49
+ 'list.files', 'tolower', 'toupper', 'printf',
50
+ '<-', '->', '=', '<<-', '->>', 'assign', 'get',
51
+ '[', '[[', '$', 'length<-', 'dim<-', 'names<-', 'colnames<-', 'rownames<-',
52
+ 'as.character', 'as.numeric', 'as.logical', 'as.list', 'as.data.frame', 'as.matrix', 'as.array',
53
+ 'identity', 'invisible', 'return', 'force', 'missing',
54
+ 'print', 'cat', 'message', 'warning', 'stop'
55
+ ],
56
+ readFileFns: query.config?.readFileFns ?? read_functions_1.ReadFunctions.map(f => f.name)
57
+ });
58
+ }
59
+ return {
60
+ '.meta': {
61
+ timing: Date.now() - start
62
+ },
63
+ results
64
+ };
65
+ }
66
+ //# sourceMappingURL=input-sources-query-executor.js.map
@@ -0,0 +1,36 @@
1
+ import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
2
+ import type { SlicingCriterion } from '../../../slicing/criterion/parse';
3
+ import type { ParsedQueryLine } from '../../query';
4
+ import Joi from 'joi';
5
+ import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
6
+ import type { InputClassifierConfig, InputSources } from './simple-input-classifier';
7
+ import type { ReplOutput } from '../../../cli/repl/commands/repl-main';
8
+ import type { FlowrConfig } from '../../../config';
9
+ import { executeInputSourcesQuery } from './input-sources-query-executor';
10
+ export type InputSourcesQueryConfig = InputClassifierConfig;
11
+ /**
12
+ * Calculates provenance for all inputs and their transformations
13
+ * based on the `provenance` of a given function.
14
+ */
15
+ export interface InputSourcesQuery extends BaseQueryFormat {
16
+ readonly type: 'input-sources';
17
+ /**
18
+ * This takes a criterion (or a numerical id works too)
19
+ * {@link SlicingCriterion.fromId}
20
+ */
21
+ readonly criterion: SlicingCriterion;
22
+ readonly config?: InputSourcesQueryConfig;
23
+ }
24
+ export interface InputSourcesQueryResult extends BaseQueryResult {
25
+ /** For each query key, a list of classified input sources (each with id and all traces) */
26
+ results: Record<string, InputSources>;
27
+ }
28
+ declare function inputSourcesQueryLineParser(output: ReplOutput, line: readonly string[], _config: FlowrConfig): ParsedQueryLine<'input-sources'>;
29
+ export declare const InputSourcesDefinition: {
30
+ readonly executor: typeof executeInputSourcesQuery;
31
+ readonly asciiSummarizer: (formatter: import("../../../util/text/ansi").OutputFormatter, analyzer: import("../../../project/flowr-analyzer").ReadonlyFlowrAnalysisProvider<import("../../../r-bridge/parser").KnownParser>, queryResults: BaseQueryResult, result: string[]) => Promise<boolean>;
32
+ readonly fromLine: typeof inputSourcesQueryLineParser;
33
+ readonly schema: Joi.ObjectSchema<any>;
34
+ readonly flattenInvolvedNodes: (queryResults: BaseQueryResult) => NodeId[];
35
+ };
36
+ export {};