@eagleoutice/flowr 2.8.5 → 2.8.7

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 (162) hide show
  1. package/README.md +14 -14
  2. package/abstract-interpretation/absint-visitor.d.ts +20 -68
  3. package/abstract-interpretation/absint-visitor.js +44 -54
  4. package/abstract-interpretation/data-frame/dataframe-domain.d.ts +0 -9
  5. package/abstract-interpretation/data-frame/dataframe-domain.js +1 -14
  6. package/abstract-interpretation/data-frame/mappers/function-mapper.js +1 -1
  7. package/abstract-interpretation/data-frame/mappers/replacement-mapper.d.ts +2 -0
  8. package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +5 -2
  9. package/abstract-interpretation/data-frame/shape-inference.d.ts +15 -7
  10. package/abstract-interpretation/data-frame/shape-inference.js +20 -17
  11. package/abstract-interpretation/domains/abstract-domain.d.ts +1 -1
  12. package/abstract-interpretation/domains/abstract-domain.js +1 -2
  13. package/abstract-interpretation/domains/product-domain.d.ts +1 -1
  14. package/abstract-interpretation/domains/product-domain.js +1 -1
  15. package/abstract-interpretation/domains/set-range-domain.d.ts +1 -1
  16. package/abstract-interpretation/domains/set-range-domain.js +1 -1
  17. package/abstract-interpretation/domains/state-abstract-domain.d.ts +3 -1
  18. package/abstract-interpretation/domains/state-abstract-domain.js +6 -0
  19. package/abstract-interpretation/normalized-ast-fold.d.ts +2 -1
  20. package/abstract-interpretation/normalized-ast-fold.js +8 -1
  21. package/cli/flowr.js +2 -0
  22. package/cli/repl/commands/repl-execute.js +1 -1
  23. package/cli/repl/commands/repl-query.js +7 -9
  24. package/cli/wiki.d.ts +2 -1
  25. package/cli/wiki.js +2 -0
  26. package/control-flow/cfg-dead-code.js +3 -0
  27. package/control-flow/extract-cfg.js +27 -7
  28. package/control-flow/semantic-cfg-guided-visitor.d.ts +57 -4
  29. package/control-flow/semantic-cfg-guided-visitor.js +89 -28
  30. package/control-flow/useless-loop.d.ts +2 -1
  31. package/control-flow/useless-loop.js +13 -6
  32. package/dataflow/environments/built-in-config.d.ts +6 -5
  33. package/dataflow/environments/built-in.d.ts +107 -34
  34. package/dataflow/environments/built-in.js +115 -39
  35. package/dataflow/environments/default-builtin-config.d.ts +113 -67
  36. package/dataflow/environments/default-builtin-config.js +71 -66
  37. package/dataflow/environments/diff.js +2 -2
  38. package/dataflow/environments/environment.js +7 -7
  39. package/dataflow/environments/identifier.d.ts +4 -2
  40. package/dataflow/environments/identifier.js +2 -0
  41. package/dataflow/environments/reference-to-maybe.d.ts +2 -2
  42. package/dataflow/environments/reference-to-maybe.js +11 -11
  43. package/dataflow/environments/resolve-by-name.js +17 -6
  44. package/dataflow/eval/resolve/alias-tracking.js +1 -1
  45. package/dataflow/eval/resolve/resolve.js +6 -6
  46. package/dataflow/eval/values/intervals/interval-constants.js +3 -3
  47. package/dataflow/eval/values/scalar/{scalar-consatnts.d.ts → scalar-constants.d.ts} +2 -2
  48. package/dataflow/eval/values/scalar/{scalar-consatnts.js → scalar-constants.js} +3 -3
  49. package/dataflow/eval/values/sets/set-constants.d.ts +4 -2
  50. package/dataflow/eval/values/sets/set-constants.js +4 -2
  51. package/dataflow/extractor.js +1 -1
  52. package/dataflow/fn/exceptions-of-function.d.ts +1 -1
  53. package/dataflow/fn/exceptions-of-function.js +3 -3
  54. package/dataflow/graph/call-graph.js +2 -2
  55. package/dataflow/graph/dataflowgraph-builder.d.ts +4 -4
  56. package/dataflow/graph/dataflowgraph-builder.js +14 -14
  57. package/dataflow/graph/diff-dataflow-graph.js +3 -3
  58. package/dataflow/graph/graph.d.ts +1 -1
  59. package/dataflow/graph/graph.js +4 -4
  60. package/dataflow/graph/vertex.d.ts +3 -3
  61. package/dataflow/info.d.ts +3 -3
  62. package/dataflow/info.js +11 -11
  63. package/dataflow/internal/linker.d.ts +9 -0
  64. package/dataflow/internal/linker.js +33 -7
  65. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +16 -12
  66. package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +1 -1
  67. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +11 -10
  68. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +20 -17
  69. package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +1 -1
  70. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +4 -3
  71. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.d.ts +1 -1
  72. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +9 -9
  73. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.d.ts +5 -1
  74. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +11 -6
  75. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +0 -7
  76. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +39 -6
  77. package/dataflow/internal/process/functions/call/built-in/built-in-get.js +2 -1
  78. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +12 -1
  79. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +36 -12
  80. package/dataflow/internal/process/functions/call/built-in/built-in-library.d.ts +1 -1
  81. package/dataflow/internal/process/functions/call/built-in/built-in-library.js +3 -2
  82. package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -1
  83. package/dataflow/internal/process/functions/call/built-in/built-in-local.d.ts +18 -0
  84. package/dataflow/internal/process/functions/call/built-in/built-in-local.js +67 -0
  85. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.d.ts +1 -1
  86. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +11 -10
  87. package/dataflow/internal/process/functions/call/built-in/built-in-quote.d.ts +1 -1
  88. package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +3 -2
  89. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.js +5 -4
  90. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +3 -2
  91. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +2 -1
  92. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +7 -6
  93. package/dataflow/internal/process/functions/call/built-in/built-in-rm.d.ts +1 -1
  94. package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +3 -2
  95. package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.d.ts +18 -0
  96. package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.js +103 -0
  97. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +8 -7
  98. package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.js +4 -3
  99. package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.js +13 -12
  100. package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.js +6 -5
  101. package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -1
  102. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.d.ts +1 -1
  103. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +7 -6
  104. package/dataflow/internal/process/functions/call/common.js +7 -7
  105. package/dataflow/internal/process/functions/call/known-call-handling.js +7 -8
  106. package/dataflow/internal/process/functions/call/unnamed-call-handling.d.ts +1 -2
  107. package/dataflow/internal/process/functions/call/unnamed-call-handling.js +6 -6
  108. package/dataflow/internal/process/functions/process-argument.js +2 -2
  109. package/dataflow/internal/process/functions/process-parameter.js +3 -3
  110. package/dataflow/internal/process/process-symbol.js +3 -3
  111. package/dataflow/internal/process/process-uninteresting-leaf.d.ts +3 -1
  112. package/dataflow/internal/process/process-uninteresting-leaf.js +3 -1
  113. package/dataflow/internal/process/process-value.d.ts +1 -1
  114. package/dataflow/internal/process/process-value.js +4 -4
  115. package/dataflow/origin/dfg-get-symbol-refs.js +1 -1
  116. package/dataflow/processor.d.ts +1 -1
  117. package/documentation/doc-util/doc-structure.js +1 -1
  118. package/documentation/doc-util/doc-types.d.ts +10 -3
  119. package/documentation/doc-util/doc-types.js +110 -33
  120. package/documentation/wiki-absint.d.ts +6 -0
  121. package/documentation/wiki-absint.js +149 -0
  122. package/documentation/wiki-analyzer.js +1 -1
  123. package/documentation/wiki-dataflow-graph.js +12 -11
  124. package/documentation/wiki-interface.js +2 -1
  125. package/documentation/wiki-mk/doc-context.d.ts +3 -3
  126. package/documentation/wiki-mk/doc-context.js +2 -2
  127. package/documentation/wiki-mk/doc-maker.js +2 -2
  128. package/documentation/wiki-normalized-ast.d.ts +9 -0
  129. package/documentation/wiki-normalized-ast.js +40 -52
  130. package/linter/linter-rules.d.ts +1 -1
  131. package/linter/rules/seeded-randomness.js +5 -4
  132. package/linter/rules/useless-loop.d.ts +3 -3
  133. package/package.json +1 -1
  134. package/queries/catalog/call-context-query/call-context-query-executor.js +9 -4
  135. package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +1 -1
  136. package/queries/catalog/control-flow-query/control-flow-query-executor.js +1 -1
  137. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +4 -0
  138. package/queries/catalog/dependencies-query/dependencies-query-format.js +5 -0
  139. package/queries/catalog/dependencies-query/function-info/test-functions.d.ts +2 -0
  140. package/queries/catalog/dependencies-query/function-info/test-functions.js +82 -0
  141. package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +3 -2
  142. package/queries/catalog/df-shape-query/df-shape-query-format.js +3 -3
  143. package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.d.ts +1 -1
  144. package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.js +1 -1
  145. package/r-bridge/data/data.d.ts +6 -1
  146. package/r-bridge/data/data.js +8 -2
  147. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +7 -0
  148. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +19 -0
  149. package/r-bridge/lang-4.x/ast/model/nodes/r-project.d.ts +4 -0
  150. package/r-bridge/lang-4.x/ast/model/nodes/r-project.js +7 -0
  151. package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +3 -1
  152. package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +2 -1
  153. package/r-bridge/lang-4.x/convert-values.d.ts +5 -0
  154. package/search/flowr-search-filters.d.ts +2 -2
  155. package/slicing/static/static-slicer.js +2 -2
  156. package/util/mermaid/cfg.d.ts +10 -3
  157. package/util/mermaid/cfg.js +39 -10
  158. package/util/mermaid/dfg.js +5 -5
  159. package/util/simple-df/dfg-view.js +1 -1
  160. package/util/text/ansi.d.ts +4 -0
  161. package/util/text/ansi.js +7 -0
  162. package/util/version.js +1 -1
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
@@ -16,7 +49,7 @@ exports.printCodeOfElement = printCodeOfElement;
16
49
  exports.shortLink = shortLink;
17
50
  exports.shortLinkFile = shortLinkFile;
18
51
  exports.getDocumentationForType = getDocumentationForType;
19
- const typescript_1 = __importDefault(require("typescript"));
52
+ const typescript_1 = __importStar(require("typescript"));
20
53
  const assert_1 = require("../../util/assert");
21
54
  const doc_files_1 = require("./doc-files");
22
55
  const fs_1 = __importDefault(require("fs"));
@@ -128,6 +161,33 @@ function getStartLineOfTypeScriptNode(node, sourceFile) {
128
161
  const lineStart = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line;
129
162
  return lineStart + 1;
130
163
  }
164
+ function hasModifier(modifiers, modifier) {
165
+ return modifiers.some(mod => typeof mod === 'object' && mod !== null && 'kind' in mod && mod.kind === modifier);
166
+ }
167
+ function formatNode(node, sourceFile, typeChecker) {
168
+ const name = node.name?.getText(sourceFile);
169
+ let prefix = '', suffix = '';
170
+ if ('modifiers' in node && Array.isArray(node.modifiers)) {
171
+ if (hasModifier(node.modifiers, typescript_1.SyntaxKind.PrivateKeyword)) {
172
+ prefix = '-';
173
+ }
174
+ else if (hasModifier(node.modifiers, typescript_1.SyntaxKind.ProtectedKeyword)) {
175
+ prefix = '#';
176
+ }
177
+ else if (hasModifier(node.modifiers, typescript_1.SyntaxKind.PublicKeyword)) {
178
+ prefix = '+';
179
+ }
180
+ if (hasModifier(node.modifiers, typescript_1.SyntaxKind.AbstractKeyword)) {
181
+ suffix = '*';
182
+ }
183
+ else if (hasModifier(node.modifiers, typescript_1.SyntaxKind.StaticKeyword)) {
184
+ suffix = '$';
185
+ }
186
+ }
187
+ const type = getType(node, typeChecker);
188
+ const typeAnnotation = type.includes('=>') ? type.replaceAll(/\s+=>\s+/g, ' ') : ': ' + type;
189
+ return `${prefix}${(0, mermaid_1.escapeMarkdown)(name + typeAnnotation)}${suffix}`;
190
+ }
131
191
  function getType(node, typeChecker) {
132
192
  const tryDirect = typeChecker.getTypeAtLocation(node);
133
193
  return tryDirect ? typeChecker.typeToString(tryDirect) : 'unknown';
@@ -168,10 +228,7 @@ function collectHierarchyInformation(sourceFiles, options) {
168
228
  comments: getTextualCommentsFromTypeScript(node),
169
229
  filePath: sourceFile.fileName,
170
230
  lineNumber: getStartLineOfTypeScriptNode(node, sourceFile),
171
- properties: node.members.map(member => {
172
- const name = member.name?.getText(sourceFile) ?? '';
173
- return `${name}${(0, mermaid_1.escapeMarkdown)(': ' + getType(member, typeChecker))}`;
174
- }),
231
+ properties: node.members.map(member => formatNode(member, sourceFile, typeChecker)),
175
232
  });
176
233
  }
177
234
  else if (typescript_1.default.isTypeAliasDeclaration(node)) {
@@ -209,10 +266,7 @@ function collectHierarchyInformation(sourceFiles, options) {
209
266
  generics: [],
210
267
  filePath: sourceFile.fileName,
211
268
  lineNumber: getStartLineOfTypeScriptNode(node, sourceFile),
212
- properties: node.members.map(member => {
213
- const name = member.name?.getText(sourceFile) ?? '';
214
- return `${name}${(0, mermaid_1.escapeMarkdown)(': ' + getType(member, typeChecker))}`;
215
- })
269
+ properties: node.members.map(member => formatNode(member, sourceFile, typeChecker))
216
270
  });
217
271
  }
218
272
  else if (typescript_1.default.isEnumMember(node)) {
@@ -244,10 +298,9 @@ function collectHierarchyInformation(sourceFiles, options) {
244
298
  generics,
245
299
  filePath: sourceFile.fileName,
246
300
  lineNumber: getStartLineOfTypeScriptNode(node, sourceFile),
247
- properties: node.members.map(member => {
248
- const name = member.name?.getText(sourceFile) ?? '';
249
- return `${name}${(0, mermaid_1.escapeMarkdown)(': ' + getType(member, typeChecker))}`;
250
- }),
301
+ properties: node.members
302
+ .filter(member => member.name !== undefined)
303
+ .map(member => formatNode(member, sourceFile, typeChecker)),
251
304
  });
252
305
  }
253
306
  else if (typescript_1.default.isVariableDeclaration(node) || typescript_1.default.isExportDeclaration(node) || typescript_1.default.isExportAssignment(node) || typescript_1.default.isDeclarationStatement(node)) {
@@ -265,7 +318,7 @@ function collectHierarchyInformation(sourceFiles, options) {
265
318
  });
266
319
  }
267
320
  else if (typescript_1.default.isPropertyAssignment(node) || typescript_1.default.isPropertyDeclaration(node) || typescript_1.default.isPropertySignature(node)
268
- || typescript_1.default.isMethodDeclaration(node) || typescript_1.default.isMethodSignature(node) || typescript_1.default.isFunctionDeclaration(node)) {
321
+ || typescript_1.default.isMethodDeclaration(node) || typescript_1.default.isMethodSignature(node) || typescript_1.default.isFunctionDeclaration(node) || typescript_1.default.isGetAccessorDeclaration(node) || typescript_1.default.isSetAccessorDeclaration(node)) {
269
322
  const name = node.name?.getText(sourceFile) ?? '';
270
323
  // get the name of the object/enclosing type
271
324
  let parent = node.parent;
@@ -315,22 +368,30 @@ function generateMermaidClassDiagram(hierarchyList, rootName, options, visited =
315
368
  return collect;
316
369
  }
317
370
  const genericPart = node.generics.length > 0 ? `~${node.generics.join(', ')}~` : '';
318
- collect.nodeLines.push(`class ${node.name}${genericPart}`);
319
- collect.nodeLines.push(` <<${node.kind}>> ${node.name}`);
320
- if (node.kind === 'type') {
321
- collect.nodeLines.push(`style ${node.name} opacity:.35,fill:#FAFAFA`);
322
- }
371
+ collect.nodeLines.push(`class ${node.name}${genericPart}{`);
372
+ collect.nodeLines.push(` <<${node.kind}>>`);
323
373
  const writtenProperties = new Set();
324
- if (node.properties) {
374
+ if (!options.simplify && node.properties) {
325
375
  for (const property of node.properties) {
326
- collect.nodeLines.push(` ${node.name} : ${property}`);
376
+ collect.nodeLines.push(` ${property}`);
327
377
  writtenProperties.add(property);
328
378
  }
329
379
  }
380
+ collect.nodeLines.push('}');
381
+ if (node.kind === 'type') {
382
+ collect.nodeLines.push(`style ${node.name} opacity:.35,fill:#FAFAFA`);
383
+ }
330
384
  collect.nodeLines.push(`click ${node.name} href "${getTypePathLink(node)}" "${(0, mermaid_1.escapeMarkdown)(node.comments?.join('; ').replace(/\n/g, ' ') ?? '')}"`);
331
385
  const inline = [...options.inlineTypes ?? [], ...defaultSkip];
332
- if (node.extends.length > 0) {
333
- for (const baseType of node.extends) {
386
+ let baseTypes = node.extends;
387
+ if (options.reverse) {
388
+ baseTypes = hierarchyList
389
+ .filter(e => e.kind === 'class' || e.kind === 'interface' || e.kind === 'type' || e.kind === 'enum')
390
+ .filter(e => e.extends.includes(rootName))
391
+ .map(e => e.name);
392
+ }
393
+ if (baseTypes.length > 0) {
394
+ for (const baseType of baseTypes) {
334
395
  if (inline.includes(baseType)) {
335
396
  const info = hierarchyList.find(h => h.name === baseType);
336
397
  for (const property of info?.properties ?? []) {
@@ -345,7 +406,7 @@ function generateMermaidClassDiagram(hierarchyList, rootName, options, visited =
345
406
  collect.edgeLines.push(`${dropGenericsFromTypeName(baseType)} .. ${node.name}`);
346
407
  }
347
408
  else {
348
- collect.edgeLines.push(`${dropGenericsFromTypeName(baseType)} <|-- ${node.name}`);
409
+ collect.edgeLines.push(`${dropGenericsFromTypeName(baseType)} ${options.reverse ? '--|>' : '<|--'} ${node.name}`);
349
410
  }
350
411
  const { nodeLines, edgeLines } = generateMermaidClassDiagram(hierarchyList, baseType, options, visited);
351
412
  collect.nodeLines.push(...nodeLines);
@@ -364,8 +425,13 @@ function visualizeMermaidClassDiagram(hierarchyList, options) {
364
425
  }
365
426
  const { nodeLines, edgeLines } = generateMermaidClassDiagram(hierarchyList, options.typeNameForMermaid, options);
366
427
  return nodeLines.length === 0 && edgeLines.length === 0 ? '' : `
428
+ ---
429
+ config:
430
+ class:
431
+ hideEmptyMembersBox: true
432
+ ---
367
433
  classDiagram
368
- direction RL
434
+ direction ${options.reverse ? 'LR' : 'RL'}
369
435
  ${nodeLines.join('\n')}
370
436
  ${edgeLines.join('\n')}
371
437
  `;
@@ -422,12 +488,12 @@ function implSnippet(node, program, showName = true, nesting = 0, open = false,
422
488
  const init = showName ? `* ${bold}[${node.name}](${getTypePathLink(node)})${bold} ${sep}${indent}` : '';
423
489
  return ` ${indent}${showName ? init : ''} ${text.replaceAll('\t', ' ').split(/\n/g).join(`\n${indent} `)}`;
424
490
  }
425
- exports.mermaidHide = ['Leaf', 'Location', 'Namespace', 'Base', 'WithChildren', 'Partial', 'RAccessBase'];
491
+ exports.mermaidHide = ['MergeableRecord', 'Leaf', 'Location', 'Namespace', 'Base', 'WithChildren', 'Partial', 'RAccessBase'];
426
492
  /**
427
493
  * Print the hierarchy of types starting from the given root.
428
494
  * If you create a wiki, please refer to the functions provided by the {@link GeneralWikiContext}.
429
495
  */
430
- function printHierarchy({ program, info, root, collapseFromNesting = 1, initialNesting = 0, maxDepth = 20, openTop, showImplSnippet = true }) {
496
+ function printHierarchy({ program, info, root, ignoredTypes, collapseFromNesting = 1, initialNesting = 0, maxDepth = 20, skipNesting = 0, openTop, showImplSnippet = true, reverse = false }) {
431
497
  if (initialNesting > maxDepth) {
432
498
  return '';
433
499
  }
@@ -435,18 +501,29 @@ function printHierarchy({ program, info, root, collapseFromNesting = 1, initialN
435
501
  if (!node) {
436
502
  return '';
437
503
  }
438
- const thisLine = implSnippet(node, program, true, initialNesting, initialNesting === 0 && openTop, showImplSnippet);
504
+ let thisLine = '';
505
+ if (initialNesting >= skipNesting) {
506
+ thisLine = implSnippet(node, program, true, initialNesting, initialNesting === 0 && openTop, showImplSnippet);
507
+ }
508
+ let baseTypes = node.extends;
509
+ if (reverse) {
510
+ baseTypes = info
511
+ .filter(e => e.kind === 'class' || e.kind === 'interface')
512
+ .filter(e => e.extends.includes(root))
513
+ .map(e => e.name);
514
+ }
439
515
  const result = [];
440
- for (const baseType of node.extends) {
441
- if (exports.mermaidHide.includes(baseType)) {
516
+ for (const baseType of baseTypes) {
517
+ if (exports.mermaidHide.includes(baseType) || ignoredTypes?.includes(baseType)) {
442
518
  continue;
443
519
  }
444
- const res = printHierarchy({ program, info: info, root: baseType, collapseFromNesting, initialNesting: initialNesting + 1, maxDepth, showImplSnippet });
520
+ const res = printHierarchy({ program, info, root: baseType, collapseFromNesting, initialNesting: initialNesting + 1, maxDepth, skipNesting, showImplSnippet, reverse });
445
521
  result.push(res);
446
522
  }
447
523
  const out = result.join('\n');
448
- if (initialNesting === collapseFromNesting - 1) {
449
- return thisLine + (out ? (0, doc_structure_1.details)(`View more (${node.extends.join(', ')})`, out, { prefixInit: ' '.repeat(2 * (collapseFromNesting + 1)) }) : '');
524
+ if (initialNesting >= collapseFromNesting - 1) {
525
+ const more = baseTypes.length > 4 ? baseTypes.slice(0, 4).join(', ') + ', ...' : baseTypes.join(', ');
526
+ return thisLine + (out ? (0, doc_structure_1.details)(`View more (${more})`, out, { prefixInit: ' '.repeat(2 * (initialNesting + 2)) }) : '');
450
527
  }
451
528
  else {
452
529
  return thisLine + (out ? '\n' + out : '');
@@ -0,0 +1,6 @@
1
+ import type { DocMakerArgs } from './wiki-mk/doc-maker';
2
+ import { DocMaker } from './wiki-mk/doc-maker';
3
+ export declare class WikiAbsint extends DocMaker<'wiki/Abstract Interpretation.md'> {
4
+ constructor();
5
+ protected text({ ctx }: DocMakerArgs): Promise<string>;
6
+ }
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WikiAbsint = void 0;
4
+ const absint_visitor_1 = require("../abstract-interpretation/absint-visitor");
5
+ const abstract_domain_1 = require("../abstract-interpretation/domains/abstract-domain");
6
+ const interval_domain_1 = require("../abstract-interpretation/domains/interval-domain");
7
+ const state_abstract_domain_1 = require("../abstract-interpretation/domains/state-abstract-domain");
8
+ const semantic_cfg_guided_visitor_1 = require("../control-flow/semantic-cfg-guided-visitor");
9
+ const flowr_analyzer_builder_1 = require("../project/flowr-analyzer-builder");
10
+ const r_function_call_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
11
+ const doc_code_1 = require("./doc-util/doc-code");
12
+ const doc_structure_1 = require("./doc-util/doc-structure");
13
+ const doc_maker_1 = require("./wiki-mk/doc-maker");
14
+ class IntervalInferenceVisitor extends absint_visitor_1.AbstractInterpretationVisitor {
15
+ onNumberConstant({ vertex, node }) {
16
+ super.onNumberConstant({ vertex, node });
17
+ const interval = new interval_domain_1.IntervalDomain([node.content.num, node.content.num]);
18
+ this.currentState.set(node.info.id, interval);
19
+ }
20
+ onFunctionCall({ call }) {
21
+ super.onFunctionCall({ call });
22
+ if (call.args.length === 2 && call.args.every(arg => arg !== r_function_call_1.EmptyArgument)) {
23
+ const left = this.getAbstractValue(call.args[0].nodeId);
24
+ const right = this.getAbstractValue(call.args[1].nodeId);
25
+ if (left === undefined || right === undefined) {
26
+ // If an operand does not have an inferred interval, this might not be a numerical operation
27
+ return;
28
+ }
29
+ // We map the numerical operation to the resulting interval after applying the abstract semantics of the operation
30
+ switch (call.name) {
31
+ case '+':
32
+ return this.currentState.set(call.id, left.add(right));
33
+ case '-':
34
+ return this.currentState.set(call.id, left.subtract(right));
35
+ }
36
+ }
37
+ }
38
+ }
39
+ async function inferIntervals() {
40
+ const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder()
41
+ .setEngine('tree-sitter')
42
+ .build();
43
+ analyzer.addRequest(`
44
+ x <- 42
45
+ y <- if (runif() < 0.5) 6 else 12
46
+ z <- x + y
47
+ `.trim());
48
+ const ast = await analyzer.normalize();
49
+ const dfg = (await analyzer.dataflow()).graph;
50
+ const cfg = await analyzer.controlflow();
51
+ const ctx = analyzer.inspectContext();
52
+ const domain = new state_abstract_domain_1.StateAbstractDomain(new Map());
53
+ const inference = new IntervalInferenceVisitor({ controlFlow: cfg, dfg: dfg, normalizedAst: ast, ctx: ctx, domain: domain });
54
+ inference.start();
55
+ const result = inference.getEndState();
56
+ return result.value.entries().toArray()
57
+ .map(([id, value]) => `${nodeIdToSlicingCriterion(id, ast.idMap)} -> ${value.toString()}`)
58
+ .join('\n');
59
+ }
60
+ function nodeIdToSlicingCriterion(id, idMap) {
61
+ const node = idMap.get(id);
62
+ return `${node?.location?.[0]}@${node?.lexeme}`;
63
+ }
64
+ class WikiAbsint extends doc_maker_1.DocMaker {
65
+ constructor() {
66
+ super('wiki/Abstract Interpretation.md', module.filename, 'abstract interpretation framework');
67
+ }
68
+ async text({ ctx }) {
69
+ return `
70
+ This page describes the abstract interpretation framework of _flowR_.
71
+ Abstract interpretation abstracts the concrete semantics of a program to automatically infer properties about the behavior of a program.
72
+ It uses an abstract domain to capture sets of possible runtime values of a program.
73
+ An abstract domain is represented by a lattice with a partial order, join operator (least upper bound), meet operator (greated lower bound), top element (greatest element), and bottom element (least element).
74
+ Abstract interpretation uses an abstraction of the concrete semantics of a program to perform fixpoint iteration to find program invariants.
75
+
76
+ ${(0, doc_structure_1.section)('Abstract Domains', 2, 'abstract-domains')}
77
+
78
+ To perform abstract interpretation, we first need to define an abstract domain to capture possible runtime values of the program.
79
+ In _flowR_, an abstract domain is represented by the class ${ctx.link(abstract_domain_1.AbstractDomain)} that extends the ${ctx.link('Lattice')} interface. It has the type parameters \`Concrete\` for the concrete domain of the abstract domain (e.g. strings, numbers, lists), \`Abstract\` for the abstract representation of the values (e.g. sets, intervals), \`Top\` for the representation of the top element, \`Bot\` for the representation of the bottom element, and \`Value\` for the type of the current abstract value of the abstract domain (i.e. \`Abstract\`, \`Top\`, or \`Bot\`). An abstract domain provides the following properties and functions:
80
+
81
+ * ${ctx.linkM(abstract_domain_1.AbstractDomain, 'value')} the current abstract value of the abstract domain
82
+ * ${ctx.linkM(abstract_domain_1.AbstractDomain, 'top')} to get the top element (greatest element) of the abstract domain
83
+ * ${ctx.linkM(abstract_domain_1.AbstractDomain, 'bottom')} to get the bottom element (least element) of the abstract domain
84
+ <!-- --->
85
+ * ${ctx.linkM(abstract_domain_1.AbstractDomain, 'isTop')} to check whether the current abstract value is top
86
+ * ${ctx.linkM(abstract_domain_1.AbstractDomain, 'isBottom')} to check whether the current abstract value is bottom
87
+ * ${ctx.linkM(abstract_domain_1.AbstractDomain, 'isValue')} to check whether the current abstract value is a value (can still be top or bottom)
88
+ <!-- --->
89
+ * ${ctx.linkM(abstract_domain_1.AbstractDomain, 'leq')} to check whether two abstract values are ordered with respect to the partial order of the lattice
90
+ * ${ctx.linkM(abstract_domain_1.AbstractDomain, 'join')} to join two abstract values to get the least upper bound (LUB)
91
+ * ${ctx.linkM(abstract_domain_1.AbstractDomain, 'meet')} to meet two abstract values to get the greates lower bound (GLB)
92
+ * ${ctx.linkM(abstract_domain_1.AbstractDomain, 'widen')} to perform widening with another abstract value to ensure termination of the fixpoint iteration
93
+ * ${ctx.linkM(abstract_domain_1.AbstractDomain, 'narrow')} to perform narrowing with another abstract value to refine the abstract value after widening
94
+ <!-- --->
95
+ * ${ctx.linkM(abstract_domain_1.AbstractDomain, 'concretize')} representing the concretization function of the abstract domain
96
+ * ${ctx.linkM(abstract_domain_1.AbstractDomain, 'abstract')} representing the abstraction function of the abstract domain
97
+
98
+ ${(0, doc_structure_1.details)('Class Diagram', `
99
+ All boxes link to their respective implementation in the source code.
100
+ ${(0, doc_code_1.codeBlock)('mermaid', ctx.mermaid(abstract_domain_1.AbstractDomain))}
101
+ `.trim())}
102
+
103
+ The ${ctx.link('Top')} and ${ctx.link('Bottom')} symbols can be used to explicitly represent the top or bottom elment of an abstract domain. Additionally, for value abstract domains, there is the ${ctx.link('SatisfiableDomain')} interface that provides the function ${ctx.link('SatisfiableDomain:::satisfies')} to check whether the current abstract value of the abstract domain satisfies a concrete value (see also ${ctx.link('NumericalComparator')} and ${ctx.link('SetComparator')}).
104
+
105
+ _flowR_ already provides different abstract domains for abstract interpretation in [\`src/abstract-interpretation/domains\`](https://github.com/flowr-analysis/flowr/tree/main/src/abstract-interpretation/domains). Many of the abstract domains are generic and can be used for differend kinds of analyses. The existing abstract domains are presented in the following. Some of the listed abstract domains can be expanded to show the inherited abstract domains.
106
+
107
+ ${ctx.hierarchy(abstract_domain_1.AbstractDomain, { collapseFromNesting: 2, skipNesting: 1, reverse: true })}
108
+
109
+ ${(0, doc_structure_1.details)('Class Diagram', `
110
+ All boxes link to their respective implementation in the source code.
111
+ ${(0, doc_code_1.codeBlock)('mermaid', ctx.mermaid(abstract_domain_1.AbstractDomain, { simplify: true, reverse: true }))}
112
+ `.trim())}
113
+
114
+ ${(0, doc_structure_1.section)('Abstract Interpretation', 2, 'abstract-interpretation')}
115
+
116
+ We perform abstract interpretation by forward-traversing the ${ctx.linkPage('wiki/Control Flow Graph', 'control flow graph')} of _flowR_ using an ${ctx.link(absint_visitor_1.AbstractInterpretationVisitor)}. For each visited control flow vertex, the visitor retrieves the current abstract state by joining the abstract states of the predecessors, applies the abstract semantics of the visited control flow vertex to the current state, and updates the abstract state of the currently visited vertex to the current state. The visitor already handles assignments and (delayed) widening at widening points. However, the visitor does not yet support interprocedural abstract interpretation.
117
+
118
+ To implement a custom abstract interpretation analysis, we can just create a new class and extend the ${ctx.link(absint_visitor_1.AbstractInterpretationVisitor)}. The abstract interpretation visitor uses a ${ctx.link(state_abstract_domain_1.StateAbstractDomain)} to capture the current abstract state at each vertex in the control flow graph. Hence, the abstract interpretation visitor requires a value abstract domain \`Domain\` as type parameter to specify the state abstract domain. We can then extend the callback functions of the ${ctx.link(absint_visitor_1.AbstractInterpretationVisitor)} to implement the abstract semantics of expressions, such as ${ctx.link(`${semantic_cfg_guided_visitor_1.SemanticCfgGuidedVisitor.name}:::onNumberConstant`)}, ${ctx.link(`${absint_visitor_1.AbstractInterpretationVisitor.name}:::onFunctionCall`)}, and ${ctx.link(`${semantic_cfg_guided_visitor_1.SemanticCfgGuidedVisitor.name}:::onReplacementCall`)} (make sure to still call the respective super function). The abstract interpretation visitor provides the following functions to retrieve the currently inferred values:
119
+
120
+ * ${ctx.linkM(absint_visitor_1.AbstractInterpretationVisitor, 'getAbstractValue')} to resolve the inferred abstract value for an AST node (this includes resolving symbols, pipes, and if expressions)
121
+ * ${ctx.linkM(absint_visitor_1.AbstractInterpretationVisitor, 'getAbstractState')} to get the inferred abstract state at an AST node mapping AST nodes to abstract values
122
+ * ${ctx.linkM(absint_visitor_1.AbstractInterpretationVisitor, 'getAbstractTrace')} to get the complete abstract trace mapping AST nodes to abstract states at the respective node
123
+ * ${ctx.linkM(absint_visitor_1.AbstractInterpretationVisitor, 'getEndState')} to get the inferred abstract state at the end of the program (at the exit points of the control flow graph)
124
+
125
+ For example, if we want to perform a (very basic) interval analysis using abstract interpretation in _flowR_, we can implement the following ${ctx.link(IntervalInferenceVisitor)} that extends ${ctx.link(absint_visitor_1.AbstractInterpretationVisitor)} using the ${ctx.link(interval_domain_1.IntervalDomain)}:
126
+
127
+ ${ctx.code(IntervalInferenceVisitor)}
128
+
129
+ The interval inference visitor first overrides the ${ctx.link(`${semantic_cfg_guided_visitor_1.SemanticCfgGuidedVisitor.name}:::onNumberConstant`)} function to infer intervals for visited control flow vertices that represent numeric constants. For numeric constants, the resulting interval consists just of the number value of the constant. We then update the current abstract state of the visitor by setting the inferred abstract value of the currently visited control flow vertex to the new interval.
130
+
131
+ In this simple example, we only want to support the addition and subtraction of numeric values. Therefore, we override the ${ctx.link(`${absint_visitor_1.AbstractInterpretationVisitor.name}:::onFunctionCall`)} function to apply the abstract semantics of additions and subtraction with resprect to the interval domain. For the addition and subtraction, we are only interested in function calls with exactly two non-empty arguments. We first resolve the currently inferred abstract value for the left and right operand of the function call. If we have no inferred value for one of the operands, this function call might not be a numeric function call and we ignore it. Otherwise, we check whether the function call represents an addition or subtraction and apply the abstract semantics of the operation to the left and right operand. We then again update the current abstract state of the visitor by setting the inferred abstract value of the currently visited function call vertex to the abstract value resulting from applying the abstract semantics of the operation to the operands.
132
+
133
+ If we now want to run the interval inference, we can write the following code:
134
+
135
+ ${ctx.code(inferIntervals, { dropLinesStart: 1, dropLinesEnd: 5 })}
136
+
137
+ We first need a ${ctx.linkPage('wiki/Analyzer', 'flowR analyzer')} (in this case, using the ${ctx.linkPage('wiki/Engines', 'tree-sitter engine')}). In this example, we want to analyze a small example code that assigns \`42\` to the variable \`x\`, randomly assigns \`6\` or \`12\` to the variable \`y\`, and assignes the sum of \`x\` and \`y\` to the variable \`z\`. For the abstract interpretation visitor, we need to retrieve the ${ctx.linkPage('wiki/Normalized AST', 'normalized AST')}, ${ctx.linkPage('wiki/Dataflow Graph', 'dataflow graph')}, ${ctx.linkPage('wiki/Control Flow Graph', 'control flow graph')}, and context of the flowR anaylzer. Additionally, we need to provide a state abstract domain for the visitor -- in this case, a state abstract domain for the interval domain. We then construct a new ${ctx.link(IntervalInferenceVisitor)} using the control flow graph, dataflow graph, normalized AST, analyzer context, and state abstract domain, and start the visitor using ${ctx.linkM(absint_visitor_1.AbstractInterpretationVisitor, 'start', { hideClass: true })}. After the visitor is finished, we retrieve the inferred abstract state at the end of the program using ${ctx.linkM(absint_visitor_1.AbstractInterpretationVisitor, 'getEndState', { hideClass: true })}.
138
+
139
+ If we now print the inferred abstract state at the end of the program, we get the following output:
140
+
141
+ ${(0, doc_code_1.codeBlock)('ts', await inferIntervals())}
142
+ <i>The output has been prettified for better readability.</i>
143
+
144
+ The AST nodes are represented as slicing criteria for better readability in the format \`<line>@<lexeme>\`. Here, the constants \`42\`, \`0.5\`, \`6\`, and \`12\` of line 1 and 2 are mapped to the intervals \`[42, 42]\`, \`[0.5, 0.5]\`, \`[6, 6]\`, and \`[12, 12]\`, respectively. The variable \`x\` of line 1 is mapped to the interval \`[42, 42]\` of the assigned value and the variable \`y\` of line 2 is assigned to the interval \`[6, 12]\` representing a sound over-approximation of the actual value, as the assigned value can be \`6\` or \`12\`. After applying the abstract semantics of the addition of \`x\` and \`y\`, the addition operation \`+\` and the variable \`z\` of line 3 are mapped to the interval \`[48, 54]\`, resulting from the addition of the interval \`[42, 42]\` of \`x\` and \`[6, 12]\` of \`y\`.
145
+ `;
146
+ }
147
+ }
148
+ exports.WikiAbsint = WikiAbsint;
149
+ //# sourceMappingURL=wiki-absint.js.map
@@ -112,7 +112,7 @@ The builder provides two methods for building the analyzer:
112
112
 
113
113
  For more information on how to configure the builder, please refer to the [Builder Configuration](#builder-configuration) section below.
114
114
 
115
- ${(0, doc_structure_1.section)('Overview of the Analyzer', 3)}
115
+ ${(0, doc_structure_1.section)('Overview of the Analyzer', 3)}
116
116
 
117
117
  Once you have created an analyzer instance, you can add R files, folders, or even entire projects for analysis using the
118
118
  ${ctx.linkM(flowr_analyzer_1.FlowrAnalyzer, 'addRequest')} method.
@@ -38,6 +38,7 @@ const flowr_analyzer_builder_1 = require("../project/flowr-analyzer-builder");
38
38
  const flowr_analyzer_context_1 = require("../project/context/flowr-analyzer-context");
39
39
  const doc_maker_1 = require("./wiki-mk/doc-maker");
40
40
  const flowr_analyzer_1 = require("../project/flowr-analyzer");
41
+ const built_in_1 = require("../dataflow/environments/built-in");
41
42
  async function subExplanation(parser, { description, code, expectedSubgraph }) {
42
43
  expectedSubgraph = await (0, doc_dfg_1.verifyExpectedSubgraph)(parser, code, expectedSubgraph);
43
44
  const marks = [];
@@ -190,9 +191,9 @@ The related function argument references are defined like this:
190
191
  ${ctx.hierarchy('FunctionArgument')}
191
192
 
192
193
  There is another element of potential interest to you, the \`origin\` property which records how flowR created the respective function call.
193
- These origins may hold the name of any processor that is part of the ${ctx.link('BuiltInProcessorMapper')} to signal that the respective processor was responsible for creating the vertex.
194
- The entry \`function\` signals that flowR used a processor for a user-defined function defined within the source code, \`unnamed\` signals that the function as an anonymous function definition.
195
- However, in general, flowR may use any fitting handler as an origin. For example, within a access definition, flowR will correspondingly redefine the meaning of \`:=\` to that of the \`table:assign\`.
194
+ These origins may hold the name of any processor that is part of the ${ctx.link('BuiltInProcName')} enumeration to signal that the respective processor (cf. ${ctx.link('BuiltInProcessorMapper')}) was responsible for creating the vertex.
195
+ The entry \`${built_in_1.BuiltInProcName.Function}\` signals that flowR used a processor for a user-defined function defined within the source code, \`${built_in_1.BuiltInProcName.Unnamed}\` signals that the function as an anonymous function definition.
196
+ However, in general, flowR may use any fitting handler as an origin (see the ${ctx.link('BuiltInProcName')} enum for a *complete* list). For example, within a access definition, flowR will correspondingly redefine the meaning of \`:=\` to that of the \`${built_in_1.BuiltInProcName.TableAssignment}\`.
196
197
 
197
198
  ${(0, doc_structure_1.details)('Example: Simple Function Call (unresolved)', await (async () => {
198
199
  const code = 'foo(x,3,y=3,)';
@@ -362,7 +363,7 @@ ${(0, doc_structure_1.block)({
362
363
  content: `Now you might be asking yourself how to differentiate anonymous and named functions and what you have to keep in mind when working with them?
363
364
 
364
365
  Unnamed functions have an array of signatures which you can use to identify them.
365
- But in short: the \`origin\` attribute of the ${ctx.link('DataflowGraphVertexFunctionCall')} is \`${unnamed_call_handling_1.UnnamedFunctionCallOrigin}\`.
366
+ But in short: the \`origin\` attribute of the ${ctx.link('DataflowGraphVertexFunctionCall')} is \`${built_in_1.BuiltInProcName.Unnamed}\`.
366
367
  Please be aware that unnamed functions still have a \`name\` property to give it a unique identifier that can be used for debugging and reference.
367
368
  This name _always_ starts with \`${unnamed_call_handling_1.UnnamedFunctionCallPrefix}\`.
368
369
 
@@ -499,7 +500,7 @@ Besides this being a theoretically "shorter" way of defining a function, this be
499
500
 
500
501
  `,
501
502
  code: 'function() 1',
502
- expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().defineFunction('1@function', [0], { hooks: [], graph: new Set('0'), in: [{ nodeId: 0, controlDependencies: [], type: identifier_1.ReferenceType.Constant, name: undefined }], out: [], unknownReferences: [], entryPoint: 0, environment: (0, environment_builder_1.defaultEnv)() })
503
+ expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().defineFunction('1@function', [0], { hooks: [], graph: new Set('0'), in: [{ nodeId: 0, cds: [], type: identifier_1.ReferenceType.Constant, name: undefined }], out: [], unknownReferences: [], entryPoint: 0, environment: (0, environment_builder_1.defaultEnv)() })
503
504
  }, []]);
504
505
  const results = [];
505
506
  let i = 0;
@@ -790,7 +791,7 @@ The following vertices types exist:
790
791
 
791
792
  1. ${(0, doc_data_dfg_util_1.getAllVertices)().map(([k, v], index) => `[\`${k}\`](#${index + 1}-${v.toLowerCase().replace(/\s/g, '-')}-vertex)`).join('\n1. ')}
792
793
 
793
- ${(0, doc_structure_1.details)('Class Diagram', 'All boxes should link to their respective implementation:\n' + (0, doc_code_1.codeBlock)('mermaid', ctx.mermaid('DataflowGraphVertexInfo', ['MergeableRecord'])))}
794
+ ${(0, doc_structure_1.details)('Class Diagram', 'All boxes should link to their respective implementation:\n' + (0, doc_code_1.codeBlock)('mermaid', ctx.mermaid('DataflowGraphVertexInfo', { inlineTypes: ['MergeableRecord'] })))}
794
795
 
795
796
  </details>
796
797
 
@@ -802,7 +803,7 @@ The following edges types exist, internally we use bitmasks to represent multipl
802
803
 
803
804
  1. ${(0, doc_data_dfg_util_1.getAllEdges)().map(([k, v], index) => `[\`${k}\` (${v})](#${index + 1}-${k.toLowerCase().replace(/\s/g, '-')}-edge)`).join('\n1. ')}
804
805
 
805
- ${(0, doc_structure_1.details)('Class Diagram', 'All boxes should link to their respective implementation:\n' + (0, doc_code_1.codeBlock)('mermaid', ctx.mermaid('EdgeType', ['MergeableRecord'])))}
806
+ ${(0, doc_structure_1.details)('Class Diagram', 'All boxes should link to their respective implementation:\n' + (0, doc_code_1.codeBlock)('mermaid', ctx.mermaid('EdgeType', { inlineTypes: ['MergeableRecord'] })))}
806
807
 
807
808
  </details>
808
809
 
@@ -828,7 +829,7 @@ ${(0, doc_general_1.prefixLines)((0, doc_code_1.codeBlock)('ts', `const name = $
828
829
 
829
830
  ${(0, doc_structure_1.section)('Vertices', 2, 'vertices')}
830
831
 
831
- 1. ${(0, doc_data_dfg_util_1.getAllVertices)().map(([k, v]) => `[\`${k}\`](#${v.toLowerCase().replace(/\s/g, '-')}-vertex)`).join('\n1. ')}
832
+ 1. ${(0, doc_data_dfg_util_1.getAllVertices)().map(([k, v]) => `[\`${k}\`](#${v.toLowerCase().replaceAll(/\s/g, '-')}-vertex)`).join('\n1. ')}
832
833
 
833
834
  ${await getVertexExplanations(treeSitter, ctx)}
834
835
 
@@ -906,7 +907,7 @@ Let's start by looking at the properties of the dataflow information object: ${O
906
907
 
907
908
  ${(() => {
908
909
  /* this includes the meta field for timing and the quick CFG in order to enable re-use and improve performance */
909
- (0, assert_1.guard)(Object.keys(result).length === 9, () => 'Update Dataflow Documentation!');
910
+ (0, assert_1.guard)(Object.keys(result).length === 10, () => 'Update Dataflow Documentation! (Keys: ' + Object.keys(result).join(', ') + ')');
910
911
  return '';
911
912
  })()}
912
913
 
@@ -1043,7 +1044,7 @@ ${await (async () => {
1043
1044
  return '`' + wanted.types + '`';
1044
1045
  }
1045
1046
  }
1046
- new Error('Could not find edge');
1047
+ throw new Error('Could not find edge');
1047
1048
  })()}&mdash;which is usually not very helpful.
1048
1049
  You can use ${ctx.link(edge_1.splitEdgeTypes.name)} to get the individual bitmasks of all included types, and
1049
1050
  ${ctx.link(edge_1.edgeIncludesType.name)} to check whether a specific type (or one of a collection of types) is included in the edge.
@@ -1058,7 +1059,7 @@ ${ctx.hierarchy('Origin', { openTop: true })}
1058
1059
 
1059
1060
  Their respective uses are documented alongside their implementation:
1060
1061
 
1061
- ${['SimpleOrigin', 'FunctionCallOrigin', 'BuiltInFunctionOrigin'].sort().map(key => `- ${ctx.link(key)}\\\n${ctx.doc(key, { type: 'interface' })}`).join('\n')}
1062
+ ${['SimpleOrigin', 'FunctionCallOrigin', 'BuiltInFunctionOrigin'].sort((a, b) => a.localeCompare(b)).map(key => `- ${ctx.link(key)}\\\n${ctx.doc(key, { type: 'interface' })}`).join('\n')}
1062
1063
 
1063
1064
  Please note, the current structure of this function is biased by what implementations already exist in flowR.
1064
1065
  Hence, we do not just track definitions and constants, but also the origins of function calls, albeit we do not yet track the origins of values (only resorting to
@@ -21,6 +21,7 @@ const doc_structure_1 = require("./doc-util/doc-structure");
21
21
  const tree_sitter_executor_1 = require("../r-bridge/lang-4.x/tree-sitter/tree-sitter-executor");
22
22
  const flowr_analyzer_1 = require("../project/flowr-analyzer");
23
23
  const doc_maker_1 = require("./wiki-mk/doc-maker");
24
+ const built_in_1 = require("../dataflow/environments/built-in");
24
25
  async function explainServer(parser) {
25
26
  (0, doc_data_server_messages_1.documentAllServerMessages)();
26
27
  return `
@@ -235,7 +236,7 @@ ${(0, doc_code_1.codeBlock)('json', JSON.stringify({
235
236
  environment: {
236
237
  overwriteBuiltIns: {
237
238
  definitions: [
238
- { type: 'function', names: ['foo'], processor: 'builtin:assignment', config: {} }
239
+ { type: 'function', names: ['foo'], processor: built_in_1.BuiltInProcName.Assignment, config: {} }
239
240
  ]
240
241
  }
241
242
  }
@@ -1,4 +1,4 @@
1
- import type { FnElementInfo, PrintHierarchyArguments, TypeElementKind } from '../doc-util/doc-types';
1
+ import type { FnElementInfo, MermaidClassDiagramArguments, PrintHierarchyArguments, TypeElementKind } from '../doc-util/doc-types';
2
2
  import type { RShell } from '../../r-bridge/shell';
3
3
  import type { ValidWikiDocumentTargetsNoSuffix } from '../../cli/wiki';
4
4
  import type { PathLike } from 'fs';
@@ -174,9 +174,9 @@ export interface GeneralDocContext {
174
174
  /**
175
175
  * Generates a mermaid diagram for the given code element, returned as markdown string.
176
176
  * @param element - The element to create a mermaid diagram for, the name can be qualified with `::` to specify the class.
177
- * @param inlineTypes - Optional list of type names to inline in the mermaid diagram (instead of linking them out).
177
+ * @param options - Formatting options for the mermaid class diagram (see {@link MermaidClassDiagramArguments})
178
178
  */
179
- mermaid(element: ElementIdOrRef, inlineTypes?: string[]): string;
179
+ mermaid(element: ElementIdOrRef, options?: MermaidClassDiagramArguments): string;
180
180
  /**
181
181
  * Generates a wiki link to another wiki or general docs page.
182
182
  * @example
@@ -75,10 +75,10 @@ function makeDocContextForTypes(shell, ...rootFolders) {
75
75
  const rVersion = (await shell?.usedRVersion())?.format();
76
76
  return (0, doc_auto_gen_1.autoGenHeader)({ filename, purpose, rVersion });
77
77
  },
78
- mermaid(element, inlineTypes = doc_types_1.mermaidHide) {
78
+ mermaid(element, options) {
79
79
  return (0, doc_types_1.visualizeMermaidClassDiagram)(info, {
80
80
  typeNameForMermaid: getNameFromElementIdOrRef(element),
81
- inlineTypes
81
+ ...options
82
82
  });
83
83
  },
84
84
  linkPage(pageName, linkText, segment) {
@@ -9,9 +9,9 @@ var WikiChangeType;
9
9
  })(WikiChangeType || (exports.WikiChangeType = WikiChangeType = {}));
10
10
  const DefaultReplacementPatterns = [
11
11
  // eslint-disable-next-line no-irregular-whitespace -- we may produce it in output
12
- [/[0-9]+(\.[0-9]+)?( |\s*)?ms/g, ''],
12
+ [/\d+(\.\d+)?( |\s*)?ms/g, ''],
13
13
  [/tmp[%A-Za-z0-9-]+/g, ''],
14
- [/"?(timing|searchTimeMs|processTimeMs|id|treeSitterId)"?:\s*[0-9]+(\.[0-9])?,?/g, ''],
14
+ [/"?(timing|searchTimeMs|processTimeMs|id|treeSitterId)"?:\s*\d+(\.\d)?,?/g, ''],
15
15
  [/"format":"compact".+/gmius, ''],
16
16
  [/%%\s*\d*-+/g, ''],
17
17
  [/"[rR]": "\d+\.\d+\.\d+.*?"/g, ''],
@@ -1,5 +1,14 @@
1
+ import { DefaultNormalizedAstFold } from '../abstract-interpretation/normalized-ast-fold';
1
2
  import type { DocMakerArgs } from './wiki-mk/doc-maker';
2
3
  import { DocMaker } from './wiki-mk/doc-maker';
4
+ import type { RNumber } from '../r-bridge/lang-4.x/ast/model/nodes/r-number';
5
+ import type { RBinaryOp } from '../r-bridge/lang-4.x/ast/model/nodes/r-binary-op';
6
+ export declare class MyMathFold<Info> extends DefaultNormalizedAstFold<number, Info> {
7
+ constructor();
8
+ protected concat(a: number, b: number): number;
9
+ foldRNumber(node: RNumber<Info>): number;
10
+ foldRBinaryOp(node: RBinaryOp<Info>): number;
11
+ }
3
12
  /**
4
13
  * https://github.com/flowr-analysis/flowr/wiki/Normalized-AST
5
14
  */