@eagleoutice/flowr 2.9.11 → 2.9.12

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.
package/README.md CHANGED
@@ -24,7 +24,7 @@ It offers a wide variety of features, for example:
24
24
 
25
25
  ```shell
26
26
  $ docker run -it --rm eagleoutice/flowr # or npm run flowr
27
- flowR repl using flowR v2.9.10, R grammar v14 (tree-sitter engine)
27
+ flowR repl using flowR v2.9.11, R grammar v14 (tree-sitter engine)
28
28
  R> :query @linter "read.csv(\"/root/x.txt\")"
29
29
  ```
30
30
 
@@ -35,11 +35,11 @@ It offers a wide variety of features, for example:
35
35
  ```text
36
36
  Query: linter (2 ms)
37
37
  ╰ Deprecated Functions (deprecated-functions):
38
- ╰ Metadata: totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 0, processTimeMs: 0
38
+ ╰ Metadata: totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 1, processTimeMs: 0
39
39
  ╰ File Path Validity (file-path-validity):
40
40
  ╰ certain:
41
41
  ╰ Path `/root/x.txt` at 1.1-23
42
- ╰ Metadata: totalReads: 1, totalUnknown: 0, totalWritesBeforeAlways: 0, totalValid: 0, searchTimeMs: 1, processTimeMs: 0
42
+ ╰ Metadata: totalReads: 1, totalUnknown: 0, totalWritesBeforeAlways: 0, totalValid: 0, searchTimeMs: 0, processTimeMs: 0
43
43
  ╰ Seeded Randomness (seeded-randomness):
44
44
  ╰ Metadata: consumerCalls: 0, callsWithFunctionProducers: 0, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0, callsWithOtherBranchProducers: 0, searchTimeMs: 0, processTimeMs: 0
45
45
  ╰ Absolute Paths (absolute-file-paths):
@@ -58,7 +58,7 @@ It offers a wide variety of features, for example:
58
58
  ╰ Metadata: consideredNodes: 5, searchTimeMs: 0, processTimeMs: 0
59
59
  ╰ Useless Loops (useless-loop):
60
60
  ╰ Metadata: numOfUselessLoops: 0, searchTimeMs: 0, processTimeMs: 0
61
- All queries together required ≈2 ms (1ms accuracy, total 3 ms)
61
+ All queries together required ≈2 ms (1ms accuracy, total 2 ms)
62
62
  ```
63
63
 
64
64
 
@@ -80,7 +80,7 @@ It offers a wide variety of features, for example:
80
80
 
81
81
  _Results (prettified and summarized):_
82
82
 
83
- Query: **linter** (3 ms)\
83
+ Query: **linter** (2 ms)\
84
84
     ╰ **Deprecated Functions** (deprecated-functions):\
85
85
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 1, processTimeMs: 0</code>\
86
86
  &nbsp;&nbsp;&nbsp;╰ **File Path Validity** (file-path-validity):\
@@ -88,11 +88,11 @@ It offers a wide variety of features, for example:
88
88
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ Path `/root/x.txt` at 1.1-23\
89
89
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>totalReads: 1, totalUnknown: 0, totalWritesBeforeAlways: 0, totalValid: 0, searchTimeMs: 0, processTimeMs: 0</code>\
90
90
  &nbsp;&nbsp;&nbsp;╰ **Seeded Randomness** (seeded-randomness):\
91
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>consumerCalls: 0, callsWithFunctionProducers: 0, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0, callsWithOtherBranchProducers: 0, searchTimeMs: 1, processTimeMs: 0</code>\
91
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>consumerCalls: 0, callsWithFunctionProducers: 0, callsWithAssignmentProducers: 0, callsWithNonConstantProducers: 0, callsWithOtherBranchProducers: 0, searchTimeMs: 0, processTimeMs: 0</code>\
92
92
  &nbsp;&nbsp;&nbsp;╰ **Absolute Paths** (absolute-file-paths):\
93
93
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ certain:\
94
94
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ Path `/root/x.txt` at 1.1-23\
95
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>totalConsidered: 1, totalUnknown: 0, searchTimeMs: 0, processTimeMs: 0</code>\
95
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>totalConsidered: 1, totalUnknown: 0, searchTimeMs: 1, processTimeMs: 0</code>\
96
96
  &nbsp;&nbsp;&nbsp;╰ **Unused Definitions** (unused-definitions):\
97
97
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>totalConsidered: 0, searchTimeMs: 0, processTimeMs: 0</code>\
98
98
  &nbsp;&nbsp;&nbsp;╰ **Naming Convention** (naming-convention):\
@@ -102,14 +102,14 @@ It offers a wide variety of features, for example:
102
102
  &nbsp;&nbsp;&nbsp;╰ **Dataframe Access Validation** (dataframe-access-validation):\
103
103
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs: 0</code>\
104
104
  &nbsp;&nbsp;&nbsp;╰ **Dead Code** (dead-code):\
105
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>consideredNodes: 5, searchTimeMs: 0, processTimeMs: 1</code>\
105
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>consideredNodes: 5, searchTimeMs: 0, processTimeMs: 0</code>\
106
106
  &nbsp;&nbsp;&nbsp;╰ **Useless Loops** (useless-loop):\
107
107
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;╰ _Metadata_: <code>numOfUselessLoops: 0, searchTimeMs: 0, processTimeMs: 0</code>\
108
- _All queries together required ≈3 ms (1ms accuracy, total 3 ms)_
108
+ _All queries together required ≈2 ms (1ms accuracy, total 2 ms)_
109
109
 
110
110
  <details> <summary style="color:gray">Show Detailed Results as Json</summary>
111
111
 
112
- The analysis required _2.5 ms_ (including parsing and normalization and the query) within the generation environment.
112
+ The analysis required _2.2 ms_ (including parsing and normalization and the query) within the generation environment.
113
113
 
114
114
  In general, the JSON contains the Ids of the nodes in question as they are present in the normalized AST or the dataflow graph of flowR.
115
115
  Please consult the [Interface](https://github.com/flowr-analysis/flowr/wiki/Interface) wiki page for more information on how to get those.
@@ -161,7 +161,7 @@ It offers a wide variety of features, for example:
161
161
  "callsWithAssignmentProducers": 0,
162
162
  "callsWithNonConstantProducers": 0,
163
163
  "callsWithOtherBranchProducers": 0,
164
- "searchTimeMs": 1,
164
+ "searchTimeMs": 0,
165
165
  "processTimeMs": 0
166
166
  }
167
167
  },
@@ -181,7 +181,7 @@ It offers a wide variety of features, for example:
181
181
  ".meta": {
182
182
  "totalConsidered": 1,
183
183
  "totalUnknown": 0,
184
- "searchTimeMs": 0,
184
+ "searchTimeMs": 1,
185
185
  "processTimeMs": 0
186
186
  }
187
187
  },
@@ -226,7 +226,7 @@ It offers a wide variety of features, for example:
226
226
  ".meta": {
227
227
  "consideredNodes": 5,
228
228
  "searchTimeMs": 0,
229
- "processTimeMs": 1
229
+ "processTimeMs": 0
230
230
  }
231
231
  },
232
232
  "useless-loop": {
@@ -239,11 +239,11 @@ It offers a wide variety of features, for example:
239
239
  }
240
240
  },
241
241
  ".meta": {
242
- "timing": 3
242
+ "timing": 2
243
243
  }
244
244
  },
245
245
  ".meta": {
246
- "timing": 3
246
+ "timing": 2
247
247
  }
248
248
  }
249
249
  ```
@@ -308,7 +308,7 @@ It offers a wide variety of features, for example:
308
308
 
309
309
  ```shell
310
310
  $ docker run -it --rm eagleoutice/flowr # or npm run flowr
311
- flowR repl using flowR v2.9.10, R grammar v14 (tree-sitter engine)
311
+ flowR repl using flowR v2.9.11, R grammar v14 (tree-sitter engine)
312
312
  R> :query @static-slice (11@sum) file://test/testfiles/example.R
313
313
  ```
314
314
 
@@ -322,7 +322,7 @@ It offers a wide variety of features, for example:
322
322
  N <- 10
323
323
  for(i in 1:(N-1)) sum <- sum + i + w
324
324
  sum
325
- All queries together required ≈2 ms (1ms accuracy, total 3 ms)
325
+ All queries together required ≈2 ms (1ms accuracy, total 2 ms)
326
326
  ```
327
327
 
328
328
 
@@ -356,7 +356,7 @@ It offers a wide variety of features, for example:
356
356
 
357
357
 
358
358
  * 🚀 **fast call-graph, data-, and control-flow graphs**\
359
- Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">104.5 ms</span></i> (as of Feb 13, 2026)](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark),
359
+ Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">98.9 ms</span></i> (as of Feb 18, 2026)](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark),
360
360
  _flowR_ can analyze the data- and control-flow of the average real-world R&nbsp;script. See the [benchmarks](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark) for more information,
361
361
  and consult the [wiki pages](https://github.com/flowr-analysis/flowr/wiki/wiki/dataflow-graph) for more details on the [dataflow graphs](https://github.com/flowr-analysis/flowr/wiki/wiki/dataflow-graph) as well as [call graphs](https://github.com/flowr-analysis/flowr/wiki/wiki/dataflow-graph#perspectives-cg).
362
362
 
@@ -392,7 +392,7 @@ It offers a wide variety of features, for example:
392
392
 
393
393
  ```shell
394
394
  $ docker run -it --rm eagleoutice/flowr # or npm run flowr
395
- flowR repl using flowR v2.9.10, R grammar v14 (tree-sitter engine)
395
+ flowR repl using flowR v2.9.11, R grammar v14 (tree-sitter engine)
396
396
  R> :dataflow* test/testfiles/example.R
397
397
  ```
398
398
 
@@ -700,7 +700,7 @@ It offers a wide variety of features, for example:
700
700
  ```
701
701
 
702
702
 
703
- (The analysis required _2.2 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.)
703
+ (The analysis required _1.6 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.)
704
704
 
705
705
 
706
706
 
@@ -30,18 +30,22 @@ function makeCluster(graph, from, notReached) {
30
30
  if (info.tag === vertex_1.VertexType.FunctionDefinition) {
31
31
  for (const { nodeId } of info.exitPoints) {
32
32
  if (notReached.delete(nodeId)) {
33
- makeCluster(graph, nodeId, notReached).forEach(n => nodes.add(n));
33
+ for (const m of makeCluster(graph, nodeId, notReached)) {
34
+ nodes.add(m);
35
+ }
34
36
  }
35
37
  }
36
38
  }
37
39
  // cluster adjacent edges
38
- for (const [dest, e] of [...graph.outgoingEdges(from) ?? [], ...graph.ingoingEdges(from) ?? []]) {
39
- // don't cluster for function content if it isn't returned
40
- if (edge_1.DfEdge.doesNotIncludeType(e, edge_1.EdgeType.Returns) && info.onlyBuiltin && info.name === '{') {
41
- continue;
42
- }
43
- if (notReached.delete(dest)) {
44
- makeCluster(graph, dest, notReached).forEach(n => nodes.add(n));
40
+ for (const edges of [graph.outgoingEdges(from), graph.ingoingEdges(from)]) {
41
+ for (const [dest, e] of edges ?? []) {
42
+ // don't cluster for function content if it isn't returned
43
+ if (edge_1.DfEdge.doesNotIncludeType(e, edge_1.EdgeType.Returns) && info.onlyBuiltin && info.name === '{') {
44
+ continue;
45
+ }
46
+ if (notReached.delete(dest)) {
47
+ makeCluster(graph, dest, notReached).forEach(n => nodes.add(n));
48
+ }
45
49
  }
46
50
  }
47
51
  return nodes;
@@ -10,13 +10,10 @@ const edge_1 = require("./edge");
10
10
  */
11
11
  function df2quads(graph, config) {
12
12
  return (0, quads_1.graph2quads)({
13
- rootIds: [...graph.rootIds()],
14
- vertices: graph.vertices(true)
15
- .map(([id, v]) => ({
16
- ...v,
17
- id
18
- })).toArray(),
19
- edges: graph.edges().flatMap(([fromId, targets]) => [...targets].map(([toId, info]) => ({
13
+ rootIds: Array.from(graph.rootIds()),
14
+ vertices: Array.from(graph.vertices(true)
15
+ .map(([, v]) => v)),
16
+ edges: graph.edges().flatMap(([fromId, targets]) => Array.from(targets).map(([toId, info]) => ({
20
17
  from: fromId,
21
18
  to: toId,
22
19
  type: Array.from(edge_1.DfEdge.typesToNames(info)),
@@ -395,18 +395,18 @@ function getAllLinkedFunctionDefinitions(functionDefinitionReadIds, dataflowGrap
395
395
  builtIns.add(cid);
396
396
  continue;
397
397
  }
398
- const currentInfo = dataflowGraph.get(cid, true);
399
- if (currentInfo === undefined) {
398
+ const vertex = dataflowGraph.getVertex(cid);
399
+ if (vertex === undefined) {
400
400
  continue;
401
401
  }
402
- const [vertex, edges] = currentInfo;
403
402
  // Found a function definition
404
403
  if (vertex.subflow !== undefined) {
405
404
  result.add(vertex);
406
405
  continue;
407
406
  }
408
407
  let hasReturnEdge = false;
409
- for (const [target, e] of edges) {
408
+ const outgoing = dataflowGraph.outgoingEdges(cid) ?? [];
409
+ for (const [target, e] of outgoing) {
410
410
  if (edge_1.DfEdge.includesType(e, edge_1.EdgeType.Returns)) {
411
411
  hasReturnEdge = true;
412
412
  if (!visited.has(target)) {
@@ -417,7 +417,7 @@ function getAllLinkedFunctionDefinitions(functionDefinitionReadIds, dataflowGrap
417
417
  if (vertex.tag === vertex_1.VertexType.FunctionCall || hasReturnEdge || (vertex.tag === vertex_1.VertexType.VariableDefinition && vertex.par)) {
418
418
  continue;
419
419
  }
420
- for (const [target, e] of edges) {
420
+ for (const [target, e] of outgoing) {
421
421
  if (edge_1.DfEdge.includesType(e, LinkedFnFollowBits) && !visited.has(target)) {
422
422
  potential.push(target);
423
423
  }
@@ -39,6 +39,10 @@ const flowr_analyzer_context_1 = require("../project/context/flowr-analyzer-cont
39
39
  const doc_maker_1 = require("./wiki-mk/doc-maker");
40
40
  const flowr_analyzer_1 = require("../project/flowr-analyzer");
41
41
  const built_in_1 = require("../dataflow/environments/built-in");
42
+ const dfg_1 = require("../util/mermaid/dfg");
43
+ const r_number_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-number");
44
+ const model_1 = require("../r-bridge/lang-4.x/ast/model/model");
45
+ const range_1 = require("../util/range");
42
46
  async function subExplanation(parser, { description, code, expectedSubgraph }) {
43
47
  expectedSubgraph = await (0, doc_dfg_1.verifyExpectedSubgraph)(parser, code, expectedSubgraph);
44
48
  const marks = [];
@@ -741,12 +745,14 @@ class WikiDataflowGraph extends doc_maker_1.DocMaker {
741
745
  super('wiki/Dataflow Graph.md', module.filename, 'dataflow graph');
742
746
  }
743
747
  async text({ ctx, treeSitter }) {
748
+ const introExampleCode = 'x <- 3\ny <- x + 1\ny';
744
749
  return `
745
- This page briefly summarizes flowR's dataflow graph, represented by the ${ctx.link(graph_1.DataflowGraph)} class within the code.
746
- In case you want to manually build such a graph (e.g., for testing), you can use the ${ctx.link(dataflowgraph_builder_1.DataflowGraphBuilder)}.
750
+ This page briefly summarizes flowR's dataflow graph (${ctx.link(graph_1.DataflowGraph)}).
747
751
  If you are interested in which features we support and which features are still to be worked on, please refer to our ${ctx.linkPage('wiki/Capabilities')} page.
748
- In summary, we discuss the following topics:
752
+ In case you want to manually build such a graph (e.g., for testing), you can use the ${ctx.link(dataflowgraph_builder_1.DataflowGraphBuilder)}.
753
+ In summary, we discuss the following topics in this wiki page:
749
754
 
755
+ - [Reading the Visualization](#reading-the-visualization)
750
756
  - [Vertices](#vertices)
751
757
  - [Edges](#edges)
752
758
  - [Control Dependencies](#control-dependencies)
@@ -756,37 +762,35 @@ In summary, we discuss the following topics:
756
762
  - [Call Graph Perspective](#perspectives-cg)
757
763
  - [Working with the Dataflow Graph](#dfg-working)
758
764
 
759
- Please be aware that the accompanied [dataflow information](#dataflow-information) (${ctx.link('DataflowInformation')}) returned by _flowR_ contains things besides the graph,
760
- like the entry and exit points of the subgraphs, and currently active references (see [below](#dataflow-information)).
761
- Additionally, you may be interested in the set of [Unknown Side Effects](#unknown-side-effects), marking calls which _flowR_ is unable to handle correctly.
762
-
763
- Potentially, you are interested in another perspective that flowR provides, the [control flow graph](${doc_files_1.FlowrWikiBaseRef}/Control%20Flow%20Graph), so please check the correpsonding
764
- wiki page if you are unsure.
765
+ Please be aware that the accompanied [dataflow information](#dataflow-information) (${ctx.link('DataflowInformation')}) returned by _flowR_
766
+ contains things besides the graph, like the entry and exit points of the subgraphs, and currently active references (see [below](#dataflow-information)).
767
+ Additionally, you may be interested in the [Unknown Side Effects](#unknown-side-effects), marking calls which _flowR_ is unable to handle correctly.
765
768
 
766
769
  > [!TIP]
767
- > If you want to investigate the dataflow graph,
768
- > you can either use the [Visual Studio Code extension](${doc_files_1.FlowrVsCode}) or the ${ctx.replCmd('dataflow*')}
769
- > command in the REPL (see the ${ctx.linkPage('wiki/Interface', 'Interface wiki page')} for more information).
770
- > There is also a simplified perspective available with ${ctx.replCmd('dataflowsimple*')} that does not show everything but is easier to read.
770
+ > To investigate the dataflow graph,
771
+ > you can either use the ${ctx.linkPage('flowr:vscode')} or the ${ctx.replCmd('dataflow*')}
772
+ > command in the REPL (see the ${ctx.linkPage('wiki/Interface', 'Interface wiki page')}).
773
+ > There is also a simplified version available with ${ctx.replCmd('dataflowsimple*')} that does not show everything but is easier to read.
771
774
  > For small graphs, you can also use ${ctx.replCmd('dataflowascii')} to print the graph as ASCII art.
772
- >
773
- > When using _flowR_ as a library, you may use the functions in ${(0, doc_files_1.getFilePathMd)('../util/mermaid/dfg.ts')}.
774
775
  >
775
- > If you receive a dataflow graph in its serialized form (e.g., by talking to a [_flowR_ server](${doc_files_1.FlowrWikiBaseRef}/Interface)), you can use ${ctx.linkM(graph_1.DataflowGraph, 'fromJson', { realNameWrapper: 'i', codeFont: true })} to retrieve the graph from the JSON representation.
776
+ > If you receive a dataflow graph in its serialized form (e.g., by talking to a [_flowR_ server](${doc_files_1.FlowrWikiBaseRef}/Interface)), you can use ${ctx.linkM(graph_1.DataflowGraph, 'fromJson', { realNameWrapper: 'i', codeFont: true })} to recover the graph object.
776
777
  >
777
778
  > Also, check out the [${doc_files_1.FlowrGithubGroupName}/sample-analyzer-df-diff](${doc_files_1.FlowrGithubBaseRef}/sample-analyzer-df-diff) repository for a complete example project creating and comparing dataflow graphs.
778
779
 
779
- ${await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'x <- 3\ny <- x + 1\ny')}
780
+ To get started, let's look at the graph for the following code snippet:
781
+ ${(0, doc_code_1.codeBlock)('r', introExampleCode)}
780
782
 
783
+ With this code, the corresponding dataflow graph looks like this:
781
784
 
782
- The above dataflow graph showcases the general gist. We define a dataflow graph as a directed graph G = (V, E), differentiating between ${(0, doc_data_dfg_util_1.getAllVertices)().length} types of vertices V and
783
- ${(0, doc_data_dfg_util_1.getAllEdges)().length} types of edges E allowing each vertex to have a single, and each edge to have multiple distinct types.
785
+ ${await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, introExampleCode, { showCode: false })}
786
+
787
+ The above dataflow graph showcases the general gist. We define a dataflow graph as a directed graph G&nbsp;=&nbsp;(V,&nbsp;E),
788
+ differentiating between ${(0, doc_data_dfg_util_1.getAllVertices)().length} types of vertices&nbsp;V and
789
+ ${(0, doc_data_dfg_util_1.getAllEdges)().length} types of edges&nbsp;E allowing each vertex to have a single, and each edge to have multiple distinct types.
784
790
  Additionally, every node may have links to its [control dependencies](#control-dependencies) (which you may view as a ${(0, text_1.nth)((0, doc_data_dfg_util_1.getAllEdges)().length + 1)} edge type,
785
791
  although they are explicitly no data dependency and relate to the ${ctx.linkPage('wiki/Control Flow Graph')}.
786
792
 
787
- <details open>
788
-
789
- <summary>Vertex Types</summary>
793
+ ${(0, doc_structure_1.details)('Simplified Version of the graph', await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'x <- 3\ny <- x + 1\ny', { simplified: true, showCode: false }))}
790
794
 
791
795
  The following vertices types exist:
792
796
 
@@ -794,20 +798,13 @@ The following vertices types exist:
794
798
 
795
799
  ${(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'] })))}
796
800
 
797
- </details>
798
-
799
- <details open>
800
-
801
- <summary>Edge Types</summary>
802
-
803
- The following edges types exist, internally we use bitmasks to represent multiple types in a compact form:
801
+ The following edges types exist, internally we use bitmasks to represent multiple types in a compact form, so you
802
+ should use the ${ctx.link('DfEdge', { codeFont: false, realNameWrapper: 'i' }, { type: 'variable' })} object and its methods to work with them:
804
803
 
805
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. ')}
806
805
 
807
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'] })))}
808
807
 
809
- </details>
810
-
811
808
 
812
809
  From an implementation perspective all of these types are represented by respective interfaces, see ${(0, doc_files_1.getFilePathMd)('../dataflow/graph/vertex.ts')} and ${(0, doc_files_1.getFilePathMd)('../dataflow/graph/edge.ts')}.
813
810
 
@@ -828,6 +825,64 @@ ${(0, doc_general_1.prefixLines)((0, doc_code_1.codeBlock)('ts', `const name = $
828
825
  > For argument wrappers you can access the dataflow information for their value. For dead code, however, flowR currently contains
829
826
  > some core heuristics that remove it which cannot be reversed easily. So please open [an issue](${doc_issue_1.NewIssueUrl}) if you encounter such a case and require the node to be present in the dataflow graph.
830
827
 
828
+ ${(0, doc_structure_1.section)('Reading the Visualizations', 2, 'reading-the-visualization')}
829
+
830
+ Before we dive into the details of the different vertices and edges, let's briefly talk about how to read the visualizations.
831
+ For this, let's have a look at a very simple graph, created for the number \`42\`:
832
+
833
+ ${await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, '42', { showCode: false })}
834
+
835
+ ${(0, doc_structure_1.section)('Vertex Shape', 3, 'vtx-shape')}
836
+
837
+ The _shape_ of the vertex tells you the type of the vertex in the dataflow graph using the following scheme (the types are
838
+ explained in more detail in the following sections):
839
+
840
+ ${(0, doc_code_1.codeBlock)('mermaid', 'flowchart TD\n' +
841
+ // use mermaidNodeBrackets to get open and closing bracket
842
+ Object.entries(vertex_1.VertexType)
843
+ .map(([k, v]) => {
844
+ const { open, close } = (0, dfg_1.mermaidNodeBrackets)(v);
845
+ return ` ${v}${open}${k}${close}`;
846
+ }).join('\n') +
847
+ // we add a subflow for the function definition
848
+ '\n subgraph fbox ["function body"]\n body((...))\n end\n fdef-->fbox')}
849
+
850
+ ${(0, doc_structure_1.section)('Syntactic Types', 3, 'vtx-synt-type')}
851
+
852
+ Within the shape, in square brackets, you can find the syntactic type of the vertex
853
+ which is linked to the node in the ${ctx.linkPage('wiki/Normalized AST')}.
854
+ For more information on valid types and what to do with them, please refer to the ${ctx.linkPage('wiki/Normalized AST', 'normalized AST wiki page')}
855
+ and the corresponding helper objects (e.g., ${ctx.link(r_number_1.RNumber, undefined, { type: 'variable' })}).
856
+
857
+ ${(0, doc_structure_1.section)('Lexeme', 3, 'vtx-lexeme')}
858
+
859
+ Also in the first line, next to the [syntactic type](#vtx-synt-type), you can find the lexeme of the vertex (if it has one, e.g., for a variable definition or use).
860
+ This usually represents the textual source string of the respective vertex, and is also linked to the ${ctx.linkPage('wiki/Normalized AST')}.
861
+ You can access the lexeme too with ${ctx.linkO(model_1.RNode, 'lexeme')}.
862
+
863
+ ${(0, doc_structure_1.section)('Vertex Id', 3, 'vtx-id')}
864
+
865
+ In the second line, you will usually find the id (in the form of a ${ctx.link(node_id_1.NodeId, undefined, { type: 'variable' })}) of the vertex,
866
+ alongside its [control dependencies](#control-dependencies) if it has any. This id links the vertex to the respective node in the ${ctx.linkPage('wiki/Normalized AST')} (and all other perspectives created by flowR).
867
+ To give you an example, have a look at the following graph:
868
+
869
+ ${await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'if(u) a', { showCode: false, mark: new Set(['1']) })}
870
+ With the _may_ prefix you can see that \`a\` has a [control dependency](#control-dependencies)
871
+ on the \`if\`, which only triggers when the condition is \`true\` (as indicated by the \`+\` suffix).
872
+
873
+ ${(0, doc_structure_1.section)('Location', 3, 'vtx-location')}
874
+
875
+ The third line indicates the compressed ${ctx.link(range_1.SourceRange)} of the vertex in the format \`startLine.startCharacter - endLine.endCharacter\`. If the range reads \`1.7\`,
876
+ this is short for \`1.7-1.7\`, likewise, \`1.7-9\` is short for \`1.7-1.9\`. So, \`1.7-9\` describes something starting
877
+ in the first line at the seventh character and ending in the first line at the ninth character.
878
+
879
+ ${(0, doc_structure_1.section)('Arguments and Additional Information', 3, 'vtx-additional-info')}
880
+
881
+ Some vertices (e.g., [function calls](#function-call-vertex)) have additional information, like the arguments of the call.
882
+ As you can see with the \`if\` example above alongside the [vertex id](#vtx-id),
883
+ these vertices also have an additional line which lists the ids of the arguments in order to clear any ambiguity in case, for example,
884
+ the mermaid graph layouting fumbles the order.
885
+
831
886
  ${(0, doc_structure_1.section)('Vertices', 2, 'vertices')}
832
887
 
833
888
  1. ${(0, doc_data_dfg_util_1.getAllVertices)().map(([k, v]) => `[\`${k}\`](#${v.toLowerCase().replaceAll(/\s/g, '-')}-vertex)`).join('\n1. ')}
@@ -37,6 +37,19 @@ are exposed with some command line options (e.g., when using the docker image of
37
37
  - ${ctx.cliOption('flowr', 'engine.tree-sitter.tree-sitter-wasm-path', false)} pass the path to the wasm of tree-sitter (see [below](#tree-sitter))
38
38
  - ${ctx.cliOption('flowr', 'default-engine', false)} to set the default engine to use
39
39
 
40
+ <a id="r-shell"></a>
41
+ ## Dealing with the R Shell Engine
42
+
43
+ The ${ctx.link(shell_1.RShell)} engine is the original engine of flowR and is still available today.
44
+ It provides a powerful interface to the R interpreter, allowing for complex interactions and the execution of R code.
45
+ There are two interfaces available:
46
+
47
+ * The ${ctx.link(shell_1.RShell)} which is asynchronous and allows for non-blocking interactions with the R interpreter. This is the default engine.
48
+ * The ${ctx.link(shell_executor_1.RShellExecutor)} which is synchronous and blocks the execution until the R code is executed. This can be useful for certain use cases where you want to ensure that the R code is executed before proceeding with the analysis.
49
+
50
+ Please note, that these classes are available to you even if you do not use/enable the R shell engine.
51
+ The selection and preparation of the engine just reflects what the flowR analysis will use.
52
+
40
53
  <a id="tree-sitter"></a>
41
54
  ## Dealing with the Tree-Sitter Engine
42
55
 
@@ -59,6 +72,11 @@ you first must build the new wasm file. For this you have to:
59
72
  3. Pass the \`tree-sitter-r.wasm\` to flowR.
60
73
 
61
74
  For tree-sitter, please rely on the [releases](https://github.com/tree-sitter/tree-sitter/releases).
75
+
76
+ ${(0, doc_structure_1.block)({
77
+ type: 'NOTE',
78
+ content: 'The tree-sitter grammar may not be able to parse all valid R code due to some bugs in the parser grammar. In that case, please report these to the [tree-sitter-r repository](https://github.com/r-lib/tree-sitter-r).'
79
+ })}
62
80
  `;
63
81
  }
64
82
  }
@@ -47,17 +47,50 @@ type StaticKeys<T> = T extends {
47
47
  prototype: infer P;
48
48
  } ? Exclude<keyof T, keyof P> : never;
49
49
  export declare const ConstantWikiLinkInfo: {
50
- readonly 'flowr:npm': "https://www.npmjs.com/package/@eagleoutice/flowr";
51
- readonly 'flowr:github': string;
52
- readonly 'flowr:wiki': "https://github.com/flowr-analysis/flowr/wiki";
53
- readonly 'flowr:docker': "https://hub.docker.com/r/eagleoutice/flowr";
54
- readonly 'flowr:vscode': "https://marketplace.visualstudio.com/items?itemName=code-inspect.vscode-flowr";
55
- readonly 'flowr:positron': "https://open-vsx.org/extension/code-inspect/vscode-flowr";
56
- readonly 'flowr:rstudio-addin': "https://github.com/flowr-analysis/rstudio-addin-flowr";
57
- readonly 'flowr:radapter': "https://github.com/flowr-analysis/flowr-r-adapter";
58
- readonly 'flowr:benchmarks': "https://flowr-analysis.github.io/flowr/wiki/stats/benchmark";
59
- readonly 'flowr:docs': "https://flowr-analysis.github.io/flowr/docs";
60
- readonly 'flowr:zenodo': "https://zenodo.org/doi/10.5281/zenodo.13319290";
50
+ readonly 'flowr:npm': {
51
+ readonly url: "https://www.npmjs.com/package/@eagleoutice/flowr";
52
+ readonly name: "flowR on npm";
53
+ };
54
+ readonly 'flowr:github': {
55
+ readonly url: string;
56
+ readonly name: "flowR's GitHub";
57
+ };
58
+ readonly 'flowr:wiki': {
59
+ readonly url: "https://github.com/flowr-analysis/flowr/wiki";
60
+ readonly name: "flowR's wiki";
61
+ };
62
+ readonly 'flowr:docker': {
63
+ readonly url: "https://hub.docker.com/r/eagleoutice/flowr";
64
+ readonly name: "flowR's Docker Image";
65
+ };
66
+ readonly 'flowr:vscode': {
67
+ readonly url: "https://marketplace.visualstudio.com/items?itemName=code-inspect.vscode-flowr";
68
+ readonly name: "flowR extension for VS Code";
69
+ };
70
+ readonly 'flowr:positron': {
71
+ readonly url: "https://open-vsx.org/extension/code-inspect/vscode-flowr";
72
+ readonly name: "flowR extension for Positron";
73
+ };
74
+ readonly 'flowr:rstudio-addin': {
75
+ readonly url: "https://github.com/flowr-analysis/rstudio-addin-flowr";
76
+ readonly name: "flowR RStudio Addin";
77
+ };
78
+ readonly 'flowr:radapter': {
79
+ readonly url: "https://github.com/flowr-analysis/flowr-r-adapter";
80
+ readonly name: "flowR R Adapter";
81
+ };
82
+ readonly 'flowr:benchmarks': {
83
+ readonly url: "https://flowr-analysis.github.io/flowr/wiki/stats/benchmark";
84
+ readonly name: "flowR benchmark page";
85
+ };
86
+ readonly 'flowr:docs': {
87
+ readonly url: "https://flowr-analysis.github.io/flowr/docs";
88
+ readonly name: "flowR code docs";
89
+ };
90
+ readonly 'flowr:zenodo': {
91
+ readonly url: "https://zenodo.org/doi/10.5281/zenodo.13319290";
92
+ readonly name: "flowR on Zenodo";
93
+ };
61
94
  };
62
95
  /**
63
96
  * Provides methods to generate links, code snippets, and documentation for code elements.
@@ -23,17 +23,17 @@ function getNameFromElementIdOrRef(element) {
23
23
  }
24
24
  }
25
25
  exports.ConstantWikiLinkInfo = {
26
- 'flowr:npm': doc_files_1.FlowrNpmRef,
27
- 'flowr:github': doc_files_1.FlowrGithubRef,
28
- 'flowr:wiki': doc_files_1.FlowrWikiBaseRef,
29
- 'flowr:docker': doc_files_1.FlowrDockerRef,
30
- 'flowr:vscode': doc_files_1.FlowrVsCode,
31
- 'flowr:positron': doc_files_1.FlowrPositron,
32
- 'flowr:rstudio-addin': doc_files_1.FlowrRStudioAddin,
33
- 'flowr:radapter': doc_files_1.FlowrRAdapter,
34
- 'flowr:benchmarks': 'https://flowr-analysis.github.io/flowr/wiki/stats/benchmark',
35
- 'flowr:docs': 'https://flowr-analysis.github.io/flowr/docs',
36
- 'flowr:zenodo': 'https://zenodo.org/doi/10.5281/zenodo.13319290'
26
+ 'flowr:npm': { url: doc_files_1.FlowrNpmRef, name: 'flowR on npm' },
27
+ 'flowr:github': { url: doc_files_1.FlowrGithubRef, name: 'flowR\'s GitHub' },
28
+ 'flowr:wiki': { url: doc_files_1.FlowrWikiBaseRef, name: 'flowR\'s wiki' },
29
+ 'flowr:docker': { url: doc_files_1.FlowrDockerRef, name: 'flowR\'s Docker Image' },
30
+ 'flowr:vscode': { url: doc_files_1.FlowrVsCode, name: 'flowR extension for VS Code' },
31
+ 'flowr:positron': { url: doc_files_1.FlowrPositron, name: 'flowR extension for Positron' },
32
+ 'flowr:rstudio-addin': { url: doc_files_1.FlowrRStudioAddin, name: 'flowR RStudio Addin' },
33
+ 'flowr:radapter': { url: doc_files_1.FlowrRAdapter, name: 'flowR R Adapter' },
34
+ 'flowr:benchmarks': { url: 'https://flowr-analysis.github.io/flowr/wiki/stats/benchmark', name: 'flowR benchmark page' },
35
+ 'flowr:docs': { url: 'https://flowr-analysis.github.io/flowr/docs', name: 'flowR code docs' },
36
+ 'flowr:zenodo': { url: 'https://zenodo.org/doi/10.5281/zenodo.13319290', name: 'flowR on Zenodo' },
37
37
  };
38
38
  /**
39
39
  * Creates a wiki context for generating documentation for code elements.
@@ -100,14 +100,17 @@ function makeDocContextForTypes(shell, ...rootFolders) {
100
100
  });
101
101
  },
102
102
  linkPage(pageName, linkText, segment) {
103
- const text = linkText ?? pageName.split('/').pop() ?? pageName;
104
103
  let link;
104
+ let text = linkText;
105
105
  if (pageName in exports.ConstantWikiLinkInfo) {
106
- link = exports.ConstantWikiLinkInfo[pageName];
106
+ const i = exports.ConstantWikiLinkInfo[pageName];
107
+ link = i.url;
108
+ text ??= i.name;
107
109
  }
108
110
  else {
109
111
  link = `${doc_files_1.FlowrWikiBaseRef}/${pageName.toLowerCase().replace(/ /g, '-')}`;
110
112
  }
113
+ text ??= pageName.split('/').pop() ?? pageName;
111
114
  return `[${text}](${link}${segment ? `#${segment}` : ''})`;
112
115
  },
113
116
  linkCode(path, lineNumber) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eagleoutice/flowr",
3
- "version": "2.9.11",
3
+ "version": "2.9.12",
4
4
  "description": "Static Dataflow Analyzer and Program Slicer for the R Programming Language",
5
5
  "types": "dist/src/index.d.ts",
6
6
  "repository": {
@@ -13,6 +13,7 @@ exports.LibraryFunctions = [
13
13
  { package: 'easypackages', name: 'from_import', argIdx: 0, argName: 'package', resolveValue: true },
14
14
  { package: 'easypackages', name: 'libraries', argIdx: 'unnamed', resolveValue: true },
15
15
  { package: 'librarian', name: 'shelf', argIdx: 'unnamed', resolveValue: true },
16
- { package: 'devtools', name: 'load_all', argIdx: 0, argName: 'path', resolveValue: true }
16
+ { package: 'devtools', name: 'load_all', argIdx: 0, argName: 'path', resolveValue: true, defaultValue: '.' },
17
+ { package: 'devtools', name: 'load_code', argIdx: 0, argName: 'path', resolveValue: true, defaultValue: '.' },
17
18
  ];
18
19
  //# sourceMappingURL=library-functions.js.map
@@ -93,7 +93,7 @@ exports.ReadFunctions = [
93
93
  { package: 'XLConnect', name: 'loadWorkbook', argIdx: 0, argName: 'filename', resolveValue: true },
94
94
  { package: 'DiagrammeR', name: 'import_graph', argIdx: 0, argName: 'graph_file', resolveValue: true },
95
95
  { package: 'DiagrammeR', name: 'open_graph', argIdx: 0, argName: 'file', resolveValue: true },
96
- { package: 'highcharter', name: 'download_map_data', argIdx: 0, argName: 'url', resolveValue: true },
96
+ { package: 'highcharter', name: 'download_map_data', argIdx: 0, argName: 'url', resolveValue: true, defaultValue: 'custom/world.js' },
97
97
  { package: 'rvest', name: 'read_html', argIdx: 0, argName: 'x', resolveValue: true },
98
98
  { package: 'rvest', name: 'read_html_live', argIdx: 0, argName: 'url', resolveValue: true },
99
99
  { package: 'stats', name: 'read.ftable', argIdx: 0, argName: 'file', resolveValue: true },
@@ -9,5 +9,13 @@ exports.VisualizeFunctions =
9
9
  // plot creation
10
10
  default_builtin_config_1.GgPlotCreate.map(f => ({ package: 'ggplot2', name: f })).concat(default_builtin_config_1.TinyPlotCrate.map(f => ({ package: 'tinyplot', name: f })), default_builtin_config_1.GraphicsPlotCreate.map(f => ({ name: f })),
11
11
  // plot modification
12
- default_builtin_config_1.GgPlotImplicitAddons.concat(default_builtin_config_1.GgPlotAddons).map(f => ({ package: 'ggplot2', name: f, linkTo: LinkToPlotCreation })), default_builtin_config_1.TinyPlotAddons.map(f => ({ package: 'tinyplot', name: f, linkTo: LinkToPlotCreation })), default_builtin_config_1.GraphicsPlotAddons.map(f => ({ name: f, linkTo: LinkToPlotCreation })));
12
+ default_builtin_config_1.GgPlotImplicitAddons.concat(default_builtin_config_1.GgPlotAddons).map(f => ({ package: 'ggplot2', name: f, linkTo: LinkToPlotCreation })), default_builtin_config_1.TinyPlotAddons.map(f => ({ package: 'tinyplot', name: f, linkTo: LinkToPlotCreation })), default_builtin_config_1.GraphicsPlotAddons.map(f => ({ name: f, linkTo: LinkToPlotCreation }))).map(f => {
13
+ if (f.name !== 'hist') {
14
+ return f;
15
+ }
16
+ else {
17
+ // ignore if plot is false.
18
+ return { ...f, ignoreIf: 'arg-false', additionalArgs: { val: { argIdx: 17, argName: 'plot', resolveValue: true } } };
19
+ }
20
+ });
13
21
  //# sourceMappingURL=visualize-functions.js.map
@@ -115,5 +115,6 @@ exports.WriteFunctions = [
115
115
  { package: 'rpolars', name: 'write_csv', argIdx: 0, argName: 'file', resolveValue: true, ignoreIf: 'arg-missing' },
116
116
  { package: 'rpolars', name: 'write_ndjson', argIdx: 0, argName: 'file', resolveValue: true, ignoreIf: 'arg-missing' },
117
117
  { package: 'rpolars', name: 'write_parquet', argIdx: 0, argName: 'file', resolveValue: true, ignoreIf: 'arg-missing' },
118
+ { package: 'magick', name: 'image_write', argIdx: 1, argName: 'path', resolveValue: true, ignoreIf: 'arg-missing' },
118
119
  ];
119
120
  //# sourceMappingURL=write-functions.js.map
@@ -1,6 +1,7 @@
1
1
  import { type DataflowGraph } from '../../dataflow/graph/graph';
2
2
  import { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
3
3
  import { type IdentifierDefinition } from '../../dataflow/environments/identifier';
4
+ import { type DataflowGraphVertexInfo } from '../../dataflow/graph/vertex';
4
5
  import { type MermaidMarkdownMark, type MermaidMarkStyle } from './info';
5
6
  interface MermaidGraph {
6
7
  nodeLines: string[];
@@ -15,6 +16,13 @@ interface MermaidGraph {
15
16
  /** if given, the dataflow graph will only focus on the "important" parts */
16
17
  simplified?: boolean;
17
18
  }
19
+ /**
20
+ * Translates a vertex tag to the corresponding mermaid node brackets.
21
+ */
22
+ export declare function mermaidNodeBrackets(tag: DataflowGraphVertexInfo['tag']): {
23
+ open: string;
24
+ close: string;
25
+ };
18
26
  /**
19
27
  * Prints an identifier definition in a human-readable format.
20
28
  */
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mermaidNodeBrackets = mermaidNodeBrackets;
3
4
  exports.printIdentifier = printIdentifier;
4
5
  exports.graphToMermaid = graphToMermaid;
5
6
  exports.graphToMermaidUrl = graphToMermaidUrl;
@@ -89,6 +90,9 @@ function displayFunctionArgMapping(argMapping) {
89
90
  function encodeEdge(from, to, types) {
90
91
  return `${from}->${to}["${Array.from(types).join(':')}"]`;
91
92
  }
93
+ /**
94
+ * Translates a vertex tag to the corresponding mermaid node brackets.
95
+ */
92
96
  function mermaidNodeBrackets(tag) {
93
97
  let open;
94
98
  let close;
package/util/quads.js CHANGED
@@ -130,16 +130,24 @@ function processLiteralEntry(value, key, obj, quads, config, index) {
130
130
  }
131
131
  }
132
132
  function processObjectEntry(key, value, obj, quads, config) {
133
- if (config.ignore(key, value)) {
134
- return;
135
- }
136
- if (guardCycle(value)) {
133
+ if (config.ignore(key, value) || guardCycle(value)) {
137
134
  return;
138
135
  }
139
136
  if ((0, objects_1.isObjectOrArray)(value)) {
140
137
  if (Array.isArray(value)) {
141
138
  processArrayEntries(key, value, obj, quads, config);
142
139
  }
140
+ else if (value instanceof Map) {
141
+ for (const [mapKey, mapValue] of value.entries()) {
142
+ processObjectEntry('key-' + String(mapKey), mapValue, obj, quads, config);
143
+ }
144
+ }
145
+ else if (value instanceof Set) {
146
+ let i = 0;
147
+ for (const setValue of value.values()) {
148
+ processObjectEntry('idx-' + String(i++), setValue, obj, quads, config);
149
+ }
150
+ }
143
151
  else {
144
152
  processObjectEntries(key, value, obj, quads, config);
145
153
  }
@@ -152,10 +160,10 @@ let store = new Set();
152
160
  function guardCycle(obj) {
153
161
  // @ts-expect-error we do not care about the type here
154
162
  if ((0, objects_1.isObjectOrArray)(obj) && 'id' in obj) {
155
- if (store.has(obj.id)) {
163
+ if (store.has(obj)) {
156
164
  return true;
157
165
  }
158
- store.add(obj.id);
166
+ store.add(obj);
159
167
  }
160
168
  return false;
161
169
  }
package/util/range.d.ts CHANGED
@@ -16,6 +16,7 @@ export type SourcePosition = [
16
16
  * Utility functions for {@link SourcePosition|source positions}.
17
17
  */
18
18
  export declare const SourcePosition: {
19
+ readonly name: "SourcePosition";
19
20
  /**
20
21
  * Formats a {@link SourcePosition|source position} as a human-readable string.
21
22
  */
@@ -48,6 +49,7 @@ export type SourceRange = [
48
49
  * Utility functions for {@link SourceRange|source ranges}.
49
50
  */
50
51
  export declare const SourceRange: {
52
+ readonly name: "SourceRange";
51
53
  /**
52
54
  * Prints a {@link SourceRange|range} as a human-readable string.
53
55
  */
@@ -123,6 +125,7 @@ export type SourceLocation = [...r: SourceRange, f?: string];
123
125
  * Utility functions for {@link SourceLocation|source locations}.
124
126
  */
125
127
  export declare const SourceLocation: {
128
+ readonly name: "SourceLocation";
126
129
  /**
127
130
  * Formats a {@link SourceLocation|source location} as a human-readable string.
128
131
  */
package/util/range.js CHANGED
@@ -6,6 +6,7 @@ const assert_1 = require("./assert");
6
6
  * Utility functions for {@link SourcePosition|source positions}.
7
7
  */
8
8
  exports.SourcePosition = {
9
+ name: 'SourcePosition',
9
10
  /**
10
11
  * Formats a {@link SourcePosition|source position} as a human-readable string.
11
12
  */
@@ -36,6 +37,7 @@ exports.SourcePosition = {
36
37
  * Utility functions for {@link SourceRange|source ranges}.
37
38
  */
38
39
  exports.SourceRange = {
40
+ name: 'SourceRange',
39
41
  /**
40
42
  * Prints a {@link SourceRange|range} as a human-readable string.
41
43
  */
@@ -157,6 +159,7 @@ exports.SourceRange = {
157
159
  * Utility functions for {@link SourceLocation|source locations}.
158
160
  */
159
161
  exports.SourceLocation = {
162
+ name: 'SourceLocation',
160
163
  /**
161
164
  * Formats a {@link SourceLocation|source location} as a human-readable string.
162
165
  */
package/util/version.js CHANGED
@@ -6,7 +6,7 @@ exports.printVersionInformation = printVersionInformation;
6
6
  const semver_1 = require("semver");
7
7
  const assert_1 = require("./assert");
8
8
  // this is automatically replaced with the current version by release-it
9
- const version = '2.9.11';
9
+ const version = '2.9.12';
10
10
  /**
11
11
  * Retrieves the current flowR version as a new {@link SemVer} object.
12
12
  */