@eagleoutice/flowr 2.9.9 → 2.9.11

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 (198) hide show
  1. package/README.md +57 -54
  2. package/abstract-interpretation/absint-visitor.d.ts +16 -14
  3. package/abstract-interpretation/absint-visitor.js +93 -47
  4. package/abstract-interpretation/data-frame/mappers/arguments.d.ts +1 -1
  5. package/abstract-interpretation/data-frame/mappers/arguments.js +2 -2
  6. package/abstract-interpretation/data-frame/shape-inference.d.ts +2 -5
  7. package/abstract-interpretation/data-frame/shape-inference.js +4 -5
  8. package/abstract-interpretation/domains/abstract-domain.d.ts +4 -4
  9. package/abstract-interpretation/domains/abstract-domain.js +8 -8
  10. package/abstract-interpretation/domains/mapped-abstract-domain.d.ts +12 -5
  11. package/abstract-interpretation/domains/mapped-abstract-domain.js +47 -23
  12. package/abstract-interpretation/domains/set-range-domain.js +1 -1
  13. package/abstract-interpretation/domains/state-abstract-domain.d.ts +30 -1
  14. package/abstract-interpretation/domains/state-abstract-domain.js +130 -4
  15. package/abstract-interpretation/normalized-ast-fold.d.ts +2 -2
  16. package/abstract-interpretation/normalized-ast-fold.js +4 -3
  17. package/benchmark/slicer.js +5 -5
  18. package/benchmark/summarizer/first-phase/process.js +4 -4
  19. package/cli/repl/commands/repl-normalize.js +2 -2
  20. package/cli/repl/core.js +2 -2
  21. package/config.js +1 -1
  22. package/control-flow/cfg-simplification.d.ts +1 -0
  23. package/control-flow/cfg-simplification.js +1 -0
  24. package/control-flow/control-flow-graph.d.ts +1 -1
  25. package/control-flow/control-flow-graph.js +1 -2
  26. package/control-flow/extract-cfg.js +34 -15
  27. package/control-flow/semantic-cfg-guided-visitor.js +1 -0
  28. package/dataflow/cluster.js +1 -1
  29. package/dataflow/environments/built-in.d.ts +6 -15
  30. package/dataflow/environments/built-in.js +25 -33
  31. package/dataflow/environments/default-builtin-config.d.ts +4 -8
  32. package/dataflow/environments/default-builtin-config.js +8 -5
  33. package/dataflow/environments/reference-to-maybe.d.ts +8 -0
  34. package/dataflow/environments/reference-to-maybe.js +46 -3
  35. package/dataflow/eval/resolve/alias-tracking.d.ts +2 -2
  36. package/dataflow/eval/resolve/alias-tracking.js +6 -6
  37. package/dataflow/eval/resolve/resolve.js +12 -10
  38. package/dataflow/fn/exceptions-of-function.d.ts +1 -1
  39. package/dataflow/fn/exceptions-of-function.js +2 -1
  40. package/dataflow/graph/call-graph.d.ts +1 -1
  41. package/dataflow/graph/call-graph.js +4 -3
  42. package/dataflow/graph/dataflowgraph-builder.d.ts +1 -1
  43. package/dataflow/graph/dataflowgraph-builder.js +21 -21
  44. package/dataflow/graph/graph.d.ts +5 -5
  45. package/dataflow/graph/graph.js +36 -32
  46. package/dataflow/graph/unknown-side-effect.js +3 -1
  47. package/dataflow/info.d.ts +4 -0
  48. package/dataflow/info.js +2 -2
  49. package/dataflow/internal/linker.d.ts +4 -4
  50. package/dataflow/internal/linker.js +59 -33
  51. package/dataflow/internal/process/functions/call/argument/make-argument.d.ts +2 -1
  52. package/dataflow/internal/process/functions/call/argument/make-argument.js +3 -1
  53. package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +1 -1
  54. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +2 -1
  55. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +3 -5
  56. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.d.ts +1 -1
  57. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +6 -5
  58. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +15 -6
  59. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +1 -1
  60. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +3 -2
  61. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +4 -4
  62. package/dataflow/internal/process/functions/call/built-in/built-in-local.js +3 -3
  63. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +2 -2
  64. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +1 -1
  65. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +2 -1
  66. package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.js +7 -7
  67. package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.js +3 -3
  68. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +22 -11
  69. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +22 -19
  70. package/dataflow/internal/process/functions/call/common.d.ts +1 -1
  71. package/dataflow/internal/process/functions/call/common.js +43 -35
  72. package/dataflow/internal/process/functions/call/known-call-handling.js +0 -2
  73. package/dataflow/internal/process/functions/process-argument.d.ts +1 -1
  74. package/dataflow/internal/process/functions/process-argument.js +3 -3
  75. package/dataflow/internal/process/functions/process-parameter.js +2 -2
  76. package/dataflow/origin/dfg-get-origin.d.ts +1 -1
  77. package/dataflow/origin/dfg-get-origin.js +2 -2
  78. package/documentation/doc-util/doc-types.js +1 -1
  79. package/documentation/wiki-absint.js +7 -8
  80. package/documentation/wiki-cfg.js +3 -3
  81. package/documentation/wiki-mk/doc-context.d.ts +8 -0
  82. package/documentation/wiki-mk/doc-context.js +4 -0
  83. package/documentation/wiki-normalized-ast.d.ts +1 -1
  84. package/documentation/wiki-normalized-ast.js +9 -6
  85. package/linter/linter-format.d.ts +10 -0
  86. package/linter/linter-format.js +15 -0
  87. package/linter/rules/absolute-path.js +3 -3
  88. package/linter/rules/dead-code.js +1 -1
  89. package/linter/rules/file-path-validity.js +1 -1
  90. package/linter/rules/seeded-randomness.js +1 -1
  91. package/linter/rules/unused-definition.js +1 -1
  92. package/package.json +7 -7
  93. package/project/plugins/file-plugins/files/flowr-description-file.d.ts +9 -0
  94. package/project/plugins/file-plugins/files/flowr-description-file.js +12 -0
  95. package/queries/catalog/call-context-query/call-context-query-executor.js +1 -1
  96. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +1 -1
  97. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +4 -5
  98. package/queries/catalog/dependencies-query/dependencies-query-executor.js +2 -1
  99. package/queries/catalog/dependencies-query/dependencies-query-format.js +6 -5
  100. package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +1 -1
  101. package/queries/catalog/df-shape-query/df-shape-query-format.js +3 -3
  102. package/queries/catalog/does-call-query/does-call-query-executor.js +3 -3
  103. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +1 -1
  104. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.js +2 -2
  105. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +1 -1
  106. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.js +1 -1
  107. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +1 -1
  108. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.js +1 -1
  109. package/queries/query-print.d.ts +1 -1
  110. package/queries/query-print.js +4 -3
  111. package/r-bridge/lang-4.x/ast/model/model.d.ts +151 -4
  112. package/r-bridge/lang-4.x/ast/model/model.js +249 -0
  113. package/r-bridge/lang-4.x/ast/model/nodes/info/r-delimiter.d.ts +11 -1
  114. package/r-bridge/lang-4.x/ast/model/nodes/info/r-delimiter.js +13 -0
  115. package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +19 -1
  116. package/r-bridge/lang-4.x/ast/model/nodes/r-access.js +26 -0
  117. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +36 -3
  118. package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +48 -13
  119. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +16 -1
  120. package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.js +21 -0
  121. package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +11 -1
  122. package/r-bridge/lang-4.x/ast/model/nodes/r-break.js +14 -0
  123. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +8 -2
  124. package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +11 -5
  125. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +23 -1
  126. package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.js +32 -0
  127. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +11 -1
  128. package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.js +14 -0
  129. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +19 -1
  130. package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.js +26 -1
  131. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +11 -1
  132. package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +14 -0
  133. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +11 -1
  134. package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.js +14 -0
  135. package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +12 -2
  136. package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.js +14 -0
  137. package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +20 -2
  138. package/r-bridge/lang-4.x/ast/model/nodes/r-logical.js +26 -0
  139. package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +12 -2
  140. package/r-bridge/lang-4.x/ast/model/nodes/r-next.js +14 -0
  141. package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +8 -2
  142. package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +11 -5
  143. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +17 -1
  144. package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.js +22 -0
  145. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +16 -1
  146. package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +22 -0
  147. package/r-bridge/lang-4.x/ast/model/nodes/r-project.d.ts +45 -8
  148. package/r-bridge/lang-4.x/ast/model/nodes/r-project.js +57 -16
  149. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +12 -2
  150. package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.js +14 -0
  151. package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +15 -3
  152. package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +21 -6
  153. package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +21 -6
  154. package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.js +22 -5
  155. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +16 -1
  156. package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.js +21 -0
  157. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +11 -1
  158. package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.js +14 -0
  159. package/r-bridge/lang-4.x/ast/model/processing/decorate.js +23 -17
  160. package/r-bridge/lang-4.x/ast/model/processing/node-id.d.ts +39 -2
  161. package/r-bridge/lang-4.x/ast/model/processing/node-id.js +52 -9
  162. package/r-bridge/lang-4.x/ast/model/processing/role.d.ts +18 -17
  163. package/r-bridge/lang-4.x/ast/model/processing/visitor.d.ts +8 -7
  164. package/r-bridge/lang-4.x/ast/model/processing/visitor.js +6 -13
  165. package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +1 -1
  166. package/r-bridge/lang-4.x/ast/parser/json/parser.js +1 -1
  167. package/r-bridge/lang-4.x/ast/parser/main/internal/expression/normalize-expression.js +4 -2
  168. package/r-bridge/lang-4.x/ast/parser/main/internal/values/normalize-number.js +1 -1
  169. package/r-bridge/lang-4.x/ast/parser/main/internal/values/normalize-string.js +2 -2
  170. package/r-bridge/lang-4.x/convert-values.d.ts +14 -5
  171. package/r-bridge/lang-4.x/convert-values.js +76 -72
  172. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +33 -15
  173. package/r-bridge/roxygen2/roxygen-parse.js +1 -1
  174. package/r-bridge/shell-executor.js +1 -1
  175. package/reconstruct/auto-select/magic-comments.js +4 -4
  176. package/reconstruct/reconstruct.js +2 -1
  177. package/search/search-executor/search-generators.js +2 -2
  178. package/slicing/criterion/filters/all-variables.js +1 -1
  179. package/slicing/criterion/parse.d.ts +1 -1
  180. package/slicing/criterion/parse.js +5 -3
  181. package/slicing/static/slice-call.d.ts +1 -1
  182. package/slicing/static/slice-call.js +2 -2
  183. package/statistics/features/supported/assignments/assignments.js +2 -2
  184. package/statistics/features/supported/control-flow/control-flow.js +2 -2
  185. package/statistics/features/supported/data-access/data-access.js +6 -5
  186. package/statistics/features/supported/defined-functions/defined-functions.js +9 -8
  187. package/statistics/features/supported/expression-list/statistics-expression-list.js +2 -2
  188. package/statistics/features/supported/loops/loops.js +6 -5
  189. package/statistics/features/supported/used-functions/used-functions.js +2 -2
  190. package/statistics/features/supported/variables/variables.js +8 -8
  191. package/util/mermaid/ast.js +3 -3
  192. package/util/mermaid/cfg.js +3 -4
  193. package/util/mermaid/dfg.d.ts +1 -1
  194. package/util/mermaid/dfg.js +13 -12
  195. package/util/simple-df/dfg-ascii.js +1 -1
  196. package/util/version.js +1 -1
  197. package/r-bridge/lang-4.x/ast/model/collect.d.ts +0 -10
  198. package/r-bridge/lang-4.x/ast/model/collect.js +0 -25
@@ -7,10 +7,10 @@ const known_call_handling_1 = require("../known-call-handling");
7
7
  const linker_1 = require("../../../../linker");
8
8
  const common_1 = require("../common");
9
9
  const unpack_argument_1 = require("../argument/unpack-argument");
10
- const r_argument_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument");
11
10
  const scoping_1 = require("../../../../../environments/scoping");
12
11
  const built_in_1 = require("../../../../../environments/built-in");
13
12
  const identifier_1 = require("../../../../../environments/identifier");
13
+ const r_argument_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument");
14
14
  /**
15
15
  * Processes a built-in 'local' function call.
16
16
  */
@@ -24,8 +24,8 @@ function processLocal(name, args, rootId, data, config) {
24
24
  '...': '...'
25
25
  };
26
26
  const argMaps = (0, linker_1.invertArgumentMap)((0, linker_1.pMatch)((0, common_1.convertFnArguments)(args), params));
27
- const env = (0, unpack_argument_1.unpackArg)((0, r_argument_1.getArgumentWithId)(args, argMaps.get('env')?.[0]));
28
- const expr = (0, unpack_argument_1.unpackArg)((0, r_argument_1.getArgumentWithId)(args, argMaps.get('expr')?.[0]));
27
+ const env = (0, unpack_argument_1.unpackArg)(r_argument_1.RArgument.getWithId(args, argMaps.get('env')?.[0]));
28
+ const expr = (0, unpack_argument_1.unpackArg)(r_argument_1.RArgument.getWithId(args, argMaps.get('expr')?.[0]));
29
29
  if (!expr) {
30
30
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
31
31
  }
@@ -41,8 +41,8 @@ function processRepeatLoop(name, args, rootId, data) {
41
41
  });
42
42
  const body = processedArguments[0];
43
43
  (0, assert_1.guard)(body !== undefined, () => `Repeat-Loop ${identifier_1.Identifier.toString(name.content)} has no body, impossible!`);
44
- (0, linker_1.linkCircularRedefinitionsWithinALoop)(information.graph, (0, linker_1.produceNameSharedIdMap)((0, linker_1.findNonLocalReads)(information.graph, [])), body.out);
45
- (0, linker_1.reapplyLoopExitPoints)(body.exitPoints, body.in.concat(body.out, body.unknownReferences));
44
+ (0, linker_1.linkCircularRedefinitionsWithinALoop)(information.graph, (0, linker_1.produceNameSharedIdMap)((0, linker_1.findNonLocalReads)(information.graph)), body.out);
45
+ (0, linker_1.reapplyLoopExitPoints)(body.exitPoints, body.in.concat(body.out, body.unknownReferences), information.graph);
46
46
  information.exitPoints = (0, info_1.filterOutLoopExitPoints)(information.exitPoints);
47
47
  return information;
48
48
  }
@@ -4,7 +4,7 @@ import { type ForceArguments } from '../common';
4
4
  import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
5
5
  import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
6
6
  import { type RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
7
- import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
7
+ import { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
8
8
  /**
9
9
  * Process a replacement function call like `<-`, `[[<-`, `$<-`, etc.
10
10
  * These are automatically created when doing assignments like `x[y] <- value` or in general `fun(x) <- value` will call `fun<- (x, value)`.
@@ -6,6 +6,7 @@ const known_call_handling_1 = require("../known-call-handling");
6
6
  const log_1 = require("../../../../../../util/log");
7
7
  const common_1 = require("../common");
8
8
  const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
9
+ const node_id_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id");
9
10
  const logger_1 = require("../../../../../logger");
10
11
  const vertex_1 = require("../../../../../graph/vertex");
11
12
  const edge_1 = require("../../../../../graph/edge");
@@ -110,7 +111,7 @@ args, rootId, data, config) {
110
111
  fn.type = identifier_1.ReferenceType.S3MethodPrefix;
111
112
  }
112
113
  // link the built-in replacement op
113
- res.graph.addEdge(rootId, (0, built_in_1.builtInId)(identifier_1.Identifier.getName(name.content)), edge_1.EdgeType.Calls | edge_1.EdgeType.Reads);
114
+ res.graph.addEdge(rootId, node_id_1.NodeId.toBuiltIn(identifier_1.Identifier.getName(name.content)), edge_1.EdgeType.Calls | edge_1.EdgeType.Reads);
114
115
  return res;
115
116
  }
116
117
  //# sourceMappingURL=built-in-replacement.js.map
@@ -33,7 +33,7 @@ function processS7NewGeneric(name, args, rootId, data, config) {
33
33
  params[config.args.fun] = 'fun';
34
34
  params['...'] = '...';
35
35
  const argMaps = (0, linker_1.invertArgumentMap)((0, linker_1.pMatch)((0, common_1.convertFnArguments)(args), params));
36
- const genName = (0, unpack_argument_1.unpackArg)((0, r_argument_1.getArgumentWithId)(args, argMaps.get('name')?.[0]));
36
+ const genName = (0, unpack_argument_1.unpackArg)(r_argument_1.RArgument.getWithId(args, argMaps.get('name')?.[0]));
37
37
  if (!genName) {
38
38
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
39
39
  }
@@ -51,10 +51,10 @@ function processS7NewGeneric(name, args, rootId, data, config) {
51
51
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
52
52
  }
53
53
  data = { ...data, currentS7name: accessedIdentifiers };
54
- let funArg = (0, unpack_argument_1.unpackArg)((0, r_argument_1.getArgumentWithId)(args, argMaps.get('fun')?.[0]))?.info.id;
54
+ let funArg = (0, unpack_argument_1.unpackArg)(r_argument_1.RArgument.getWithId(args, argMaps.get('fun')?.[0]))?.info.id;
55
55
  const effectiveArgs = args.slice();
56
56
  if (!funArg) {
57
- const dispatchArg = (0, unpack_argument_1.unpackArg)((0, r_argument_1.getArgumentWithId)(args, argMaps.get('dispatchArg')?.[0]));
57
+ const dispatchArg = (0, unpack_argument_1.unpackArg)(r_argument_1.RArgument.getWithId(args, argMaps.get('dispatchArg')?.[0]));
58
58
  const newFun = makeS7DispatchFDef(name, [dispatchArg?.lexeme ?? undefined], rootId, args.length, data.completeAst.idMap);
59
59
  // fake it 'function([dispatch_args],...) S7_dispatch()'
60
60
  effectiveArgs.push(newFun[0]);
@@ -80,7 +80,7 @@ function makeS7DispatchFDef(name, names, rootId, args, idMap) {
80
80
  info: {
81
81
  id: argNameId,
82
82
  nesting: name.info.nesting,
83
- role: "arg-name" /* RoleInParent.ArgumentName */,
83
+ role: "arg-n" /* RoleInParent.ArgumentName */,
84
84
  fullRange: r,
85
85
  adToks: undefined,
86
86
  file: name.info.file,
@@ -117,7 +117,7 @@ function makeS7DispatchFDef(name, names, rootId, args, idMap) {
117
117
  info: {
118
118
  id: rootId + '-s7-new-generic-fun-body',
119
119
  nesting: name.info.nesting,
120
- role: "fun-body" /* RoleInParent.FunctionDefinitionBody */,
120
+ role: "fun-b" /* RoleInParent.FunctionDefinitionBody */,
121
121
  fullRange: r,
122
122
  adToks: undefined,
123
123
  file: name.info.file,
@@ -132,7 +132,7 @@ function makeS7DispatchFDef(name, names, rootId, args, idMap) {
132
132
  file: name.info.file,
133
133
  id: fdefId,
134
134
  nesting: name.info.nesting,
135
- role: "arg-value" /* RoleInParent.ArgumentValue */,
135
+ role: "arg-v" /* RoleInParent.ArgumentValue */,
136
136
  parent: rootId,
137
137
  index: args + 1,
138
138
  adToks: undefined,
@@ -150,7 +150,7 @@ function makeS7DispatchFDef(name, names, rootId, args, idMap) {
150
150
  info: {
151
151
  id: paramNameId,
152
152
  nesting: name.info.nesting,
153
- role: "param-name" /* RoleInParent.ParameterName */,
153
+ role: "param-n" /* RoleInParent.ParameterName */,
154
154
  fullRange: r,
155
155
  adToks: undefined,
156
156
  file: name.info.file,
@@ -8,13 +8,13 @@ const logger_1 = require("../../../../../logger");
8
8
  const built_in_1 = require("../../../../../environments/built-in");
9
9
  const linker_1 = require("../../../../linker");
10
10
  const common_1 = require("../common");
11
- const r_argument_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument");
12
11
  const unpack_argument_1 = require("../argument/unpack-argument");
13
12
  const alias_tracking_1 = require("../../../../../eval/resolve/alias-tracking");
14
13
  const r_value_1 = require("../../../../../eval/values/r-value");
15
14
  const identifier_1 = require("../../../../../environments/identifier");
16
15
  const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
17
16
  const range_1 = require("../../../../../../util/range");
17
+ const r_argument_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument");
18
18
  /**
19
19
  * Process an S3 dispatch call like `UseMethod`.
20
20
  */
@@ -29,11 +29,11 @@ function processS3Dispatch(name, args, rootId, data, config) {
29
29
  '...': '...'
30
30
  };
31
31
  const argMaps = (0, linker_1.invertArgumentMap)((0, linker_1.pMatch)((0, common_1.convertFnArguments)(args), params));
32
- const generic = (0, unpack_argument_1.unpackArg)((0, r_argument_1.getArgumentWithId)(args, argMaps.get('generic')?.[0]));
32
+ const generic = (0, unpack_argument_1.unpackArg)(r_argument_1.RArgument.getWithId(args, argMaps.get('generic')?.[0]));
33
33
  if (!generic && !config.inferFromClosure) {
34
34
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
35
35
  }
36
- const obj = (0, unpack_argument_1.unpackArg)((0, r_argument_1.getArgumentWithId)(args, argMaps.get('object')?.[0]));
36
+ const obj = (0, unpack_argument_1.unpackArg)(r_argument_1.RArgument.getWithId(args, argMaps.get('object')?.[0]));
37
37
  const dfObj = obj ? (0, processor_1.processDataflowFor)(obj, data) : (0, info_1.initializeCleanDataflowInformation)(rootId, data);
38
38
  if ((0, info_1.alwaysExits)(dfObj)) {
39
39
  (0, common_1.patchFunctionCall)({
@@ -155,19 +155,30 @@ function processSourceCall(name, args, rootId, data, config) {
155
155
  if (sourceFile?.length === 1) {
156
156
  const path = (0, retriever_1.removeRQuotes)(sourceFile[0]);
157
157
  let filepath = path ? findSource(data.ctx.config.solver.resolveSource, path, data) : path;
158
- if (Array.isArray(filepath)) {
159
- filepath = filepath?.[0];
158
+ if (!Array.isArray(filepath)) {
159
+ filepath = filepath ? [filepath] : undefined;
160
160
  }
161
- if (filepath !== undefined) {
162
- // check if the sourced file has already been dataflow analyzed, and if so, skip it
163
- const limit = data.ctx.config.solver.resolveSource?.repeatedSourceLimit ?? 0;
164
- const findCount = data.referenceChain.filter(e => e !== undefined && filepath === e).length;
165
- if (findCount > limit) {
166
- logger_1.dataflowLogger.warn(`Found cycle (>=${limit + 1}) in dataflow analysis for ${JSON.stringify(filepath)}: ${JSON.stringify(data.referenceChain)}, skipping further dataflow analysis`);
167
- (0, unknown_side_effect_1.handleUnknownSideEffect)(information.graph, information.environment, rootId);
168
- return information;
161
+ if (filepath !== undefined && filepath.length > 0) {
162
+ let result = information;
163
+ const origCds = data.cds?.slice() ?? [];
164
+ for (const f of filepath) {
165
+ // check if the sourced file has already been dataflow analyzed, and if so, skip it
166
+ const limit = data.ctx.config.solver.resolveSource?.repeatedSourceLimit ?? 0;
167
+ const findCount = data.referenceChain.filter(e => e !== undefined && f === e).length;
168
+ if (findCount > limit) {
169
+ logger_1.dataflowLogger.warn(`Found cycle (>=${limit + 1}) in dataflow analysis for ${JSON.stringify(filepath)}: ${JSON.stringify(data.referenceChain)}, skipping further dataflow analysis`);
170
+ (0, unknown_side_effect_1.handleUnknownSideEffect)(result.graph, result.environment, rootId);
171
+ continue;
172
+ }
173
+ if (filepath.length > 1) {
174
+ data = { ...data, cds: [...origCds, { id: rootId, when: true, file: f }] };
175
+ }
176
+ result = sourceRequest(rootId, {
177
+ request: 'file',
178
+ content: f
179
+ }, data, result, (0, decorate_1.sourcedDeterministicCountingIdGenerator)((findCount > 0 ? findCount + '::' : '') + f, name.location));
169
180
  }
170
- return sourceRequest(rootId, { request: 'file', content: filepath }, data, information, (0, decorate_1.sourcedDeterministicCountingIdGenerator)((findCount > 0 ? findCount + '::' : '') + path, name.location));
181
+ return result;
171
182
  }
172
183
  }
173
184
  (0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Non-constant argument ${JSON.stringify(sourceFile)} for source is currently not supported, skipping`);
@@ -14,6 +14,7 @@ const general_1 = require("../../../../../eval/values/general");
14
14
  const alias_tracking_1 = require("../../../../../eval/resolve/alias-tracking");
15
15
  const reference_to_maybe_1 = require("../../../../../environments/reference-to-maybe");
16
16
  const built_in_1 = require("../../../../../environments/built-in");
17
+ const append_1 = require("../../../../../environments/append");
17
18
  /**
18
19
  * Process a while loop like `while(cond) { ... }`.
19
20
  */
@@ -27,6 +28,8 @@ function processWhileLoop(name, args, rootId, data) {
27
28
  logger_1.dataflowLogger.warn(`While-Loop ${identifier_1.Identifier.toString(name.content)} has empty arguments in ${JSON.stringify(args)}, skipping`);
28
29
  return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
29
30
  }
31
+ const nameId = name.info.id;
32
+ const origEnv = data.environment;
30
33
  // we should defer this to the abstract interpretation
31
34
  const values = (0, alias_tracking_1.resolveIdToValue)(unpackedArgs[0]?.info.id, { environment: data.environment, idMap: data.completeAst.idMap, resolve: data.ctx.config.solver.variables, ctx: data.ctx });
32
35
  const conditionIsAlwaysFalse = (0, general_1.valueSetGuard)(values)?.elements.every(d => d.type === 'logical' && d.value === false) ?? false;
@@ -41,49 +44,49 @@ function processWhileLoop(name, args, rootId, data) {
41
44
  rootId,
42
45
  data,
43
46
  markAsNSE: [1],
44
- patchData: (d, i) => {
45
- if (i === 1) {
46
- return { ...d, cds: [...d.cds ?? [], { id: name.info.id, when: true }] };
47
- }
48
- return d;
49
- }, origin: built_in_1.BuiltInProcName.WhileLoop
47
+ origin: built_in_1.BuiltInProcName.WhileLoop
50
48
  });
51
49
  const [condition, body] = processedArguments;
52
50
  // If the condition is always false, we don't include the body
53
51
  if (condition !== undefined && conditionIsAlwaysFalse) {
54
- information.graph.addEdge(name.info.id, condition.entryPoint, edge_1.EdgeType.Reads);
52
+ information.graph.addEdge(nameId, condition.entryPoint, edge_1.EdgeType.Reads);
55
53
  return {
56
54
  unknownReferences: [],
57
- in: [{ nodeId: name.info.id, name: name.lexeme, cds: data.cds, type: identifier_1.ReferenceType.Function }],
55
+ in: [{ nodeId: nameId, name: name.lexeme, cds: data.cds, type: identifier_1.ReferenceType.Function }],
58
56
  out: condition.out,
59
- entryPoint: name.info.id,
57
+ entryPoint: nameId,
60
58
  exitPoints: [],
61
59
  graph: information.graph,
62
60
  environment: information.environment,
63
61
  hooks: condition.hooks
64
62
  };
65
63
  }
64
+ const conditionIsAlwaysTrue = (0, general_1.valueSetGuard)(values)?.elements.every(d => d.type === 'logical' && d.value === true) ?? false;
66
65
  (0, assert_1.guard)(condition !== undefined && body !== undefined, () => `While-Loop ${identifier_1.Identifier.toString(name.content)} has no condition or body, impossible!`);
67
66
  const originalDependency = data.cds;
68
67
  if ((0, info_1.alwaysExits)(condition)) {
69
68
  logger_1.dataflowLogger.warn(`While-Loop ${rootId} forces exit in condition, skipping rest`);
70
- information.graph.addEdge(name.info.id, condition.entryPoint, edge_1.EdgeType.Reads);
69
+ information.graph.addEdge(nameId, condition.entryPoint, edge_1.EdgeType.Reads);
71
70
  return condition;
72
71
  }
73
- const cdTrue = [{ id: name.info.id, when: true }];
74
- const remainingInputs = (0, linker_1.linkInputs)((0, reference_to_maybe_1.makeAllMaybe)(body.unknownReferences, information.graph, information.environment, false, cdTrue).concat((0, reference_to_maybe_1.makeAllMaybe)(body.in, information.graph, information.environment, false, cdTrue)), information.environment, condition.in.concat(condition.unknownReferences), information.graph, true);
75
- (0, linker_1.linkCircularRedefinitionsWithinALoop)(information.graph, (0, linker_1.produceNameSharedIdMap)((0, linker_1.findNonLocalReads)(information.graph, condition.in)), body.out);
76
- (0, linker_1.reapplyLoopExitPoints)(body.exitPoints, body.in.concat(body.out, body.unknownReferences));
72
+ const cdTrue = [{ id: nameId, when: true }];
73
+ const bodyRead = body.in.concat(body.unknownReferences);
74
+ (0, reference_to_maybe_1.applyCdsToAllInGraphButConstants)(body.graph, bodyRead, cdTrue);
75
+ const remainingInputs = (0, linker_1.linkInputs)(bodyRead, information.environment, condition.in.concat(condition.unknownReferences), information.graph, true);
76
+ (0, reference_to_maybe_1.applyCdToReferences)(body.out, cdTrue);
77
+ (0, linker_1.linkCircularRedefinitionsWithinALoop)(information.graph, (0, linker_1.produceNameSharedIdMap)((0, linker_1.findNonLocalReads)(information.graph, new Set(condition.in.map(i => i.nodeId)))), body.out);
78
+ (0, linker_1.reapplyLoopExitPoints)(body.exitPoints, body.in.concat(body.out, body.unknownReferences), information.graph);
77
79
  // as the while-loop always evaluates its condition
78
- information.graph.addEdge(name.info.id, condition.entryPoint, edge_1.EdgeType.Reads);
80
+ information.graph.addEdge(nameId, condition.entryPoint, edge_1.EdgeType.Reads);
79
81
  return {
80
82
  unknownReferences: [],
81
- in: [{ nodeId: name.info.id, name: name.lexeme, cds: originalDependency, type: identifier_1.ReferenceType.Function }, ...remainingInputs],
82
- out: condition.out.concat((0, reference_to_maybe_1.makeAllMaybe)(body.out, information.graph, information.environment, true, cdTrue)),
83
- entryPoint: name.info.id,
83
+ in: [{ nodeId: nameId, name: name.lexeme, cds: originalDependency, type: identifier_1.ReferenceType.Function }, ...remainingInputs],
84
+ out: condition.out.concat(body.out),
85
+ entryPoint: nameId,
84
86
  exitPoints: (0, info_1.filterOutLoopExitPoints)(body.exitPoints),
85
87
  graph: information.graph,
86
- environment: information.environment,
88
+ // as we do not know whether the loop executes at all, we have to merge the environments of the condition and the body, as both may be relevant
89
+ environment: conditionIsAlwaysTrue ? information.environment : (0, append_1.appendEnvironment)(origEnv, information.environment),
87
90
  hooks: condition.hooks.concat(body.hooks)
88
91
  };
89
92
  }
@@ -40,7 +40,7 @@ export declare function convertFnArguments<OtherInfo>(args: readonly (typeof Emp
40
40
  * Transforms a function argument into a function argument reference for a function call vertex.
41
41
  * Please be aware, that the ids here are those inferred from the AST, not from the dataflow graph!
42
42
  */
43
- export declare function convertFnArgument<OtherInfo>(arg: typeof EmptyArgument | RNode<OtherInfo & ParentInformation>): FunctionArgument;
43
+ export declare function convertFnArgument<OtherInfo>(this: void, arg: typeof EmptyArgument | RNode<OtherInfo & ParentInformation>): FunctionArgument;
44
44
  /**
45
45
  * Processes all arguments for a function call, updating the given final graph and environment.
46
46
  */
@@ -6,6 +6,7 @@ exports.processAllArguments = processAllArguments;
6
6
  exports.patchFunctionCall = patchFunctionCall;
7
7
  const info_1 = require("../../../../info");
8
8
  const processor_1 = require("../../../../processor");
9
+ const model_1 = require("../../../../../r-bridge/lang-4.x/ast/model/model");
9
10
  const r_function_call_1 = require("../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
10
11
  const identifier_1 = require("../../../../environments/identifier");
11
12
  const overwrite_1 = require("../../../../environments/overwrite");
@@ -13,33 +14,34 @@ const resolve_by_name_1 = require("../../../../environments/resolve-by-name");
13
14
  const type_1 = require("../../../../../r-bridge/lang-4.x/ast/model/type");
14
15
  const vertex_1 = require("../../../../graph/vertex");
15
16
  const edge_1 = require("../../../../graph/edge");
17
+ const r_argument_1 = require("../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument");
16
18
  function forceVertexArgumentValueReferences(rootId, value, graph, env) {
17
19
  const valueVertex = graph.getVertex(value.entryPoint);
18
20
  if (!valueVertex) {
19
21
  return;
20
22
  }
21
23
  // link read if it is function definition directly and reference the exit point
22
- if (valueVertex.tag !== vertex_1.VertexType.Value) {
23
- if (valueVertex.tag === vertex_1.VertexType.FunctionDefinition) {
24
- for (const exit of valueVertex.exitPoints) {
25
- graph.addEdge(rootId, exit.nodeId, edge_1.EdgeType.Reads);
26
- }
24
+ if (valueVertex.tag === vertex_1.VertexType.FunctionDefinition) {
25
+ for (const exit of valueVertex.exitPoints) {
26
+ graph.addEdge(rootId, exit.nodeId, edge_1.EdgeType.Reads);
27
27
  }
28
- else {
29
- for (const exit of value.exitPoints) {
30
- graph.addEdge(rootId, exit.nodeId, edge_1.EdgeType.Reads);
31
- }
28
+ }
29
+ else if (valueVertex.tag !== vertex_1.VertexType.Value) {
30
+ for (const exit of value.exitPoints) {
31
+ graph.addEdge(rootId, exit.nodeId, edge_1.EdgeType.Reads);
32
32
  }
33
33
  }
34
34
  const containedSubflowIn = graph.verticesOfType(vertex_1.VertexType.FunctionDefinition)
35
- .flatMap(([, info]) => info.subflow.in)
36
- .toArray();
35
+ .flatMap(([, info]) => info.subflow.in);
37
36
  // try to resolve them against the current environment
38
- for (const ref of value.in.concat(containedSubflowIn)) {
39
- if (ref.name) {
40
- const resolved = ref.name ? (0, resolve_by_name_1.resolveByName)(ref.name, env, ref.type) ?? [] : [];
41
- for (const resolve of resolved) {
42
- graph.addEdge(ref.nodeId, resolve.nodeId, edge_1.EdgeType.Reads);
37
+ for (const l of [value.in, containedSubflowIn]) {
38
+ for (const ref of l) {
39
+ if (ref.name) {
40
+ const refId = ref.nodeId;
41
+ const resolved = (0, resolve_by_name_1.resolveByName)(ref.name, env, ref.type) ?? [];
42
+ for (const resolve of resolved) {
43
+ graph.addEdge(refId, resolve.nodeId, edge_1.EdgeType.Reads);
44
+ }
43
45
  }
44
46
  }
45
47
  }
@@ -51,7 +53,7 @@ function forceVertexArgumentValueReferences(rootId, value, graph, env) {
51
53
  * @see convertFnArgument
52
54
  */
53
55
  function convertFnArguments(args) {
54
- return args.map(arg => convertFnArgument(arg));
56
+ return args.map(convertFnArgument);
55
57
  }
56
58
  /**
57
59
  * Transforms a function argument into a function argument reference for a function call vertex.
@@ -93,32 +95,38 @@ function processAllArguments({ functionName, args, data, finalGraph, functionRoo
93
95
  continue;
94
96
  }
95
97
  const processed = (0, processor_1.processDataflowFor)(arg, { ...data, environment: argEnv });
96
- if (arg.type === type_1.RType.Argument && arg.value && (forceArgs === 'all' || forceArgs[i]) && arg.value.type !== type_1.RType.Number && arg.value.type !== type_1.RType.String && arg.value.type !== type_1.RType.Logical) {
98
+ if (r_argument_1.RArgument.isWithValue(arg) && (forceArgs === 'all' || forceArgs[i]) && !model_1.RConstant.is(arg.value)) {
97
99
  forceVertexArgumentValueReferences(functionRootId, processed, processed.graph, argEnv);
98
100
  }
99
101
  processedArguments.push(processed);
100
102
  finalEnv = (0, overwrite_1.overwriteEnvironment)(finalEnv, processed.environment);
101
103
  finalGraph.mergeWith(processed.graph);
102
104
  // resolve reads within argument, we resolve before adding the `processed.environment` to avoid cyclic dependencies
103
- for (const ingoing of processed.in.concat(processed.unknownReferences)) {
104
- // check if it is called directly
105
- const vtx = finalGraph.getVertex(ingoing.nodeId);
106
- const tryToResolve = ingoing.name ? (0, resolve_by_name_1.resolveByName)(ingoing.name, argEnv, vtx?.tag === vertex_1.VertexType.FunctionCall ? identifier_1.ReferenceType.Function : identifier_1.ReferenceType.Unknown) : undefined;
107
- if (tryToResolve === undefined) {
108
- remainingReadInArgs.push(ingoing);
109
- }
110
- else {
111
- /* maybe all targets are not definitely of the current scope and should be still kept */
112
- let assumeItMayHaveAHigherTarget = true;
113
- for (const resolved of tryToResolve) {
114
- if ((0, info_1.happensInEveryBranch)(resolved.cds) && !(0, identifier_1.isReferenceType)(resolved.type, identifier_1.ReferenceType.BuiltInFunction | identifier_1.ReferenceType.BuiltInConstant)) {
115
- assumeItMayHaveAHigherTarget = false;
116
- }
117
- finalGraph.addEdge(ingoing.nodeId, resolved.nodeId, edge_1.EdgeType.Reads);
118
- }
119
- if (assumeItMayHaveAHigherTarget) {
105
+ for (const l of [processed.in, processed.unknownReferences]) {
106
+ for (const ingoing of l) {
107
+ // check if it is called directly
108
+ const inId = ingoing.nodeId;
109
+ const refType = finalGraph.getVertex(inId)?.tag === vertex_1.VertexType.FunctionCall ? identifier_1.ReferenceType.Function : identifier_1.ReferenceType.Unknown;
110
+ const tryToResolve = ingoing.name ? (0, resolve_by_name_1.resolveByName)(ingoing.name, argEnv, refType) : undefined;
111
+ if (tryToResolve === undefined) {
120
112
  remainingReadInArgs.push(ingoing);
121
113
  }
114
+ else {
115
+ /* maybe all targets are not definitely of the current scope and should be still kept */
116
+ let assumeItMayHaveAHigherTarget = true;
117
+ for (const resolved of tryToResolve) {
118
+ if ((0, identifier_1.isReferenceType)(resolved.type, identifier_1.ReferenceType.BuiltInFunction | identifier_1.ReferenceType.BuiltInConstant)) {
119
+ continue;
120
+ }
121
+ else if ((0, info_1.happensInEveryBranch)(resolved.cds)) {
122
+ assumeItMayHaveAHigherTarget = false;
123
+ }
124
+ finalGraph.addEdge(inId, resolved.nodeId, edge_1.EdgeType.Reads);
125
+ }
126
+ if (assumeItMayHaveAHigherTarget) {
127
+ remainingReadInArgs.push(ingoing);
128
+ }
129
+ }
122
130
  }
123
131
  }
124
132
  argEnv = (0, overwrite_1.overwriteEnvironment)(argEnv, processed.environment);
@@ -9,7 +9,6 @@ const graph_1 = require("../../../../graph/graph");
9
9
  const edge_1 = require("../../../../graph/edge");
10
10
  const logger_1 = require("../../../../logger");
11
11
  const vertex_1 = require("../../../../graph/vertex");
12
- const log_1 = require("../../../../../util/log");
13
12
  const unknown_side_effect_1 = require("../../../../graph/unknown-side-effect");
14
13
  const built_in_1 = require("../../../../environments/built-in");
15
14
  /**
@@ -36,7 +35,6 @@ function processKnownFunctionCall({ name, args, rootId, data, reverseOrder = fal
36
35
  const functionName = (0, processor_1.processDataflowFor)(name, data);
37
36
  const finalGraph = new graph_1.DataflowGraph(data.completeAst.idMap);
38
37
  const functionCallName = name.content;
39
- (0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Processing known function call ${identifier_1.Identifier.toString(functionCallName)} with ${args.length} arguments`);
40
38
  const processArgs = reverseOrder ? args.toReversed() : args;
41
39
  const { finalEnv, callArgs, remainingReadInArgs, processedArguments } = (0, common_1.processAllArguments)({ functionName, args: processArgs, data, finalGraph, functionRootId: rootId, patchData, forceArgs });
42
40
  if (markAsNSE) {
@@ -1,7 +1,7 @@
1
1
  import { type DataflowProcessorInformation } from '../../../processor';
2
2
  import { type DataflowInformation } from '../../../info';
3
3
  import type { ParentInformation } from '../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
4
- import type { RNode } from '../../../../r-bridge/lang-4.x/ast/model/model';
4
+ import { RNode } from '../../../../r-bridge/lang-4.x/ast/model/model';
5
5
  import type { IdentifierReference } from '../../../environments/identifier';
6
6
  import { DataflowGraph } from '../../../graph/graph';
7
7
  import type { RArgument } from '../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument';
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.linkReadsForArgument = linkReadsForArgument;
4
4
  exports.processFunctionArgument = processFunctionArgument;
5
5
  const processor_1 = require("../../../processor");
6
- const collect_1 = require("../../../../r-bridge/lang-4.x/ast/model/collect");
6
+ const model_1 = require("../../../../r-bridge/lang-4.x/ast/model/model");
7
7
  const graph_1 = require("../../../graph/graph");
8
8
  const type_1 = require("../../../../r-bridge/lang-4.x/ast/model/type");
9
9
  const edge_1 = require("../../../graph/edge");
@@ -12,9 +12,9 @@ const vertex_1 = require("../../../graph/vertex");
12
12
  * Links all reads that occur before the argument to the argument root node.
13
13
  */
14
14
  function linkReadsForArgument(root, ingoingRefs, graph) {
15
- const allIdsBeforeArguments = new Set((0, collect_1.collectAllIds)(root, n => n.type === type_1.RType.Argument && n.info.id !== root.info.id));
16
- const ingoingBeforeArgs = ingoingRefs.filter(r => allIdsBeforeArguments.has(r.nodeId));
17
15
  const rid = root.info.id;
16
+ const allIdsBeforeArguments = new Set(model_1.RNode.collectAllIdsWithStop(root, n => n.type === type_1.RType.Argument && n.info.id !== rid));
17
+ const ingoingBeforeArgs = ingoingRefs.filter(r => allIdsBeforeArguments.has(r.nodeId));
18
18
  for (const ref of ingoingBeforeArgs) {
19
19
  // link against the root reference currently I do not know how to deal with nested function calls otherwise
20
20
  graph.addEdge(rid, ref.nodeId, edge_1.EdgeType.Reads);
@@ -5,8 +5,8 @@ const processor_1 = require("../../../processor");
5
5
  const log_1 = require("../../../../util/log");
6
6
  const identifier_1 = require("../../../environments/identifier");
7
7
  const define_1 = require("../../../environments/define");
8
- const type_1 = require("../../../../r-bridge/lang-4.x/ast/model/type");
9
8
  const edge_1 = require("../../../graph/edge");
9
+ const r_function_definition_1 = require("../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-definition");
10
10
  /**
11
11
  *
12
12
  */
@@ -26,7 +26,7 @@ function processFunctionParameter(parameter, data) {
26
26
  graph.setDefinitionOfVertex(writtenNode);
27
27
  environment = (0, define_1.define)(writtenNode, false, environment);
28
28
  if (defaultValue !== undefined) {
29
- if (parameter.defaultValue?.type === type_1.RType.FunctionDefinition) {
29
+ if (r_function_definition_1.RFunctionDefinition.is(parameter.defaultValue)) {
30
30
  graph.addEdge(wid, parameter.defaultValue.info.id, edge_1.EdgeType.DefinedBy);
31
31
  }
32
32
  else {
@@ -1,4 +1,4 @@
1
- import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
1
+ import { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
2
2
  import type { DataflowGraph } from '../graph/graph';
3
3
  import type { Identifier } from '../environments/identifier';
4
4
  export declare const enum OriginType {
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getOriginInDfg = getOriginInDfg;
4
+ const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
4
5
  const vertex_1 = require("../graph/vertex");
5
6
  const edge_1 = require("../graph/edge");
6
7
  const linker_1 = require("../internal/linker");
7
8
  const assert_1 = require("../../util/assert");
8
- const built_in_1 = require("../environments/built-in");
9
9
  /**
10
10
  * Obtain the (dataflow) origin of a given node in the dfg.
11
11
  * @example consider the following code:
@@ -95,7 +95,7 @@ function getCallTarget(dfg, call) {
95
95
  return origins?.length === 0 ? getVariableUseOrigin(dfg, call) : origins;
96
96
  }
97
97
  origins = (origins ?? []).concat([...targets].map(target => {
98
- if ((0, built_in_1.isBuiltIn)(target)) {
98
+ if (node_id_1.NodeId.isBuiltIn(target)) {
99
99
  return {
100
100
  type: 3 /* OriginType.BuiltInFunctionOrigin */,
101
101
  fn: { name: call.name },
@@ -517,7 +517,7 @@ function printHierarchy({ program, info, root, ignoredTypes, collapseFromNesting
517
517
  if (exports.mermaidHide.includes(baseType) || ignoredTypes?.includes(baseType)) {
518
518
  continue;
519
519
  }
520
- const res = printHierarchy({ program, info, root: baseType, collapseFromNesting, initialNesting: initialNesting + 1, maxDepth, skipNesting, showImplSnippet, reverse });
520
+ const res = printHierarchy({ program, info, root: baseType, ignoredTypes, collapseFromNesting, initialNesting: initialNesting + 1, maxDepth, skipNesting, showImplSnippet, reverse });
521
521
  result.push(res);
522
522
  }
523
523
  const out = result.join('\n');
@@ -17,7 +17,7 @@ class IntervalInferenceVisitor extends absint_visitor_1.AbstractInterpretationVi
17
17
  onNumberConstant({ vertex, node }) {
18
18
  super.onNumberConstant({ vertex, node });
19
19
  const interval = new interval_domain_1.IntervalDomain([node.content.num, node.content.num]);
20
- this.currentState.set(node.info.id, interval);
20
+ this.updateState(node.info.id, interval);
21
21
  }
22
22
  onFunctionCall({ call }) {
23
23
  super.onFunctionCall({ call });
@@ -31,9 +31,9 @@ class IntervalInferenceVisitor extends absint_visitor_1.AbstractInterpretationVi
31
31
  // We map the numerical operation to the resulting interval after applying the abstract semantics of the operation
32
32
  switch (identifier_1.Identifier.getName(call.name)) {
33
33
  case '+':
34
- return this.currentState.set(call.id, left.add(right));
34
+ return this.updateState(call.id, left.add(right));
35
35
  case '-':
36
- return this.currentState.set(call.id, left.subtract(right));
36
+ return this.updateState(call.id, left.subtract(right));
37
37
  }
38
38
  }
39
39
  }
@@ -51,8 +51,7 @@ async function inferIntervals() {
51
51
  const dfg = (await analyzer.dataflow()).graph;
52
52
  const cfg = await analyzer.controlflow(undefined, cfg_kind_1.CfgKind.NoFunctionDefs);
53
53
  const ctx = analyzer.inspectContext();
54
- const domain = new state_abstract_domain_1.StateAbstractDomain(new Map());
55
- const inference = new IntervalInferenceVisitor({ controlFlow: cfg, dfg: dfg, normalizedAst: ast, ctx: ctx, domain: domain });
54
+ const inference = new IntervalInferenceVisitor({ controlFlow: cfg, dfg: dfg, normalizedAst: ast, ctx: ctx });
56
55
  inference.start();
57
56
  const result = inference.getEndState();
58
57
  return result.value.entries().toArray()
@@ -128,15 +127,15 @@ For example, if we want to perform a (very basic) interval analysis using abstra
128
127
 
129
128
  ${ctx.code(IntervalInferenceVisitor)}
130
129
 
131
- 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
+ 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 via ${ctx.linkM(absint_visitor_1.AbstractInterpretationVisitor, 'updateState', { hideClass: true })} by setting the inferred abstract value of the currently visited control flow vertex to the new interval.
132
131
 
133
- 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
+ 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 via ${ctx.linkM(absint_visitor_1.AbstractInterpretationVisitor, 'updateState', { hideClass: true })} 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.
134
133
 
135
134
  If we now want to run the interval inference, we can write the following code:
136
135
 
137
136
  ${ctx.code(inferIntervals, { dropLinesStart: 1, dropLinesEnd: 5 })}
138
137
 
139
- 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
+ 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. For performance reasons, we construct the control flow graph without simplification passes, data flow information, and function definitions. We then create a new ${ctx.link(IntervalInferenceVisitor)} using the control flow graph, dataflow graph, normalized AST, and analyzer context, 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 })}.
140
139
 
141
140
  If we now print the inferred abstract state at the end of the program, we get the following output:
142
141