@eagleoutice/flowr 2.7.6 → 2.8.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 (208) hide show
  1. package/README.md +67 -64
  2. package/cli/wiki.js +1 -1
  3. package/control-flow/extract-cfg.js +3 -3
  4. package/control-flow/useless-loop.d.ts +1 -1
  5. package/control-flow/useless-loop.js +2 -2
  6. package/dataflow/cluster.js +3 -3
  7. package/dataflow/environments/built-in-config.d.ts +8 -4
  8. package/dataflow/environments/built-in.d.ts +27 -14
  9. package/dataflow/environments/built-in.js +27 -12
  10. package/dataflow/environments/default-builtin-config.d.ts +615 -3
  11. package/dataflow/environments/default-builtin-config.js +50 -15
  12. package/dataflow/environments/environment.js +3 -2
  13. package/dataflow/environments/identifier.d.ts +5 -1
  14. package/dataflow/environments/reference-to-maybe.d.ts +2 -2
  15. package/dataflow/environments/reference-to-maybe.js +23 -14
  16. package/dataflow/environments/resolve-by-name.d.ts +6 -2
  17. package/dataflow/environments/resolve-by-name.js +5 -1
  18. package/dataflow/environments/scoping.js +1 -3
  19. package/dataflow/eval/resolve/alias-tracking.js +5 -1
  20. package/dataflow/extractor.js +3 -3
  21. package/dataflow/fn/exceptions-of-function.d.ts +13 -0
  22. package/dataflow/fn/exceptions-of-function.js +47 -0
  23. package/dataflow/fn/higher-order-function.d.ts +1 -1
  24. package/dataflow/fn/higher-order-function.js +3 -3
  25. package/dataflow/fn/recursive-function.d.ts +6 -0
  26. package/dataflow/fn/recursive-function.js +32 -0
  27. package/dataflow/graph/call-graph.d.ts +10 -0
  28. package/dataflow/graph/call-graph.js +212 -0
  29. package/dataflow/graph/dataflowgraph-builder.d.ts +7 -2
  30. package/dataflow/graph/dataflowgraph-builder.js +14 -9
  31. package/dataflow/graph/diff-dataflow-graph.js +96 -2
  32. package/dataflow/graph/graph.d.ts +10 -7
  33. package/dataflow/graph/graph.js +7 -8
  34. package/dataflow/graph/vertex.d.ts +6 -3
  35. package/dataflow/hooks.d.ts +30 -0
  36. package/dataflow/hooks.js +38 -0
  37. package/dataflow/info.d.ts +28 -5
  38. package/dataflow/info.js +66 -31
  39. package/dataflow/internal/linker.d.ts +13 -3
  40. package/dataflow/internal/linker.js +163 -73
  41. package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +4 -0
  42. package/dataflow/internal/process/functions/call/argument/unpack-argument.js +7 -0
  43. package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +1 -1
  44. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +19 -3
  45. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +14 -0
  46. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +30 -0
  47. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +2 -1
  48. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +24 -17
  49. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -1
  50. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +5 -1
  51. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +59 -21
  52. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +4 -3
  53. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.d.ts +34 -0
  54. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.js +92 -0
  55. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +1 -0
  56. package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.d.ts +21 -0
  57. package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.js +129 -0
  58. package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.d.ts +16 -0
  59. package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.js +127 -0
  60. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +5 -3
  61. package/dataflow/internal/process/functions/call/common.d.ts +13 -1
  62. package/dataflow/internal/process/functions/call/common.js +33 -2
  63. package/dataflow/internal/process/functions/call/known-call-handling.d.ts +13 -1
  64. package/dataflow/internal/process/functions/call/known-call-handling.js +29 -3
  65. package/dataflow/internal/process/functions/call/named-call-handling.js +2 -1
  66. package/dataflow/internal/process/functions/call/unnamed-call-handling.js +6 -4
  67. package/dataflow/internal/process/functions/process-argument.js +7 -6
  68. package/dataflow/internal/process/functions/process-parameter.js +2 -1
  69. package/dataflow/internal/process/process-named-call.d.ts +2 -2
  70. package/dataflow/internal/process/process-symbol.js +3 -2
  71. package/dataflow/internal/process/process-value.d.ts +3 -2
  72. package/dataflow/internal/process/process-value.js +8 -6
  73. package/dataflow/origin/dfg-get-origin.js +2 -1
  74. package/dataflow/origin/dfg-get-symbol-refs.js +1 -1
  75. package/documentation/doc-readme.d.ts +1 -1
  76. package/documentation/doc-readme.js +6 -6
  77. package/documentation/doc-util/doc-code.js +1 -1
  78. package/documentation/doc-util/doc-dfg.d.ts +1 -0
  79. package/documentation/doc-util/doc-dfg.js +7 -4
  80. package/documentation/doc-util/doc-query.d.ts +1 -0
  81. package/documentation/doc-util/doc-query.js +1 -1
  82. package/documentation/doc-util/doc-repl.d.ts +2 -1
  83. package/documentation/doc-util/doc-repl.js +11 -3
  84. package/documentation/wiki-analyzer.js +2 -0
  85. package/documentation/wiki-dataflow-graph.js +59 -16
  86. package/documentation/wiki-interface.js +33 -5
  87. package/documentation/wiki-mk/doc-context.d.ts +2 -1
  88. package/documentation/wiki-mk/doc-context.js +2 -2
  89. package/documentation/wiki-mk/doc-maker.js +4 -3
  90. package/documentation/wiki-normalized-ast.js +6 -0
  91. package/documentation/wiki-query.js +109 -1
  92. package/linter/linter-rules.d.ts +1 -1
  93. package/linter/rules/seeded-randomness.js +17 -12
  94. package/linter/rules/useless-loop.d.ts +1 -1
  95. package/package.json +9 -9
  96. package/project/cache/flowr-analyzer-cache.d.ts +11 -0
  97. package/project/cache/flowr-analyzer-cache.js +19 -0
  98. package/project/context/flowr-analyzer-dependencies-context.d.ts +6 -1
  99. package/project/context/flowr-analyzer-dependencies-context.js +6 -0
  100. package/project/context/flowr-analyzer-files-context.d.ts +5 -2
  101. package/project/context/flowr-analyzer-files-context.js +24 -17
  102. package/project/context/flowr-file.d.ts +9 -4
  103. package/project/context/flowr-file.js +20 -6
  104. package/project/flowr-analyzer.d.ts +11 -0
  105. package/project/flowr-analyzer.js +6 -0
  106. package/project/plugins/file-plugins/files/flowr-description-file.d.ts +8 -0
  107. package/project/plugins/file-plugins/files/flowr-description-file.js +36 -3
  108. package/project/plugins/file-plugins/files/flowr-jupyter-file.js +1 -1
  109. package/project/plugins/file-plugins/files/flowr-namespace-file.js +1 -1
  110. package/project/plugins/file-plugins/files/flowr-news-file.js +1 -1
  111. package/project/plugins/file-plugins/files/flowr-rmarkdown-file.js +1 -1
  112. package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.js +1 -1
  113. package/project/plugins/file-plugins/flowr-analyzer-file-plugin.d.ts +4 -1
  114. package/project/plugins/file-plugins/flowr-analyzer-file-plugin.js +3 -0
  115. package/project/plugins/file-plugins/{flowr-analyzer-namespace-file-plugin.d.ts → flowr-analyzer-namespace-files-plugin.d.ts} +1 -1
  116. package/project/plugins/file-plugins/{flowr-analyzer-namespace-file-plugin.js → flowr-analyzer-namespace-files-plugin.js} +4 -4
  117. package/project/plugins/file-plugins/flowr-analyzer-test-file-plugin.d.ts +26 -0
  118. package/project/plugins/file-plugins/flowr-analyzer-test-file-plugin.js +39 -0
  119. package/project/plugins/file-plugins/flowr-analyzer-vignette-file-plugin.d.ts +26 -0
  120. package/project/plugins/file-plugins/flowr-analyzer-vignette-file-plugin.js +39 -0
  121. package/project/plugins/flowr-analyzer-plugin-defaults.js +6 -2
  122. package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-description-file-plugin.js +3 -13
  123. package/project/plugins/package-version-plugins/package.d.ts +1 -1
  124. package/project/plugins/package-version-plugins/package.js +3 -3
  125. package/project/plugins/plugin-registry.d.ts +4 -2
  126. package/project/plugins/plugin-registry.js +6 -2
  127. package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.d.ts +11 -0
  128. package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.js +5 -2
  129. package/queries/catalog/call-context-query/call-context-query-format.d.ts +4 -12
  130. package/queries/catalog/call-graph-query/call-graph-query-executor.d.ts +6 -0
  131. package/queries/catalog/call-graph-query/call-graph-query-executor.js +21 -0
  132. package/queries/catalog/call-graph-query/call-graph-query-format.d.ts +21 -0
  133. package/queries/catalog/call-graph-query/call-graph-query-format.js +32 -0
  134. package/queries/catalog/dataflow-query/dataflow-query-executor.js +4 -3
  135. package/queries/catalog/dependencies-query/dependencies-query-executor.js +29 -3
  136. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -0
  137. package/queries/catalog/dependencies-query/function-info/function-info.d.ts +8 -1
  138. package/queries/catalog/dependencies-query/function-info/write-functions.js +13 -0
  139. package/queries/catalog/does-call-query/does-call-query-executor.d.ts +6 -0
  140. package/queries/catalog/does-call-query/does-call-query-executor.js +100 -0
  141. package/queries/catalog/does-call-query/does-call-query-format.d.ts +51 -0
  142. package/queries/catalog/does-call-query/does-call-query-format.js +102 -0
  143. package/queries/catalog/files-query/files-query-executor.js +4 -4
  144. package/queries/catalog/files-query/files-query-format.d.ts +2 -1
  145. package/queries/catalog/files-query/files-query-format.js +18 -2
  146. package/queries/catalog/id-map-query/id-map-query-executor.js +4 -3
  147. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +18 -0
  148. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +56 -0
  149. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +34 -0
  150. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.js +54 -0
  151. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -3
  152. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +6 -0
  153. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.js +12 -0
  154. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-executor.d.ts +6 -0
  155. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-executor.js +23 -0
  156. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +28 -0
  157. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.js +44 -0
  158. package/queries/catalog/linter-query/linter-query-format.js +4 -1
  159. package/queries/catalog/location-map-query/location-map-query-executor.js +1 -1
  160. package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.js +4 -3
  161. package/queries/catalog/project-query/project-query-executor.js +9 -3
  162. package/queries/catalog/project-query/project-query-format.d.ts +6 -1
  163. package/queries/catalog/project-query/project-query-format.js +35 -9
  164. package/queries/query.d.ts +34 -2
  165. package/queries/query.js +9 -0
  166. package/r-bridge/data/data.d.ts +10 -5
  167. package/r-bridge/data/data.js +11 -5
  168. package/r-bridge/lang-4.x/ast/model/model.d.ts +7 -7
  169. package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +2 -2
  170. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +2 -2
  171. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +2 -2
  172. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +5 -2
  173. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +8 -0
  174. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +2 -2
  175. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +2 -2
  176. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +3 -3
  177. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +2 -2
  178. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +2 -2
  179. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +2 -2
  180. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +2 -2
  181. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +2 -2
  182. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +2 -2
  183. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +2 -2
  184. package/r-bridge/lang-4.x/ast/parser/main/internal/other/normalize-comment.js +0 -1
  185. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +0 -2
  186. package/r-bridge/roxygen2/roxygen-ast.d.ts +218 -0
  187. package/r-bridge/roxygen2/roxygen-ast.js +82 -0
  188. package/r-bridge/roxygen2/roxygen-parse.d.ts +24 -0
  189. package/r-bridge/roxygen2/roxygen-parse.js +214 -0
  190. package/reconstruct/auto-select/magic-comments.js +4 -4
  191. package/slicing/static/slice-call.js +3 -4
  192. package/slicing/static/static-slicer.js +2 -2
  193. package/statistics/features/supported/defined-functions/defined-functions.js +1 -1
  194. package/util/collections/defaultmap.d.ts +3 -3
  195. package/util/mermaid/dfg.js +5 -5
  196. package/util/objects.js +1 -1
  197. package/util/r-author.d.ts +5 -0
  198. package/util/r-author.js +110 -0
  199. package/util/r-license.d.ts +10 -1
  200. package/util/r-license.js +27 -6
  201. package/util/r-version.d.ts +19 -0
  202. package/util/r-version.js +106 -0
  203. package/util/range.d.ts +6 -0
  204. package/util/range.js +7 -0
  205. package/util/simple-df/dfg-ascii.js +2 -2
  206. package/util/text/args.d.ts +9 -0
  207. package/util/text/args.js +65 -0
  208. package/util/version.js +1 -1
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.firstAndRest = void 0;
4
+ exports.parseRoxygenCommentsOfNode = parseRoxygenCommentsOfNode;
5
+ exports.parseRoxygenComment = parseRoxygenComment;
6
+ const roxygen_ast_1 = require("./roxygen-ast");
7
+ const r_comment_1 = require("../lang-4.x/ast/model/nodes/r-comment");
8
+ const assert_1 = require("../../util/assert");
9
+ const args_1 = require("../../util/text/args");
10
+ const range_1 = require("../../util/range");
11
+ function prepareCommentContext(commentText) {
12
+ const contents = [];
13
+ for (const line of commentText) {
14
+ const trimmed = line.trim();
15
+ if (trimmed.length === 0) {
16
+ continue;
17
+ }
18
+ else if (!trimmed.startsWith('#')) {
19
+ // we are done with the roxygen comment
20
+ break;
21
+ }
22
+ contents.push((trimmed.startsWith('#\'') ? trimmed.slice(2) : trimmed.slice(1)).trimEnd());
23
+ }
24
+ return contents;
25
+ }
26
+ /**
27
+ * Parses the roxygen comments attached to a node into a RoxygenBlock AST node.
28
+ * Will return `undefined` if there are no valid roxygen comments attached to the node.
29
+ * @param node - The node to parse the roxygen comments for
30
+ * @param idMap - An optional id map to traverse up the AST to find comments attached to parent nodes
31
+ */
32
+ function parseRoxygenCommentsOfNode(node, idMap) {
33
+ let comments;
34
+ let cur = node;
35
+ do {
36
+ comments = cur?.info.additionalTokens
37
+ ?.filter(r_comment_1.isRComment).filter(r => (0, assert_1.isNotUndefined)(r.lexeme));
38
+ cur = cur?.info.parent ? idMap?.get(cur.info.parent) : undefined;
39
+ } while ((comments === undefined || comments.length === 0) && cur !== undefined);
40
+ if (comments === undefined || comments.length === 0) {
41
+ return undefined;
42
+ }
43
+ const commentContent = comments.map(c => c.lexeme);
44
+ return {
45
+ type: 'roxygen-block',
46
+ tags: parseRoxygenComment(commentContent),
47
+ attachedTo: cur?.info.id,
48
+ requestNode: node.info.id,
49
+ range: [
50
+ ...(0, range_1.mergeRanges)(...comments.map(c => c.location)),
51
+ comments.find(c => c.info.file)?.info.file
52
+ ]
53
+ };
54
+ }
55
+ /**
56
+ * Parses a roxygen comment into a RoxygenBlock AST node.
57
+ * Will return an empty array if the comment has no valid roxygen comment.
58
+ * @see {@link parseRoxygenCommentsOfNode} - to parse comments attached to a node
59
+ */
60
+ function parseRoxygenComment(commentText) {
61
+ const contents = prepareCommentContext(commentText);
62
+ const state = {
63
+ lines: contents,
64
+ tags: [],
65
+ idx: 0
66
+ };
67
+ val(state, [roxygen_ast_1.KnownRoxygenTags.Text]);
68
+ return state.tags;
69
+ }
70
+ function atEnd(state) {
71
+ return state.idx >= state.lines.length;
72
+ }
73
+ function atTag(state) {
74
+ if (atEnd(state)) {
75
+ return undefined;
76
+ }
77
+ const line = state.lines[state.idx].trim();
78
+ if (!line.startsWith('@')) {
79
+ return undefined;
80
+ }
81
+ const firstSpace = line.indexOf(' ');
82
+ return firstSpace === -1 ? [line.slice(1), undefined] : [line.slice(1, firstSpace), line.slice(firstSpace + 1).trim()];
83
+ }
84
+ function advanceLine(state) {
85
+ return state.lines[state.idx++];
86
+ }
87
+ function collectUntilNextTag(state) {
88
+ const collected = [];
89
+ while (!atEnd(state)) {
90
+ const mayTag = atTag(state);
91
+ if (mayTag) {
92
+ advanceLine(state);
93
+ return [collected, mayTag];
94
+ }
95
+ collected.push(advanceLine(state));
96
+ }
97
+ return [collected, undefined];
98
+ }
99
+ function addTag(state, tag) {
100
+ state.tags.push(tag);
101
+ }
102
+ function val(state, tagName, lineToVal = l => l.join('\n').trim()) {
103
+ const [lines, nextTag] = collectUntilNextTag(state);
104
+ if (tagName[1]) {
105
+ lines.unshift(tagName[1]);
106
+ }
107
+ if (tagName[0] !== roxygen_ast_1.KnownRoxygenTags.Text || lines.length > 0) {
108
+ const n = tagName[0];
109
+ if ((0, roxygen_ast_1.isKnownRoxygenText)(n)) {
110
+ const val = lineToVal(lines);
111
+ addTag(state, (val !== undefined ? {
112
+ type: n,
113
+ value: val
114
+ } : { type: n }));
115
+ }
116
+ else {
117
+ addTag(state, {
118
+ type: roxygen_ast_1.KnownRoxygenTags.Unknown,
119
+ value: {
120
+ tag: n,
121
+ content: lines.join(' ')
122
+ }
123
+ });
124
+ }
125
+ }
126
+ parseRoxygenTag(state, nextTag);
127
+ }
128
+ const spaceVals = (s, t) => val(s, t, l => (0, args_1.splitAtEscapeSensitive)(l.join(' ')));
129
+ const flagVal = (s, t) => val(s, t, () => undefined);
130
+ const section = (s, t) => val(s, t, l => {
131
+ return { title: l[0].trim(), content: l.slice(1).join('\n').trim() };
132
+ });
133
+ const firstAndRest = (firstName, secondName) => (s, t) => val(s, t, l => {
134
+ const vals = (0, args_1.splitAtEscapeSensitive)(l.join('\n'));
135
+ return { [firstName]: vals[0], [secondName]: vals.slice(1).join(' ').trim() };
136
+ });
137
+ exports.firstAndRest = firstAndRest;
138
+ const firstAndArrayRest = (firstName, secondName) => (s, t) => val(s, t, l => {
139
+ const vals = (0, args_1.splitAtEscapeSensitive)(l.join('\n'));
140
+ return { [firstName]: vals[0], [secondName]: vals.slice(1) };
141
+ });
142
+ const asNumber = (s, t) => val(s, t, l => {
143
+ const num = Number(l.join(' ').trim());
144
+ return Number.isNaN(num) ? undefined : num;
145
+ });
146
+ const TagMap = {
147
+ [roxygen_ast_1.KnownRoxygenTags.Aliases]: spaceVals,
148
+ [roxygen_ast_1.KnownRoxygenTags.Backref]: val,
149
+ [roxygen_ast_1.KnownRoxygenTags.Concept]: val,
150
+ [roxygen_ast_1.KnownRoxygenTags.Family]: val,
151
+ [roxygen_ast_1.KnownRoxygenTags.Keywords]: spaceVals,
152
+ [roxygen_ast_1.KnownRoxygenTags.References]: val,
153
+ [roxygen_ast_1.KnownRoxygenTags.SeeAlso]: spaceVals,
154
+ [roxygen_ast_1.KnownRoxygenTags.EvalNamespace]: val,
155
+ [roxygen_ast_1.KnownRoxygenTags.Export]: flagVal,
156
+ [roxygen_ast_1.KnownRoxygenTags.ExportClass]: val,
157
+ [roxygen_ast_1.KnownRoxygenTags.ExportMethod]: val,
158
+ [roxygen_ast_1.KnownRoxygenTags.ExportPattern]: val,
159
+ [roxygen_ast_1.KnownRoxygenTags.ExportS3Method]: val,
160
+ [roxygen_ast_1.KnownRoxygenTags.Import]: val,
161
+ [roxygen_ast_1.KnownRoxygenTags.ImportClassesFrom]: firstAndArrayRest('package', 'classes'),
162
+ [roxygen_ast_1.KnownRoxygenTags.ImportMethodsFrom]: firstAndArrayRest('package', 'methods'),
163
+ [roxygen_ast_1.KnownRoxygenTags.ImportFrom]: firstAndArrayRest('package', 'symbols'),
164
+ [roxygen_ast_1.KnownRoxygenTags.RawNamespace]: val,
165
+ [roxygen_ast_1.KnownRoxygenTags.UseDynLib]: val,
166
+ [roxygen_ast_1.KnownRoxygenTags.Md]: flagVal,
167
+ [roxygen_ast_1.KnownRoxygenTags.NoMd]: flagVal,
168
+ [roxygen_ast_1.KnownRoxygenTags.Section]: section,
169
+ [roxygen_ast_1.KnownRoxygenTags.Field]: (0, exports.firstAndRest)('name', 'description'),
170
+ [roxygen_ast_1.KnownRoxygenTags.Format]: val,
171
+ [roxygen_ast_1.KnownRoxygenTags.Method]: (0, exports.firstAndRest)('generic', 'class'),
172
+ [roxygen_ast_1.KnownRoxygenTags.Slot]: (0, exports.firstAndRest)('name', 'description'),
173
+ [roxygen_ast_1.KnownRoxygenTags.Source]: val,
174
+ [roxygen_ast_1.KnownRoxygenTags.Description]: val,
175
+ [roxygen_ast_1.KnownRoxygenTags.Details]: val,
176
+ [roxygen_ast_1.KnownRoxygenTags.Example]: val,
177
+ [roxygen_ast_1.KnownRoxygenTags.Examples]: val,
178
+ [roxygen_ast_1.KnownRoxygenTags.ExamplesIf]: (0, exports.firstAndRest)('condition', 'content'),
179
+ [roxygen_ast_1.KnownRoxygenTags.NoRd]: flagVal,
180
+ [roxygen_ast_1.KnownRoxygenTags.Param]: (0, exports.firstAndRest)('name', 'description'),
181
+ [roxygen_ast_1.KnownRoxygenTags.RawRd]: val,
182
+ [roxygen_ast_1.KnownRoxygenTags.Return]: val,
183
+ [roxygen_ast_1.KnownRoxygenTags.Returns]: val,
184
+ [roxygen_ast_1.KnownRoxygenTags.Title]: val,
185
+ [roxygen_ast_1.KnownRoxygenTags.Usage]: val,
186
+ [roxygen_ast_1.KnownRoxygenTags.DescribeIn]: (0, exports.firstAndRest)('dest', 'description'),
187
+ [roxygen_ast_1.KnownRoxygenTags.Eval]: val,
188
+ [roxygen_ast_1.KnownRoxygenTags.EvalRd]: val,
189
+ [roxygen_ast_1.KnownRoxygenTags.IncludeRmd]: val,
190
+ [roxygen_ast_1.KnownRoxygenTags.Inherit]: firstAndArrayRest('source', 'components'),
191
+ [roxygen_ast_1.KnownRoxygenTags.InheritDotParams]: firstAndArrayRest('source', 'args'),
192
+ [roxygen_ast_1.KnownRoxygenTags.InheritParams]: val,
193
+ [roxygen_ast_1.KnownRoxygenTags.InheritSection]: (0, exports.firstAndRest)('source', 'section'),
194
+ [roxygen_ast_1.KnownRoxygenTags.Order]: asNumber,
195
+ [roxygen_ast_1.KnownRoxygenTags.RdName]: val,
196
+ [roxygen_ast_1.KnownRoxygenTags.Template]: val,
197
+ [roxygen_ast_1.KnownRoxygenTags.TemplateVar]: (0, exports.firstAndRest)('name', 'value'),
198
+ [roxygen_ast_1.KnownRoxygenTags.Text]: val,
199
+ [roxygen_ast_1.KnownRoxygenTags.Name]: val,
200
+ [roxygen_ast_1.KnownRoxygenTags.DocType]: val,
201
+ [roxygen_ast_1.KnownRoxygenTags.Author]: val,
202
+ [roxygen_ast_1.KnownRoxygenTags.Unknown]: (s, t) => val(s, t, l => ({
203
+ tag: t[0],
204
+ content: l.join(' ')
205
+ }))
206
+ };
207
+ function parseRoxygenTag(state, tagName) {
208
+ if (tagName === undefined) {
209
+ return;
210
+ }
211
+ const parser = TagMap[tagName[0]] ?? val;
212
+ parser(state, tagName);
213
+ }
214
+ //# sourceMappingURL=roxygen-parse.js.map
@@ -31,7 +31,7 @@ const magicCommentIdMapper = {
31
31
  return ret;
32
32
  }
33
33
  };
34
- const commentTriggerRegex = / flowr@(\w+)/;
34
+ const commentTriggerRegex = /# flowr@(\w+)/;
35
35
  /**
36
36
  * This takes an {@link NormalizedAst} and returns an auto-select predicate for {@link reconstructToCode},
37
37
  * which will automatically include lines marked by these special comments!
@@ -58,11 +58,11 @@ function makeMagicCommentHandler(and) {
58
58
  return;
59
59
  }
60
60
  for (const c of comments) {
61
- if (c.type !== type_1.RType.Comment || !c.content.startsWith(' flowr@')) {
61
+ if (c.type !== type_1.RType.Comment || !c.lexeme.startsWith('# flowr@')) {
62
62
  continue;
63
63
  }
64
- const match = commentTriggerRegex.exec(c.content);
65
- (0, assert_1.guard)(match !== null, `invalid magic comment: ${c.content}`);
64
+ const match = commentTriggerRegex.exec(c.lexeme);
65
+ (0, assert_1.guard)(match !== null, `invalid magic comment: ${c.lexeme}`);
66
66
  const idMapper = magicCommentIdMapper[match[1]];
67
67
  (0, assert_1.guard)(idMapper !== undefined, `unknown magic comment: ${match[1]}`);
68
68
  const ls = idMapper(c, startLineStack);
@@ -33,7 +33,7 @@ function getAllFunctionCallTargets(dataflowGraph, callerInfo, baseEnvironment, q
33
33
  const functionCallTargets = queue.memoizeCallTargets(functionCallDefs.join(';'), () => (0, linker_1.getAllLinkedFunctionDefinitions)(new Set(functionCallDefs), dataflowGraph)[0]);
34
34
  return [functionCallTargets, activeEnvironment];
35
35
  }
36
- function includeArgumentFunctionCallClosure(arg, baseEnvironment, activeEnvironment, queue, dataflowGraph) {
36
+ function includeArgumentFunctionCallClosure(arg, activeEnvironment, queue, dataflowGraph) {
37
37
  const valueRoot = (0, graph_1.getReferenceOfArgument)(arg);
38
38
  if (!valueRoot) {
39
39
  return;
@@ -44,7 +44,7 @@ function includeArgumentFunctionCallClosure(arg, baseEnvironment, activeEnvironm
44
44
  function linkCallTargets(onlyForSideEffects, functionCallTargets, activeEnvironment, activeEnvironmentFingerprint, queue) {
45
45
  for (const functionCallTarget of functionCallTargets) {
46
46
  for (const exitPoint of functionCallTarget.exitPoints) {
47
- queue.add(exitPoint, activeEnvironment, activeEnvironmentFingerprint, onlyForSideEffects);
47
+ queue.add(exitPoint.nodeId, activeEnvironment, activeEnvironmentFingerprint, onlyForSideEffects);
48
48
  }
49
49
  // handle open reads
50
50
  for (const openIn of functionCallTarget.subflow.in) {
@@ -60,7 +60,6 @@ function linkCallTargets(onlyForSideEffects, functionCallTargets, activeEnvironm
60
60
  }
61
61
  /** returns the new threshold hit count */
62
62
  function sliceForCall(current, callerInfo, dataflowInformation, queue, ctx) {
63
- const baseEnvironment = current.baseEnvironment;
64
63
  const [functionCallTargets, activeEnvironment] = getAllFunctionCallTargets(dataflowInformation.graph, callerInfo, current.baseEnvironment, queue, ctx);
65
64
  const activeEnvironmentFingerprint = (0, fingerprint_1.envFingerprint)(activeEnvironment);
66
65
  if (functionCallTargets.size === 0) {
@@ -69,7 +68,7 @@ function sliceForCall(current, callerInfo, dataflowInformation, queue, ctx) {
69
68
  * hence, we add a new flag and add all argument values to the queue causing directly
70
69
  */
71
70
  for (const arg of callerInfo.args) {
72
- includeArgumentFunctionCallClosure(arg, baseEnvironment, activeEnvironment, queue, dataflowInformation.graph);
71
+ includeArgumentFunctionCallClosure(arg, activeEnvironment, queue, dataflowInformation.graph);
73
72
  }
74
73
  return;
75
74
  }
@@ -66,9 +66,9 @@ function staticSlice(ctx, info, { idMap }, criteria, direction, threshold = 75,
66
66
  }
67
67
  const [currentVertex, currentEdges] = currentInfo;
68
68
  // we only add control dependencies iff 1) we are in different function call or 2) they have, at least, the same nesting as the slicing seed
69
- if (currentVertex.cds && currentVertex.cds.length > 0) {
69
+ if (currentVertex.controlDependencies && currentVertex.controlDependencies.length > 0) {
70
70
  const topLevel = graph.isRoot(id) || sliceSeedIds.has(id);
71
- for (const cd of currentVertex.cds.filter(({ id }) => !queue.hasId(id))) {
71
+ for (const cd of currentVertex.controlDependencies.filter(({ id }) => !queue.hasId(id))) {
72
72
  if (!topLevel || (idMap.get(cd.id)?.info.nesting ?? 0) >= minNesting) {
73
73
  queue.add(cd.id, baseEnvironment, baseEnvFingerprint, false);
74
74
  }
@@ -57,7 +57,7 @@ function visitDefinitions(info, input) {
57
57
  }
58
58
  const [fnDefinition] = dfNode;
59
59
  (0, assert_1.guard)(fnDefinition.tag === vertex_1.VertexType.FunctionDefinition, () => `Dataflow node is not a function definition (${JSON.stringify(fnDefinition)}))})`);
60
- const returnTypes = fnDefinition.exitPoints.map(ep => graph.get(ep, true)).filter(assert_1.isNotUndefined)
60
+ const returnTypes = fnDefinition.exitPoints.map(ep => graph.get(ep.nodeId, true)).filter(assert_1.isNotUndefined)
61
61
  .map(([vertex]) => {
62
62
  const l = graph.idMap?.get(vertex.id)?.location;
63
63
  return {
@@ -25,10 +25,10 @@ export declare class DefaultMap<K, V = K> {
25
25
  /**
26
26
  * Iterates over all entries that have been set (explicitly or by the generator)
27
27
  */
28
- entries(): IterableIterator<[K, V]>;
28
+ entries(): MapIterator<[K, V]>;
29
29
  /** returns only the keys really stored in the map */
30
- keys(): IterableIterator<K>;
31
- values(): IterableIterator<V>;
30
+ keys(): MapIterator<K>;
31
+ values(): MapIterator<V>;
32
32
  delete(k: K): boolean;
33
33
  size(): number;
34
34
  }
@@ -33,7 +33,7 @@ function formatRange(range) {
33
33
  }
34
34
  return `${range[0]}.${range[1]}-${range[2]}.${range[3]}`;
35
35
  }
36
- function subflowToMermaid(nodeId, exitPoints, subflow, mermaid, idPrefix = '') {
36
+ function subflowToMermaid(nodeId, subflow, mermaid, idPrefix = '') {
37
37
  if (subflow === undefined) {
38
38
  return;
39
39
  }
@@ -166,7 +166,7 @@ function vertexToMermaid(info, mermaid, id, idPrefix, mark, includeOnlyIds) {
166
166
  }
167
167
  else {
168
168
  const escapedName = (0, mermaid_1.escapeMarkdown)(node ? `[${node.type}] ${lexeme}` : '??');
169
- const deps = info.cds ? ', :may:' + info.cds.map(c => c.id + (c.when ? '+' : '-')).join(',') : '';
169
+ const deps = info.controlDependencies ? ', :may:' + info.controlDependencies.map(c => c.id + (c.when ? '+' : '-')).join(',') : '';
170
170
  const lnks = info.link?.origin ? ', :links:' + info.link.origin.join(',') : '';
171
171
  const n = node?.info.fullRange ?? node?.location ?? (node?.type === type_1.RType.ExpressionList ? node?.grouping?.[0].location : undefined);
172
172
  mermaid.nodeLines.push(` ${idPrefix}${id}${open}"\`${escapedName}${escapedName.length > 10 ? '\n ' : ' '}(${id}${deps}${lnks})\n *${formatRange(n)}*${fCall ? displayFunctionArgMapping(info.args) : ''}\`"${close}`);
@@ -182,7 +182,7 @@ function vertexToMermaid(info, mermaid, id, idPrefix, mark, includeOnlyIds) {
182
182
  mermaid.nodeLines.push(' %% No edges found for ' + id);
183
183
  return;
184
184
  }
185
- const artificialCdEdges = (info.cds ?? []).map(x => [x.id, { types: new Set([x.when ? 'CD-True' : 'CD-False']) }]);
185
+ const artificialCdEdges = (info.controlDependencies ?? []).map(x => [x.id, { types: new Set([x.when ? 'CD-True' : 'CD-False']) }]);
186
186
  // eslint-disable-next-line prefer-const
187
187
  for (let [target, edge] of [...edges[1], ...artificialCdEdges]) {
188
188
  if (includeOnlyIds && !includeOnlyIds.has(target)) {
@@ -207,14 +207,14 @@ function vertexToMermaid(info, mermaid, id, idPrefix, mark, includeOnlyIds) {
207
207
  mermaid.edgeLines.push(` linkStyle ${mermaid.presentEdges.size - 1} stroke:gray;`);
208
208
  if (!mermaid.presentVertices.has(target)) {
209
209
  mermaid.nodeLines.push(` ${idPrefix}${target}["\`Built-In:\n${(0, mermaid_1.escapeMarkdown)(String(originalTarget).replace('built-in:', ''))}\`"]`);
210
- mermaid.nodeLines.push(` style ${idPrefix}${target} stroke:gray,fill:lightgray,stroke-width:2px,opacity:.8;`);
210
+ mermaid.nodeLines.push(` style ${idPrefix}${target} stroke:gray,fill:gray,stroke-width:2px,opacity:.8;`);
211
211
  mermaid.presentVertices.add(target);
212
212
  }
213
213
  }
214
214
  }
215
215
  }
216
216
  if (info.tag === vertex_1.VertexType.FunctionDefinition) {
217
- subflowToMermaid(id, info.exitPoints, info.subflow, mermaid, idPrefix);
217
+ subflowToMermaid(id, info.subflow, mermaid, idPrefix);
218
218
  }
219
219
  }
220
220
  // make the passing of root ids more performant again
package/util/objects.js CHANGED
@@ -30,7 +30,7 @@ function deepMergeObject(base, addon) {
30
30
  deepMergeObjectWithResult(addon, base, result);
31
31
  }
32
32
  else if (baseIsArray && addonIsArray) {
33
- return [...base, ...addon];
33
+ return base.concat(addon);
34
34
  }
35
35
  else {
36
36
  throw new Error('cannot merge object with array!');
@@ -37,3 +37,8 @@ export declare function rAuthorInfoToReadable(author: RAuthorInfo): string;
37
37
  * For now, this works *without* the full dataflow engine, so complex cases may not be parsed correctly.
38
38
  */
39
39
  export declare function parseRAuthorString(authorString: string): RAuthorInfo[];
40
+ /**
41
+ * In contrast to `parseRAuthorString`, this function parses simple textual author strings,
42
+ * like `First Middle Last <email> [roles] (comment)...`. It does not support the full R `person()` syntax.
43
+ */
44
+ export declare function parseTextualAuthorString(authorString: string, addRoles?: AuthorRole[]): RAuthorInfo[];
package/util/r-author.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AuthorRole = void 0;
4
4
  exports.rAuthorInfoToReadable = rAuthorInfoToReadable;
5
5
  exports.parseRAuthorString = parseRAuthorString;
6
+ exports.parseTextualAuthorString = parseTextualAuthorString;
6
7
  const args_1 = require("./text/args");
7
8
  const assert_1 = require("./assert");
8
9
  const objects_1 = require("./objects");
@@ -191,4 +192,113 @@ function parseRPersonCall(personCall) {
191
192
  orcid: comments?.orcid
192
193
  });
193
194
  }
195
+ function collectUntil(source, anyOf) {
196
+ let collected = '';
197
+ let i = 0;
198
+ while (i < source.length && !anyOf.test(source[i])) {
199
+ collected += source[i];
200
+ i++;
201
+ }
202
+ return { collected, rest: source.slice(i) };
203
+ }
204
+ /**
205
+ * In contrast to `parseRAuthorString`, this function parses simple textual author strings,
206
+ * like `First Middle Last <email> [roles] (comment)...`. It does not support the full R `person()` syntax.
207
+ */
208
+ function parseTextualAuthorString(authorString, addRoles = []) {
209
+ const parts = (0, args_1.splitOnNestingSensitive)(authorString, 'and', {
210
+ '<': '>',
211
+ '[': ']',
212
+ '(': ')',
213
+ '"': '"',
214
+ "'": "'"
215
+ });
216
+ const authors = [];
217
+ for (const part of parts) {
218
+ const name = collectUntil(part.trim(), /[<[(]/);
219
+ const others = parseOnRest(name.rest);
220
+ const c = processComment(others.comment);
221
+ authors.push((0, objects_1.compactRecord)({
222
+ name: name.collected.trim().split(/\s+/),
223
+ email: others.email,
224
+ roles: others.roles.concat(addRoles),
225
+ comment: c.comment,
226
+ orcid: c.orcid
227
+ }));
228
+ }
229
+ return authors;
230
+ }
231
+ function processComment(comment) {
232
+ if (!comment) {
233
+ return {};
234
+ }
235
+ const parts = comment.split(/\s*[,;]\s*/);
236
+ const comments = [];
237
+ let orcid = undefined;
238
+ for (const part of parts) {
239
+ const orcidExtract = /ORCID\s*[:= ]\s*(?<orcid>.+)/i;
240
+ const match = part.match(orcidExtract);
241
+ if (match && match.groups && match.groups['orcid']) {
242
+ orcid = match.groups['orcid'].trim();
243
+ }
244
+ else {
245
+ comments.push(part.trim());
246
+ }
247
+ }
248
+ if (orcid) {
249
+ return { comment: comments.length > 0 ? comments : undefined, orcid };
250
+ }
251
+ else {
252
+ return { comment: [comment] };
253
+ }
254
+ }
255
+ function parseOnRest(rest) {
256
+ let email = undefined;
257
+ let roles = [];
258
+ let comment = undefined;
259
+ while (rest.length > 0) {
260
+ rest = rest.trim();
261
+ switch (rest[0]) {
262
+ case '<': {
263
+ const emailEnd = rest.indexOf('>');
264
+ if (emailEnd !== -1) {
265
+ email = rest.slice(1, emailEnd).trim();
266
+ rest = rest.slice(emailEnd + 1);
267
+ }
268
+ else {
269
+ rest = '';
270
+ }
271
+ break;
272
+ }
273
+ case '[': {
274
+ const rolesEnd = rest.indexOf(']');
275
+ if (rolesEnd !== -1) {
276
+ const rolesStr = rest.slice(1, rolesEnd).trim();
277
+ roles = rolesStr.split(/\s*,\s*/).map(r => r);
278
+ rest = rest.slice(rolesEnd + 1);
279
+ }
280
+ else {
281
+ rest = '';
282
+ }
283
+ break;
284
+ }
285
+ case '(': {
286
+ const commentEnd = rest.indexOf(')');
287
+ if (commentEnd !== -1) {
288
+ comment = rest.slice(1, commentEnd).trim();
289
+ rest = rest.slice(commentEnd + 1);
290
+ }
291
+ else {
292
+ rest = '';
293
+ }
294
+ break;
295
+ }
296
+ default: {
297
+ rest = '';
298
+ break;
299
+ }
300
+ }
301
+ }
302
+ return { email, roles, comment };
303
+ }
194
304
  //# sourceMappingURL=r-author.js.map
@@ -1,4 +1,4 @@
1
- import { Range } from 'semver';
1
+ import type { Range } from 'semver';
2
2
  export interface RLicenseInfo {
3
3
  type: 'license';
4
4
  license: string;
@@ -16,8 +16,17 @@ export interface RLicenseCombinationInfo {
16
16
  export interface NoLicenseInfo {
17
17
  type: 'no-license';
18
18
  }
19
+ /**
20
+ * The structured representation of an R license element.
21
+ * This can be a license, an exception, a combination of licenses, or no license.
22
+ * @see {@link parseRLicense} and {@link stringifyRLicense} to parse and stringify R license strings.
23
+ */
19
24
  export type RLicenseElementInfo = RLicenseInfo | RLicenseExceptionInfo | RLicenseCombinationInfo | NoLicenseInfo;
20
25
  /**
21
26
  * Parses an R license string into its structured representation.
22
27
  */
23
28
  export declare function parseRLicense(licenseString: string): RLicenseElementInfo;
29
+ /**
30
+ * Stringifies an R license element back into its string representation.
31
+ */
32
+ export declare function stringifyRLicense(license: RLicenseElementInfo): string;
package/util/r-license.js CHANGED
@@ -1,16 +1,38 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseRLicense = parseRLicense;
4
- const semver_1 = require("semver");
4
+ exports.stringifyRLicense = stringifyRLicense;
5
5
  const assert_1 = require("./assert");
6
6
  const objects_1 = require("./objects");
7
+ const r_version_1 = require("./r-version");
7
8
  /**
8
9
  * Parses an R license string into its structured representation.
9
10
  */
10
11
  function parseRLicense(licenseString) {
11
- const start = skipWhitespace({ position: 0, remInput: licenseString });
12
- const parsed = parseLicenseInfo(start);
13
- return parsed.element;
12
+ return parseLicenseInfo(skipWhitespace({ position: 0, remInput: licenseString })).element;
13
+ }
14
+ /**
15
+ * Stringifies an R license element back into its string representation.
16
+ */
17
+ function stringifyRLicense(license) {
18
+ const t = license.type;
19
+ switch (t) {
20
+ case 'no-license':
21
+ return 'NO LICENSE';
22
+ case 'license':
23
+ return license.versionConstraint ? `${license.license} (${license.versionConstraint.raw})` : license.license;
24
+ case 'exception':
25
+ return `with ${license.exception}`;
26
+ case 'combination': {
27
+ const left = stringifyRLicense(license.elements[0]);
28
+ const right = stringifyRLicense(license.elements[1]);
29
+ const leftStr = license.elements[0].type === 'combination' ? `(${left})` : left;
30
+ const rightStr = license.elements[1].type === 'combination' ? `(${right})` : right;
31
+ return `${leftStr} ${license.combination} ${rightStr}`;
32
+ }
33
+ default:
34
+ (0, assert_1.assertUnreachable)(t);
35
+ }
14
36
  }
15
37
  function parseLicenseInfo(info) {
16
38
  info = skipWhitespace(info);
@@ -72,8 +94,7 @@ function consumeLicenseName(info) {
72
94
  }
73
95
  function makeRange(rangeStr) {
74
96
  try {
75
- rangeStr = rangeStr.trim().replaceAll('==', '=');
76
- return new semver_1.Range(rangeStr);
97
+ return (0, r_version_1.parseRRange)(rangeStr);
77
98
  }
78
99
  catch {
79
100
  return undefined;
@@ -0,0 +1,19 @@
1
+ import { Range, SemVer } from 'semver';
2
+ /**
3
+ * This parses an R version string and returns a SemVer object.
4
+ * In contrast to just using `new SemVer(version)`, this function also tries to
5
+ * normalize R's much free-er versioning scheme into valid SemVer versions.
6
+ * You can always access the original version string via the `str` property on the returned object.
7
+ */
8
+ export declare function parseRVersion(version: string): SemVer & {
9
+ str: string;
10
+ };
11
+ /**
12
+ * This parses an R version range string and returns a SemVer Range object.
13
+ * In contrast to just using `new Range(range)`, this function also tries to
14
+ * normalize R's much free-er versioning scheme into valid SemVer ranges.
15
+ * You can always access the original range string via the `str` property on the returned object.
16
+ */
17
+ export declare function parseRRange(range: string): Range & {
18
+ str: string;
19
+ };