@eagleoutice/flowr 2.2.1 → 2.2.3
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/cli/flowr.js +2 -1
- package/cli/repl/commands/repl-cfg.js +30 -7
- package/cli/repl/commands/repl-dataflow.js +29 -6
- package/cli/repl/commands/repl-normalize.js +22 -2
- package/cli/repl/commands/repl-parse.js +50 -3
- package/cli/repl/core.js +4 -0
- package/cli/repl/print-version.d.ts +1 -0
- package/cli/repl/print-version.js +7 -2
- package/cli/repl/server/connection.js +11 -9
- package/cli/script-core/statistics-helper-core.js +1 -1
- package/config.js +8 -1
- package/core/pipeline-executor.d.ts +6 -0
- package/core/pipeline-executor.js +8 -0
- package/core/print/dataflow-printer.js +3 -0
- package/core/steps/all/core/01-parse-tree-sitter.d.ts +7 -0
- package/core/steps/pipeline/default-pipelines.d.ts +57 -47
- package/core/steps/pipeline/default-pipelines.js +23 -2
- package/core/steps/pipeline/pipeline.d.ts +1 -1
- package/core/steps/pipeline/pipeline.js +1 -1
- package/core/steps/pipeline-step.d.ts +1 -3
- package/dataflow/environments/resolve-by-name.d.ts +3 -2
- package/dataflow/environments/resolve-by-name.js +4 -4
- package/dataflow/extractor.d.ts +10 -0
- package/dataflow/extractor.js +11 -1
- package/dataflow/graph/dataflowgraph-builder.d.ts +11 -10
- package/dataflow/graph/dataflowgraph-builder.js +11 -10
- package/dataflow/graph/edge.d.ts +1 -1
- package/dataflow/graph/edge.js +2 -2
- package/dataflow/graph/vertex.d.ts +6 -6
- package/dataflow/graph/vertex.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +9 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +22 -6
- package/documentation/doc-util/doc-cfg.js +2 -2
- package/documentation/doc-util/doc-dfg.d.ts +5 -3
- package/documentation/doc-util/doc-dfg.js +10 -8
- package/documentation/doc-util/doc-files.d.ts +1 -1
- package/documentation/doc-util/doc-files.js +1 -1
- package/documentation/doc-util/doc-normalized-ast.d.ts +2 -1
- package/documentation/doc-util/doc-normalized-ast.js +4 -5
- package/documentation/doc-util/doc-repl.d.ts +6 -2
- package/documentation/doc-util/doc-repl.js +10 -6
- package/documentation/doc-util/doc-structure.d.ts +1 -1
- package/documentation/doc-util/doc-types.d.ts +7 -5
- package/documentation/doc-util/doc-types.js +17 -12
- package/documentation/index.d.ts +9 -0
- package/documentation/index.js +26 -0
- package/documentation/print-capabilities-markdown.js +105 -19
- package/documentation/print-core-wiki.d.ts +1 -0
- package/documentation/print-core-wiki.js +406 -0
- package/documentation/print-dataflow-graph-wiki.js +27 -27
- package/documentation/print-interface-wiki.js +1 -3
- package/documentation/print-linting-and-testing-wiki.js +26 -8
- package/documentation/print-normalized-ast-wiki.js +22 -17
- package/documentation/print-query-wiki.js +37 -7
- package/documentation/print-search-wiki.js +2 -1
- package/package.json +10 -7
- package/queries/catalog/call-context-query/call-context-query-executor.js +1 -1
- package/queries/catalog/happens-before-query/happens-before-query-executor.d.ts +1 -1
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -2
- package/queries/catalog/happens-before-query/happens-before-query-format.js +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +4 -0
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +34 -0
- package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +72 -0
- package/queries/catalog/resolve-value-query/resolve-value-query-format.js +49 -0
- package/queries/catalog/search-query/search-query-format.js +1 -1
- package/queries/query.d.ts +60 -1
- package/queries/query.js +3 -1
- package/r-bridge/data/data.d.ts +50 -9
- package/r-bridge/data/data.js +64 -10
- package/r-bridge/data/types.d.ts +7 -1
- package/r-bridge/lang-4.x/ast/model/processing/decorate.d.ts +2 -0
- package/r-bridge/lang-4.x/ast/model/processing/node-id.js +2 -5
- package/r-bridge/lang-4.x/ast/parser/json/format.d.ts +6 -0
- package/r-bridge/lang-4.x/ast/parser/json/format.js +6 -0
- package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +13 -2
- package/r-bridge/lang-4.x/ast/parser/json/parser.js +19 -3
- package/r-bridge/lang-4.x/ast/parser/main/internal/structure/normalize-root.d.ts +3 -0
- package/r-bridge/lang-4.x/ast/parser/main/internal/structure/normalize-root.js +3 -0
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +51 -29
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-types.d.ts +4 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-types.js +3 -0
- package/r-bridge/parser.d.ts +10 -0
- package/r-bridge/parser.js +26 -2
- package/search/flowr-search-builder.d.ts +1 -2
- package/search/flowr-search-builder.js +1 -3
- package/util/cfg/cfg.d.ts +10 -1
- package/util/cfg/cfg.js +56 -2
- package/util/mermaid/dfg.d.ts +3 -0
- package/util/mermaid/dfg.js +24 -8
- package/util/range.d.ts +21 -0
- package/util/range.js +3 -0
- package/util/strings.d.ts +9 -0
- package/util/strings.js +14 -0
- package/util/version.js +1 -1
|
@@ -92,7 +92,7 @@ async function getVertexExplanations(shell, vertexType) {
|
|
|
92
92
|
Describes a constant value (numbers, booleans/logicals, strings, ...).
|
|
93
93
|
In general, the respective vertex is more or less a dummy vertex as you can see from its implementation.
|
|
94
94
|
|
|
95
|
-
${(0, doc_types_1.printHierarchy)({ program: vertexType.program,
|
|
95
|
+
${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexType.info, root: 'DataflowGraphVertexValue' })}
|
|
96
96
|
|
|
97
97
|
${(0, doc_structure_1.block)({
|
|
98
98
|
type: 'NOTE',
|
|
@@ -122,7 +122,7 @@ Describes symbol/variable references which are read (or potentially read at a gi
|
|
|
122
122
|
Similar to the [value vertex](#value-vertex) described above, this is more a marker vertex as
|
|
123
123
|
you can see from the implementation.
|
|
124
124
|
|
|
125
|
-
${(0, doc_types_1.printHierarchy)({ program: vertexType.program,
|
|
125
|
+
${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexType.info, root: 'DataflowGraphVertexUse' })}
|
|
126
126
|
|
|
127
127
|
${(0, doc_structure_1.block)({
|
|
128
128
|
type: 'NOTE',
|
|
@@ -168,12 +168,12 @@ Describes any kind of function call, including unnamed calls and those that happ
|
|
|
168
168
|
In general the vertex provides you with information about
|
|
169
169
|
the _name_ of the called function, the passed _arguments_, and the _environment_ in which the call happens (if it is of importance).
|
|
170
170
|
|
|
171
|
-
However, the implementation reveals that it may hold an additional \`onlyBuiltin\` flag to indicate that the call is only calling builtin functions — however, this is only a flag to improve performance
|
|
171
|
+
However, the implementation reveals that it may hold an additional \`onlyBuiltin\` flag to indicate that the call is only calling builtin functions — however, this is only a flag to improve performance,
|
|
172
172
|
and it should not be relied on as it may under-approximate the actual calling targets (e.g., being \`false\` even though all calls resolve to builtins).
|
|
173
173
|
|
|
174
|
-
${(0, doc_types_1.printHierarchy)({ program: vertexType.program,
|
|
174
|
+
${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexType.info, root: 'DataflowGraphVertexFunctionCall' })}
|
|
175
175
|
The related function argument references are defined like this:
|
|
176
|
-
${(0, doc_types_1.printHierarchy)({ program: vertexType.program,
|
|
176
|
+
${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexType.info, root: 'FunctionArgument' })}
|
|
177
177
|
|
|
178
178
|
|
|
179
179
|
${(0, doc_structure_1.details)('Example: Simple Function Call (unresolved)', await (async () => {
|
|
@@ -214,7 +214,7 @@ In other words, we classify the references as ${(0, doc_general_1.lastJoin)(call
|
|
|
214
214
|
}), ', ', ', and ')}.
|
|
215
215
|
For more information on the types of references, please consult the implementation.
|
|
216
216
|
|
|
217
|
-
${(0, doc_types_1.printHierarchy)({ program: identifierType.program,
|
|
217
|
+
${(0, doc_types_1.printHierarchy)({ program: identifierType.program, info: identifierType.info, root: 'ReferenceType' })}
|
|
218
218
|
`;
|
|
219
219
|
})())}
|
|
220
220
|
|
|
@@ -289,7 +289,7 @@ However, they are actually linked with the call of the built-in function \`{\` (
|
|
|
289
289
|
|
|
290
290
|
${(0, doc_structure_1.details)('3) the function resolves to a mix of both', `
|
|
291
291
|
|
|
292
|
-
Users may write
|
|
292
|
+
Users may write… interesting pieces of code - for reasons we should not be interested in!
|
|
293
293
|
Consider a case in which you have a built-in function (like the assignment operator \`<-\`) and a user that wants to redefine the meaning of the function call _sometimes_:
|
|
294
294
|
|
|
295
295
|
${await (async () => {
|
|
@@ -333,7 +333,7 @@ Function calls are the most complicated mechanism in R as essentially everything
|
|
|
333
333
|
Even **control structures** like \`if(p) a else b\` are desugared into function calls (e.g., as \`if\`(p, a, b)).
|
|
334
334
|
${(0, doc_structure_1.details)('Example: <code>if</code> as a Function Call', await (0, doc_dfg_1.printDfGraphForCode)(shell, 'if(p) a else b'))}
|
|
335
335
|
|
|
336
|
-
Similarly you should be aware of calls to **anonymous functions**, which may appear given directly (e.g. as \`(function() 1)()\`) or indirectly, with code
|
|
336
|
+
Similarly, you should be aware of calls to **anonymous functions**, which may appear given directly (e.g. as \`(function() 1)()\`) or indirectly, with code
|
|
337
337
|
directly calling the return of another function call: \`foo()()\`.
|
|
338
338
|
${(0, doc_structure_1.details)('Example: Anonymous Function Call (given directly)', await (0, doc_dfg_1.printDfGraphForCode)(shell, '(function() 1)()', { mark: new Set([6, '6->4']) }))}
|
|
339
339
|
|
|
@@ -358,7 +358,7 @@ ${(0, doc_structure_1.details)('Example: Super Definition (<code><<-</code>)', a
|
|
|
358
358
|
|
|
359
359
|
The implementation is relatively sparse and similar to the other marker vertices:
|
|
360
360
|
|
|
361
|
-
${(0, doc_types_1.printHierarchy)({ program: vertexType.program,
|
|
361
|
+
${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexType.info, root: 'DataflowGraphVertexVariableDefinition' })}
|
|
362
362
|
|
|
363
363
|
Of course, there are not just operators that define variables, but also functions, like \`assign\`.
|
|
364
364
|
|
|
@@ -399,11 +399,11 @@ As you can see, _flowR_ is able to recognize that the initial definition of \`x\
|
|
|
399
399
|
Defining a function does do a lot of things: 1) it creates a new scope, 2) it may introduce parameters which act as promises and which are only evaluated if they are actually required in the body, 3) it may access the enclosing environments and the callstack.
|
|
400
400
|
The vertex object in the dataflow graph stores multiple things, including all exit points, the enclosing environment if necessary, and the information of the subflow (the "body" of the function).
|
|
401
401
|
|
|
402
|
-
${(0, doc_types_1.printHierarchy)({ program: vertexType.program,
|
|
402
|
+
${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexType.info, root: 'DataflowGraphVertexFunctionDefinition' })}
|
|
403
403
|
The subflow is defined like this:
|
|
404
|
-
${(0, doc_types_1.printHierarchy)({ program: vertexType.program,
|
|
404
|
+
${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexType.info, root: 'DataflowFunctionFlowInformation' })}
|
|
405
405
|
And if you are interested in the exit points, they are defined like this:
|
|
406
|
-
${(0, doc_types_1.printHierarchy)({ program: vertexType.program,
|
|
406
|
+
${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexType.info, root: 'ExitPoint' })}
|
|
407
407
|
|
|
408
408
|
|
|
409
409
|
Whenever we visualize a function definition, we use a dedicated node to represent the anonymous function object,
|
|
@@ -481,7 +481,7 @@ Besides this being a theoretically "shorter" way of defining a function, this be
|
|
|
481
481
|
}
|
|
482
482
|
return results.join('\n');
|
|
483
483
|
}
|
|
484
|
-
async function getEdgesExplanations(shell) {
|
|
484
|
+
async function getEdgesExplanations(shell, vertexType) {
|
|
485
485
|
const edgeExplanations = new Map();
|
|
486
486
|
edgeExplanations.set(edge_1.EdgeType.Reads, [{
|
|
487
487
|
shell,
|
|
@@ -495,8 +495,8 @@ ${(0, doc_structure_1.block)({
|
|
|
495
495
|
content: `
|
|
496
496
|
A ${linkEdgeName(edge_1.EdgeType.Reads)} edge is not a transitive closure and only links the "directly read" definition(s).
|
|
497
497
|
Our abstract domains resolving transitive ${linkEdgeName(edge_1.EdgeType.Reads)} edges (and for that matter, following ${linkEdgeName(edge_1.EdgeType.Returns)} as well)
|
|
498
|
-
are currently tailored to what we need in _flowR_. Hence we offer a function like
|
|
499
|
-
as well as
|
|
498
|
+
are currently tailored to what we need in _flowR_. Hence, we offer a function like ${(0, doc_types_1.shortLink)(linker_1.getAllFunctionCallTargets.name, vertexType.info)} (defined in ${(0, doc_files_1.getFilePathMd)('../dataflow/internal/linker.ts')}),
|
|
499
|
+
as well as ${(0, doc_types_1.shortLink)(resolve_by_name_1.resolvesToBuiltInConstant.name, vertexType.info)} (defined in ${(0, doc_files_1.getFilePathMd)('../dataflow/environments/resolve-by-name.ts')}) which do this for specific cases.
|
|
500
500
|
|
|
501
501
|
${(0, doc_structure_1.details)('Example: Multi-Level Reads', await (0, doc_dfg_1.printDfGraphForCode)(shell, 'x <- 3\ny <- x\nprint(y)', { mark: new Set(['9->7', '7->3', '4->0']) }))}
|
|
502
502
|
|
|
@@ -557,7 +557,7 @@ However, nested definitions can carry it (in the nested case, \`x\` is defined b
|
|
|
557
557
|
shell,
|
|
558
558
|
name: 'Returns Edge',
|
|
559
559
|
type: edge_1.EdgeType.Returns,
|
|
560
|
-
description: 'Link the [function call](#function-call-vertex)
|
|
560
|
+
description: 'Link the [function call](#function-call-vertex) to the exit points of the target definition (this may incorporate the call-context).',
|
|
561
561
|
code: 'foo <- function() x\nfoo()',
|
|
562
562
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().returns('2@foo', '1@x')
|
|
563
563
|
}, []]);
|
|
@@ -582,7 +582,7 @@ f()
|
|
|
582
582
|
|
|
583
583
|
${dfInfo}
|
|
584
584
|
|
|
585
|
-
The final call evaluates to \`3\` (similar to if we
|
|
585
|
+
The final call evaluates to \`3\` (similar to if we defined \`x\` before the function definition).
|
|
586
586
|
Within a dataflow graph you can see this with two edges. The \`x\` within the function body will have a ${linkEdgeName(edge_1.EdgeType.DefinedByOnCall)}
|
|
587
587
|
to every definition it _may_ refer to. In turn, each call vertex calling the function which encloses the use of \`x\` will have a
|
|
588
588
|
${linkEdgeName(edge_1.EdgeType.DefinesOnCall)} edge to the definition(s) it causes to be active within the function body.
|
|
@@ -607,7 +607,7 @@ ${dfInfo}
|
|
|
607
607
|
type: edge_1.EdgeType.Argument,
|
|
608
608
|
description: `Links a [function call](#function-call-vertex) to the entry point of its arguments. If we do not know the target of such a call, we automatically assume that all arguments are read by the call as well!
|
|
609
609
|
|
|
610
|
-
The exception to this is the [function definition](#function-definition-vertex) which does no longer hold these argument relationships (as they are
|
|
610
|
+
The exception to this is the [function definition](#function-definition-vertex) which does no longer hold these argument relationships (as they are not implicit in the structure).
|
|
611
611
|
`,
|
|
612
612
|
code: 'f(x,y)',
|
|
613
613
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().argument('1@f', '1@x').reads('1@f', '1@x').argument('1@f', '1@y').reads('1@f', '1@y')
|
|
@@ -678,7 +678,7 @@ async function getText(shell) {
|
|
|
678
678
|
const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
|
|
679
679
|
/* we collect type information on the graph */
|
|
680
680
|
const vertexType = (0, doc_types_1.getTypesFromFolderAsMermaid)({
|
|
681
|
-
|
|
681
|
+
rootFolder: path_1.default.resolve('./src/'),
|
|
682
682
|
typeName: 'DataflowGraphVertexInfo',
|
|
683
683
|
inlineTypes: ['MergeableRecord']
|
|
684
684
|
});
|
|
@@ -689,8 +689,8 @@ async function getText(shell) {
|
|
|
689
689
|
});
|
|
690
690
|
return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'dataflow graph', rVersion: rversion })}
|
|
691
691
|
|
|
692
|
-
This page briefly summarizes flowR's dataflow graph, represented by ${(0, doc_types_1.shortLink)(
|
|
693
|
-
In case you want to manually build such a graph (e.g., for testing), you can use the
|
|
692
|
+
This page briefly summarizes flowR's dataflow graph, represented by the ${(0, doc_types_1.shortLink)(graph_1.DataflowGraph.name, vertexType.info)}.
|
|
693
|
+
In case you want to manually build such a graph (e.g., for testing), you can use the ${(0, doc_types_1.shortLink)(dataflowgraph_builder_1.DataflowGraphBuilder.name, vertexType.info)}.
|
|
694
694
|
This wiki page focuses on explaining what such a dataflow graph looks like!
|
|
695
695
|
|
|
696
696
|
Please be aware that the accompanied [dataflow information](#dataflow-information) returned by _flowR_ contains things besides the graph,
|
|
@@ -702,7 +702,7 @@ Additionally, you may be interested in the set of [Unknown Side Effects](#unknow
|
|
|
702
702
|
> you can either use the [Visual Studio Code extension](${doc_files_1.FlowrGithubBaseRef}/vscode-flowr) or the ${(0, doc_cli_option_1.getReplCommand)('dataflow*')}
|
|
703
703
|
> command in the REPL (see the [Interface wiki page](${doc_files_1.FlowrWikiBaseRef}/Interface) for more information). When using _flowR_ as a library, you may use the functions in ${(0, doc_files_1.getFilePathMd)('../util/mermaid/dfg.ts')}.
|
|
704
704
|
>
|
|
705
|
-
> 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
|
|
705
|
+
> 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 ${(0, doc_types_1.shortLink)(`${graph_1.DataflowGraph.name}::${graph_1.DataflowGraph.fromJson.name}`, vertexType.info, true, 'i')} to retrieve the graph from the JSON representation.
|
|
706
706
|
|
|
707
707
|
${await (0, doc_dfg_1.printDfGraphForCode)(shell, 'x <- 3\ny <- x + 1\ny')}
|
|
708
708
|
|
|
@@ -743,9 +743,9 @@ The following sections present details on the different types of vertices and ed
|
|
|
743
743
|
> [!NOTE]
|
|
744
744
|
> Every dataflow vertex holds an \`id\` which links it to the respective node in the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized%20AST).
|
|
745
745
|
> So if you want more information about the respective vertex, you can usually access more information
|
|
746
|
-
> using the
|
|
746
|
+
> using the <code>${(0, doc_types_1.shortLink)(`${graph_1.DataflowGraph.name}`, vertexType.info, false, 'i')}::idMap</code> linked to the dataflow graph:
|
|
747
747
|
${(0, doc_general_1.prefixLines)((0, doc_code_1.codeBlock)('ts', 'const node = graph.idMap.get(id);'), '> ')}
|
|
748
|
-
> In case you just need the name (\`lexeme\`) of the respective vertex, ${
|
|
748
|
+
> In case you just need the name (\`lexeme\`) of the respective vertex, ${(0, doc_types_1.shortLink)(node_id_1.recoverName.name, vertexType.info)} can help you out:
|
|
749
749
|
${(0, doc_general_1.prefixLines)((0, doc_code_1.codeBlock)('ts', `const name = ${node_id_1.recoverName.name}(id, graph.idMap);`), '> ')}
|
|
750
750
|
|
|
751
751
|
## Vertices
|
|
@@ -754,7 +754,7 @@ ${await getVertexExplanations(shell, vertexType)}
|
|
|
754
754
|
|
|
755
755
|
## Edges
|
|
756
756
|
|
|
757
|
-
${await getEdgesExplanations(shell)}
|
|
757
|
+
${await getEdgesExplanations(shell, vertexType)}
|
|
758
758
|
|
|
759
759
|
## Control Dependencies
|
|
760
760
|
|
|
@@ -778,7 +778,7 @@ ${(0, doc_structure_1.details)('Example: Nested Conditionals', await (0, doc_dfg
|
|
|
778
778
|
## Dataflow Information
|
|
779
779
|
|
|
780
780
|
Using _flowR's_ code interface (see the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface) wiki page for more), you can generate the dataflow information
|
|
781
|
-
for a given piece of R code (in this case \`x <- 1; x + 1\`) as follows:
|
|
781
|
+
for a given piece of R code (in this case \`x <- 1; x + 1\`) as follows (using the ${(0, doc_types_1.shortLink)(shell_1.RShell.name, vertexType.info)} and the ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, vertexType.info)} classes):
|
|
782
782
|
|
|
783
783
|
${(0, doc_code_1.codeBlock)('ts', `
|
|
784
784
|
const shell = new ${shell_1.RShell.name}()
|
|
@@ -821,7 +821,7 @@ ${(0, doc_code_1.codeBlock)('text', JSON.stringify(result.dataflow, json_1.jsonR
|
|
|
821
821
|
|
|
822
822
|
You may be interested in its implementation:
|
|
823
823
|
|
|
824
|
-
${(0, doc_types_1.printHierarchy)({ program: vertexType.program,
|
|
824
|
+
${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexType.info, root: 'DataflowInformation' })}
|
|
825
825
|
|
|
826
826
|
Let's start by looking at the properties of the dataflow information object: ${Object.keys(result.dataflow).map(k => `\`${k}\``).join(', ')}.
|
|
827
827
|
|
|
@@ -133,7 +133,7 @@ use ${(0, doc_cli_option_1.getReplCommand)('dataflow*')} (or ${(0, doc_cli_optio
|
|
|
133
133
|
|
|
134
134
|
${await (0, doc_repl_1.documentReplSession)(shell, [{
|
|
135
135
|
command: ':dataflow* y <- 1 + x',
|
|
136
|
-
description: `Retrieve the dataflow graph of the expression \`y <- 1 + x\`. It looks like this:\n${await (0, doc_dfg_1.printDfGraphForCode)(shell, 'y <- 1 + x')}
|
|
136
|
+
description: `Retrieve the dataflow graph of the expression \`y <- 1 + x\`. It looks like this:\n${await (0, doc_dfg_1.printDfGraphForCode)(shell, 'y <- 1 + x')}`
|
|
137
137
|
}])}
|
|
138
138
|
|
|
139
139
|
For the slicing with ${(0, doc_cli_option_1.getReplCommand)('slicer')}, you have access to the same [magic comments](#slice-magic-comments) as with the [slice request](#message-request-slice).
|
|
@@ -175,7 +175,6 @@ ${(0, doc_code_1.codeBlock)('shell', ':query @config')}
|
|
|
175
175
|
The following summarizes the configuration options:
|
|
176
176
|
|
|
177
177
|
- \`ignoreSourceCalls\`: If set to \`true\`, _flowR_ will ignore source calls when analyzing the code, i.e., ignoring the inclusion of other files.
|
|
178
|
-
- \`rPath\`: The path to the R executable. If not set, _flowR_ will try to find the R executable in the system's PATH.
|
|
179
178
|
- \`semantics\`: allows to configure the way _flowR_ handles R, although we currently only support \`semantics/environment/overwriteBuiltIns\`.
|
|
180
179
|
You may use this to overwrite _flowR_'s handling of built-in function and even completely clear the preset definitions shipped with flowR.
|
|
181
180
|
See [Configure BuiltIn Semantics](#configure-builtin-semantics) for more information.
|
|
@@ -191,7 +190,6 @@ So you can configure _flowR_ by adding a file like the following:
|
|
|
191
190
|
|
|
192
191
|
${(0, doc_code_1.codeBlock)('json', JSON.stringify({
|
|
193
192
|
ignoreSourceCalls: true,
|
|
194
|
-
rPath: '/usr/bin/R',
|
|
195
193
|
semantics: {
|
|
196
194
|
environment: {
|
|
197
195
|
overwriteBuiltIns: {
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
const log_1 = require("../../test/functionality/_helper/log");
|
|
4
7
|
const doc_code_1 = require("./doc-util/doc-code");
|
|
5
8
|
const doc_files_1 = require("./doc-util/doc-files");
|
|
6
9
|
const doc_structure_1 = require("./doc-util/doc-structure");
|
|
10
|
+
const doc_types_1 = require("./doc-util/doc-types");
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
7
12
|
function getText() {
|
|
13
|
+
const { info } = (0, doc_types_1.getTypesFromFolderAsMermaid)({
|
|
14
|
+
rootFolder: path_1.default.resolve('./test'),
|
|
15
|
+
files: [path_1.default.resolve('./src/dataflow/graph/dataflowgraph-builder.ts')],
|
|
16
|
+
typeName: 'parameter',
|
|
17
|
+
inlineTypes: doc_types_1.mermaidHide
|
|
18
|
+
});
|
|
8
19
|
return `
|
|
9
20
|
For the latest code coverage information, see [codecov.io](${doc_files_1.FlowrCodecovRef}),
|
|
10
21
|
for the latest benchmark results, see the [benchmark results](${doc_files_1.FlowrSiteBaseRef}/wiki/stats/benchmark) wiki page.
|
|
@@ -53,7 +64,7 @@ If you want to run the tests without the watch mode, you can use:
|
|
|
53
64
|
|
|
54
65
|
${(0, doc_code_1.codeBlock)('shell', 'npm run test -- --no-watch')}
|
|
55
66
|
|
|
56
|
-
To run all tests, including a coverage report and label summary, run:
|
|
67
|
+
To run all tests, including a coverage report and label summary, run:
|
|
57
68
|
|
|
58
69
|
${(0, doc_code_1.codeBlock)('shell', 'npm run test-full')}
|
|
59
70
|
|
|
@@ -64,7 +75,7 @@ It is up to the [ci](#ci-pipeline) to run the tests on different systems to ensu
|
|
|
64
75
|
|
|
65
76
|
#### Test Structure
|
|
66
77
|
|
|
67
|
-
All functionality tests are to be located under [test/functionality](${doc_files_1.RemoteFlowrFilePathBaseRef}test/functionality).
|
|
78
|
+
All functionality tests are to be located under [test/functionality](${doc_files_1.RemoteFlowrFilePathBaseRef}/test/functionality).
|
|
68
79
|
|
|
69
80
|
This folder contains three special and important elements:
|
|
70
81
|
|
|
@@ -76,19 +87,23 @@ ${(0, doc_structure_1.block)({
|
|
|
76
87
|
type: 'WARNING',
|
|
77
88
|
content: `
|
|
78
89
|
We name all test files using the \`.test.ts\` suffix and try to run them in parallel.
|
|
79
|
-
Whenever this is
|
|
90
|
+
Whenever this is impossible (e.g., when using ${(0, doc_types_1.shortLink)('withShell', info)}), please use _\`describe.sequential\`_
|
|
80
91
|
to disable parallel execution for the respective test (otherwise, such tests are flaky).
|
|
81
92
|
`
|
|
82
93
|
})}
|
|
83
94
|
|
|
84
95
|
#### Writing a Test
|
|
85
96
|
|
|
86
|
-
Currently, this is heavily dependent on what you want to test (normalization, dataflow, quad-export,
|
|
97
|
+
Currently, this is heavily dependent on what you want to test (normalization, dataflow, quad-export, …)
|
|
87
98
|
and it is probably best to have a look at existing tests in that area to get an idea of what comfort functionality is available.
|
|
88
99
|
|
|
89
|
-
Generally, tests should be [labeled](${doc_files_1.RemoteFlowrFilePathBaseRef}test/functionality/_helper/label.ts) according to the *flowR* capabilities they test.
|
|
100
|
+
Generally, tests should be [labeled](${doc_files_1.RemoteFlowrFilePathBaseRef}test/functionality/_helper/label.ts) according to the *flowR* capabilities they test.
|
|
101
|
+
The set of currently supported capabilities and their IDs can be found in ${(0, doc_files_1.getFilePathMd)('../r-bridge/data/data.ts')}.
|
|
102
|
+
The resulting labels are used in the test report that is generated as part of the test output.
|
|
103
|
+
They group tests by the capabilities they test and allow the report to display how many tests ensure that any given capability is properly supported.
|
|
90
104
|
|
|
91
|
-
Various helper functions are available to ease in writing tests with common behaviors, like testing for dataflow, slicing or query results.
|
|
105
|
+
Various helper functions are available to ease in writing tests with common behaviors, like testing for dataflow, slicing or query results.
|
|
106
|
+
These can be found in [the \`_helper\` subdirectory](${doc_files_1.RemoteFlowrFilePathBaseRef}test/functionality/_helper).
|
|
92
107
|
|
|
93
108
|
For example, an [existing test](${doc_files_1.RemoteFlowrFilePathBaseRef}test/functionality/dataflow/processing-of-elements/atomic/dataflow-atomic.test.ts) that tests the dataflow graph of a simple variable looks like this:
|
|
94
109
|
${(0, doc_code_1.codeBlock)('typescript', `
|
|
@@ -96,11 +111,14 @@ assertDataflow(label('simple variable', ['name-normal']), shell,
|
|
|
96
111
|
'x', emptyGraph().use('0', 'x')
|
|
97
112
|
);
|
|
98
113
|
`)}
|
|
114
|
+
Have a look at ${(0, doc_types_1.shortLink)('assertDataflow', info)}, ${(0, doc_types_1.shortLink)('label', info)}, and ${(0, doc_types_1.shortLink)('emptyGraph', info)} for more information.
|
|
99
115
|
|
|
100
116
|
When writing dataflow tests, additional settings can be used to reduce the amount of graph data that needs to be pre-written. Notably:
|
|
101
117
|
|
|
102
|
-
-
|
|
103
|
-
|
|
118
|
+
- ${(0, doc_types_1.shortLink)('expectIsSubgraph', info)} indicates that the expected graph is a subgraph, rather than the full graph that the test should generate.
|
|
119
|
+
The test will then only check if the supplied graph is contained in the result graph, rather than an exact match.
|
|
120
|
+
- ${(0, doc_types_1.shortLink)('resolveIdsAsCriterion', info)} indicates that the ids given in the expected (sub)graph should be resolved as [slicing criteria](${doc_files_1.FlowrWikiBaseRef}/Terminology#slicing-criterion) rather than actual ids.
|
|
121
|
+
For example, passing \`12@a\` as an id in the expected (sub)graph will cause it to be resolved as the corresponding id.
|
|
104
122
|
|
|
105
123
|
The following example shows both in use:
|
|
106
124
|
${(0, doc_code_1.codeBlock)('typescript', `
|
|
@@ -19,21 +19,21 @@ const retriever_1 = require("../r-bridge/retriever");
|
|
|
19
19
|
const visitor_1 = require("../r-bridge/lang-4.x/ast/model/processing/visitor");
|
|
20
20
|
const collect_1 = require("../r-bridge/lang-4.x/ast/model/collect");
|
|
21
21
|
const normalized_ast_fold_1 = require("../abstract-interpretation/normalized-ast-fold");
|
|
22
|
+
const default_pipelines_1 = require("../core/steps/pipeline/default-pipelines");
|
|
22
23
|
async function getText(shell) {
|
|
23
24
|
const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
|
|
24
25
|
const now = performance.now();
|
|
25
26
|
const types = (0, doc_types_1.getTypesFromFolderAsMermaid)({
|
|
26
|
-
rootFolder: path_1.default.resolve('./src
|
|
27
|
-
files: [path_1.default.resolve('./src/abstract-interpretation/normalized-ast-fold.ts'), path_1.default.resolve('./src/core/steps/pipeline/default-pipelines.ts')],
|
|
27
|
+
rootFolder: path_1.default.resolve('./src'),
|
|
28
28
|
typeName: 'RNode',
|
|
29
29
|
inlineTypes: doc_types_1.mermaidHide
|
|
30
30
|
});
|
|
31
31
|
const elapsed = performance.now() - now;
|
|
32
32
|
return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'normalized ast', rVersion: rversion })}
|
|
33
33
|
|
|
34
|
-
_flowR_ produces a normalized version of R's abstract syntax tree (AST),
|
|
34
|
+
_flowR_ produces a normalized version of R's abstract syntax tree (AST),
|
|
35
35
|
offering the following benefits:
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
1. abstract away from intricacies of the R parser
|
|
38
38
|
2. provide a version-independent representation of the program
|
|
39
39
|
3. decorate the AST with additional information, e.g., parent relations and nesting information
|
|
@@ -49,12 +49,10 @@ Each edge is labeled with the type of the parent-child relationship (the "role")
|
|
|
49
49
|
|
|
50
50
|
${await (0, doc_normalized_ast_1.printNormalizedAstForCode)(shell, 'x <- 2 * 3 + 1', { showCode: false, prefix: 'flowchart LR\n' })}
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
52
|
> [!TIP]
|
|
55
53
|
> If you want to investigate the normalized AST,
|
|
56
54
|
> you can either use the [Visual Studio Code extension](${doc_files_1.FlowrGithubBaseRef}/vscode-flowr) or the ${(0, doc_cli_option_1.getReplCommand)('normalize*')}
|
|
57
|
-
> command in the REPL (see the [Interface wiki page](${doc_files_1.FlowrWikiBaseRef}/Interface) for more information).
|
|
55
|
+
> command in the REPL (see the [Interface wiki page](${doc_files_1.FlowrWikiBaseRef}/Interface) for more information).
|
|
58
56
|
|
|
59
57
|
Indicative of the normalization is the root expression list node, which is present in every normalized AST.
|
|
60
58
|
In general, we provide node types for:
|
|
@@ -84,7 +82,7 @@ Most notably, the \`info\` field holds the \`id\` of the node, which is used to
|
|
|
84
82
|
|
|
85
83
|
In summary, we have the following types:
|
|
86
84
|
|
|
87
|
-
${(0, doc_structure_1.details)('Normalized AST Node Types', (0, doc_types_1.printHierarchy)({ program: types.program,
|
|
85
|
+
${(0, doc_structure_1.details)('Normalized AST Node Types', (0, doc_types_1.printHierarchy)({ program: types.program, info: types.info, root: 'RNode', collapseFromNesting: Number.MAX_VALUE }))}
|
|
88
86
|
|
|
89
87
|
The following segments intend to give you an overview of how to work with the normalized AST:
|
|
90
88
|
|
|
@@ -94,7 +92,7 @@ The following segments intend to give you an overview of how to work with the no
|
|
|
94
92
|
## How Get a Normalized AST
|
|
95
93
|
|
|
96
94
|
As explained alongside the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface#the-pipeline-executor) wiki page, you can use the
|
|
97
|
-
|
|
95
|
+
${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, types.info)} to get the ${(0, doc_types_1.shortLink)('NormalizedAst', types.info)}. If you are only interested in the normalization,
|
|
98
96
|
a pipeline like the ${(0, doc_types_1.shortLink)('DEFAULT_NORMALIZE_PIPELINE', types.info)} suffices:
|
|
99
97
|
|
|
100
98
|
${(0, doc_code_1.codeBlock)('ts', `
|
|
@@ -106,7 +104,7 @@ async function getAst(code: string): Promise<RNode> {
|
|
|
106
104
|
return result.normalize.ast;
|
|
107
105
|
}`)}
|
|
108
106
|
|
|
109
|
-
From the REPL, you can use the ${(0, doc_cli_option_1.getReplCommand)('normalize')} command.
|
|
107
|
+
From the REPL, you can use the ${(0, doc_cli_option_1.getReplCommand)('normalize')} command.
|
|
110
108
|
|
|
111
109
|
## Traversing the Normalized AST
|
|
112
110
|
|
|
@@ -114,12 +112,11 @@ We provide two ways to traverse the normalized AST: [Visitors](#visitors) and [F
|
|
|
114
112
|
|
|
115
113
|
### Visitors
|
|
116
114
|
|
|
117
|
-
If you want a simple visitor which traverses the AST, the
|
|
118
|
-
${(0, doc_files_1.getFilePathMd)('../r-bridge/lang-4.x/ast/model/processing/visitor.ts')} is a good starting point.
|
|
115
|
+
If you want a simple visitor which traverses the AST, the ${(0, doc_types_1.shortLink)(visitor_1.visitAst.name, types.info)} function is a good starting point.
|
|
119
116
|
You may specify functions to be called whenever you enter and exit a node during the traversal, and any
|
|
120
117
|
computation is to be done by side effects.
|
|
121
118
|
For example, if you want to collect all the \`id\`s present within a normalized (sub-)ast,
|
|
122
|
-
as it is done by the ${collect_1.collectAllIds.name} function, you can use the following visitor:
|
|
119
|
+
as it is done by the ${(0, doc_types_1.shortLink)(collect_1.collectAllIds.name, types.info)} function, you can use the following visitor:
|
|
123
120
|
|
|
124
121
|
${(0, doc_code_1.codeBlock)('ts', `
|
|
125
122
|
const ids = new Set<NodeId>();
|
|
@@ -131,12 +128,12 @@ return ids;
|
|
|
131
128
|
|
|
132
129
|
### Folds
|
|
133
130
|
|
|
134
|
-
We formulate a fold with the base class
|
|
131
|
+
We formulate a fold with the base class ${(0, doc_types_1.shortLink)(normalized_ast_fold_1.DefaultNormalizedAstFold.name, types.info)} in ${(0, doc_files_1.getFilePathMd)('../abstract-interpretation/normalized-ast-fold.ts')}.
|
|
135
132
|
Using this class, you can create your own fold behavior by overwriting the default methods.
|
|
136
133
|
By default, the class provides a monoid abstraction using the _empty_ from the constructor and the _concat_ method.
|
|
137
134
|
|
|
138
135
|
|
|
139
|
-
${(0, doc_types_1.printHierarchy)({ program: types.program,
|
|
136
|
+
${(0, doc_types_1.printHierarchy)({ program: types.program, info: types.info, root: 'DefaultNormalizedAstFold' })}
|
|
140
137
|
|
|
141
138
|
Now, of course, we could provide hundreds of examples here, but we use tests to verify that the fold behaves as expected
|
|
142
139
|
and happily point to them at ${(0, doc_files_1.getFilePathMd)('../../test/functionality/r-bridge/normalize-ast-fold.test.ts')}.
|
|
@@ -173,8 +170,8 @@ class MyMathFold<Info> extends ${normalized_ast_fold_1.DefaultNormalizedAstFold.
|
|
|
173
170
|
}
|
|
174
171
|
`)}
|
|
175
172
|
|
|
176
|
-
Now, we can use the
|
|
177
|
-
|
|
173
|
+
Now, we can use the ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, types.info)} to get the normalized AST and apply the fold:
|
|
174
|
+
|
|
178
175
|
${(0, doc_code_1.codeBlock)('ts', `
|
|
179
176
|
const shell = new ${shell_1.RShell.name}();
|
|
180
177
|
const ast = (await new ${pipeline_executor_1.PipelineExecutor.name}(DEFAULT_NORMALIZE_PIPELINE, {
|
|
@@ -185,6 +182,14 @@ const result = new MyMathFold().fold(ast);
|
|
|
185
182
|
console.log(result); // -> 7
|
|
186
183
|
`)}
|
|
187
184
|
|
|
185
|
+
${(0, doc_structure_1.block)({
|
|
186
|
+
type: 'NOTE',
|
|
187
|
+
content: `
|
|
188
|
+
If you want to retrieve the normalized AST with the [Tree-Sitter Engine](${doc_files_1.FlowrWikiBaseRef}/Engines),
|
|
189
|
+
you may use the ${(0, doc_types_1.shortLink)('TREE_SITTER_NORMALIZE_PIPELINE', types.info)} or directly rely on one of the
|
|
190
|
+
helper functions like ${(0, doc_types_1.shortLink)(default_pipelines_1.createNormalizePipeline.name, types.info)}.
|
|
191
|
+
`
|
|
192
|
+
})}
|
|
188
193
|
`;
|
|
189
194
|
}
|
|
190
195
|
/** if we run this script, we want a Markdown representation of the capabilities */
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
const shell_1 = require("../r-bridge/shell");
|
|
4
7
|
const doc_dfg_1 = require("./doc-util/doc-dfg");
|
|
@@ -29,6 +32,8 @@ const config_query_executor_1 = require("../queries/catalog/config-query/config-
|
|
|
29
32
|
const search_query_executor_1 = require("../queries/catalog/search-query/search-query-executor");
|
|
30
33
|
const flowr_search_builder_1 = require("../search/flowr-search-builder");
|
|
31
34
|
const vertex_1 = require("../dataflow/graph/vertex");
|
|
35
|
+
const doc_types_1 = require("./doc-util/doc-types");
|
|
36
|
+
const path_1 = __importDefault(require("path"));
|
|
32
37
|
(0, doc_query_1.registerQueryDocumentation)('call-context', {
|
|
33
38
|
name: 'Call-Context Query',
|
|
34
39
|
type: 'active',
|
|
@@ -54,9 +59,9 @@ Besides this, we provide the following ways to automatically categorize and link
|
|
|
54
59
|
It's also possible to filter the results based on the following properties:
|
|
55
60
|
|
|
56
61
|
1. **File** (\`fileFilter\`): This allows you to filter the results based on the file in which the call is located. This can be useful if you are only interested in calls in, e.g., specific folders.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
The \`fileFilter\` property is an object made up of two properties:
|
|
63
|
+
- **Filter** (\`filter\`): A regular expression that a node's file attribute must match to be considered.
|
|
64
|
+
- **Include Undefined Files** (\`includeUndefinedFiles\`): If \`fileFilter\` is set, but a node's file attribute is not present, should we include it in the results? Defaults to \`true\`.
|
|
60
65
|
|
|
61
66
|
Re-using the example code from above, the following query attaches all calls to \`mean\` to the kind \`visualize\` and the subkind \`text\`,
|
|
62
67
|
all calls that start with \`read_\` to the kind \`input\` but only if they are not locally overwritten, and the subkind \`csv-file\`, and links all calls to \`points\` to the last call to \`plot\`:
|
|
@@ -159,7 +164,7 @@ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
|
|
|
159
164
|
}], { showCode: false })}
|
|
160
165
|
|
|
161
166
|
In this simple scenario, the _lineage_ is equivalent to the slice (and in-fact the complete code).
|
|
162
|
-
In general the lineage is smaller and makes no executability
|
|
167
|
+
In general the lineage is smaller and makes no guarantees on executability.
|
|
163
168
|
It is just a quick and neither complete nor sound way to get information on where the variable originates from.
|
|
164
169
|
|
|
165
170
|
This query replaces the old [\`request-lineage\`](${doc_files_1.FlowrWikiBaseRef}/Interface#message-request-lineage) message.
|
|
@@ -194,6 +199,25 @@ ${await (0, doc_query_1.showQuery)(shell, example_query_code_1.exampleQueryCode,
|
|
|
194
199
|
`;
|
|
195
200
|
}
|
|
196
201
|
});
|
|
202
|
+
(0, doc_query_1.registerQueryDocumentation)('resolve-value', {
|
|
203
|
+
name: 'Resolve Value Query',
|
|
204
|
+
type: 'active',
|
|
205
|
+
shortDescription: 'Provides access to flowR\'s value tracking (which is configurable)',
|
|
206
|
+
functionName: search_query_executor_1.executeSearch.name,
|
|
207
|
+
functionFile: '../queries/catalog/resolve-value-query/resolve-value-query-executor.ts',
|
|
208
|
+
buildExplanation: async (shell) => {
|
|
209
|
+
const exampleCode = 'x <- 1\nprint(x)';
|
|
210
|
+
return `
|
|
211
|
+
With this query you can use flowR's value-tracking capabilities to resolve identifiers to all potential values they may have at runtime (if possible). The extend to which flowR traces values (e.g. built-ins vs. constants) can be configured in flowR's Configuration file (see the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface) wiki page for more information).
|
|
212
|
+
|
|
213
|
+
Using the example code \`${exampleCode}\`, the following query returns all values of 'x' in the code:
|
|
214
|
+
${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
|
|
215
|
+
type: 'resolve-value',
|
|
216
|
+
criteria: ['2@x']
|
|
217
|
+
}], { showCode: true })}
|
|
218
|
+
`;
|
|
219
|
+
}
|
|
220
|
+
});
|
|
197
221
|
(0, doc_query_1.registerQueryDocumentation)('search', {
|
|
198
222
|
name: 'Search Query',
|
|
199
223
|
type: 'active',
|
|
@@ -344,7 +368,7 @@ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
|
|
|
344
368
|
criteria: ['3@x']
|
|
345
369
|
}], { showCode: false })}
|
|
346
370
|
|
|
347
|
-
In general you may be uninterested in seeing the reconstructed version and want to save some computation time, for this,
|
|
371
|
+
In general, you may be uninterested in seeing the reconstructed version and want to save some computation time, for this,
|
|
348
372
|
you can use the \`noReconstruction\` flag.
|
|
349
373
|
|
|
350
374
|
${(0, doc_structure_1.details)('No Reconstruction Example', await (0, doc_query_1.showQuery)(shell, exampleCode, [{
|
|
@@ -419,9 +443,13 @@ ${await (0, doc_query_1.showQuery)(shell, longerCode, [{
|
|
|
419
443
|
functionName: location_map_query_executor_1.executeLocationMapQuery.name,
|
|
420
444
|
functionFile: '../queries/catalog/location-map-query/location-map-query-executor.ts',
|
|
421
445
|
buildExplanation: async (shell) => {
|
|
446
|
+
const types = (0, doc_types_1.getTypesFromFolderAsMermaid)({
|
|
447
|
+
files: [path_1.default.resolve('./src/util/range.ts')],
|
|
448
|
+
typeName: 'SourceRange'
|
|
449
|
+
});
|
|
422
450
|
const exampleCode = 'x + 1\nx * 2';
|
|
423
451
|
return `
|
|
424
|
-
A query like the ${(0, doc_query_1.linkToQueryOfName)('id-map')} query can return a
|
|
452
|
+
A query like the ${(0, doc_query_1.linkToQueryOfName)('id-map')} query can return a huge result, especially for larger scripts.
|
|
425
453
|
If you are not interested in all of the information contained within the full map, you can use the location map query to get a simple mapping of ids to their location in the source file.
|
|
426
454
|
|
|
427
455
|
Consider you have the following code:
|
|
@@ -434,6 +462,8 @@ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
|
|
|
434
462
|
type: 'location-map'
|
|
435
463
|
}], { showCode: false, collapseQuery: true })}
|
|
436
464
|
|
|
465
|
+
All locations are given as a ${(0, doc_types_1.shortLink)('SourceRange', types.info)} in the format \`[start-line, start-column, end-line, end-column]\`.
|
|
466
|
+
|
|
437
467
|
`;
|
|
438
468
|
}
|
|
439
469
|
});
|
|
@@ -459,7 +489,7 @@ Queries are JSON arrays of query objects, each of which uses a \`type\` property
|
|
|
459
489
|
In general, we separate two types of queries:
|
|
460
490
|
|
|
461
491
|
1. **Active Queries**: Are exactly what you would expect from a query (e.g., the ${(0, doc_query_1.linkToQueryOfName)('call-context')}). They fetch information from the dataflow graph.
|
|
462
|
-
2. **Virtual Queries**: Are used to structure your queries (e.g., the ${(0, doc_query_1.linkToQueryOfName)('compound')}).
|
|
492
|
+
2. **Virtual Queries**: Are used to structure your queries (e.g., the ${(0, doc_query_1.linkToQueryOfName)('compound')}).
|
|
463
493
|
|
|
464
494
|
We separate these from a concept perspective.
|
|
465
495
|
For now, we support the following **active** queries (which we will refer to simply as a \`query\`):
|
|
@@ -12,6 +12,7 @@ const flowr_search_builder_1 = require("../search/flowr-search-builder");
|
|
|
12
12
|
const vertex_1 = require("../dataflow/graph/vertex");
|
|
13
13
|
const doc_types_1 = require("./doc-util/doc-types");
|
|
14
14
|
const path_1 = __importDefault(require("path"));
|
|
15
|
+
const flowr_search_executor_1 = require("../search/flowr-search-executor");
|
|
15
16
|
async function getText(shell) {
|
|
16
17
|
const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
|
|
17
18
|
const types = (0, doc_types_1.getTypesFromFolderAsMermaid)({
|
|
@@ -24,7 +25,7 @@ async function getText(shell) {
|
|
|
24
25
|
This page briefly summarizes flowR's search API which provides a set of functions to search for nodes in the [Dataflow Graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow%20Graph) and the
|
|
25
26
|
[Normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized%20AST) of a given R code (the search will always consider both, with respect to your search query).
|
|
26
27
|
Please see the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface) wiki page for more information on how to access this API.
|
|
27
|
-
Within code, you can execute a search using the ${(0, doc_types_1.shortLink)(
|
|
28
|
+
Within code, you can execute a search using the ${(0, doc_types_1.shortLink)(flowr_search_executor_1.runSearch.name, types.info)} function.
|
|
28
29
|
|
|
29
30
|
For an initial motivation, let's have a look at the following example:
|
|
30
31
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eagleoutice/flowr",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.3",
|
|
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": {
|
|
@@ -21,21 +21,23 @@
|
|
|
21
21
|
"stats-helper": "ts-node src/cli/statistics-helper-app.ts",
|
|
22
22
|
"slicer": "ts-node src/cli/slicer-app.ts",
|
|
23
23
|
"benchmark-helper": "ts-node src/cli/benchmark-helper-app.ts",
|
|
24
|
-
"benchmark": "npm run build
|
|
24
|
+
"benchmark": "npm run build-dev && node dist/src/cli/benchmark-app.js",
|
|
25
25
|
"summarizer": "ts-node src/cli/summarizer-app.ts",
|
|
26
26
|
"export-quads": "ts-node src/cli/export-quads-app.ts",
|
|
27
27
|
"capabilities-markdown": "ts-node src/documentation/print-capabilities-markdown.ts",
|
|
28
28
|
"wiki:df-graph": "ts-node src/documentation/print-dataflow-graph-wiki.ts",
|
|
29
29
|
"wiki:normalized-ast": "ts-node src/documentation/print-normalized-ast-wiki.ts",
|
|
30
30
|
"wiki:query-api": "ts-node src/documentation/print-query-wiki.ts",
|
|
31
|
+
"wiki:core": "ts-node src/documentation/print-core-wiki.ts",
|
|
31
32
|
"wiki:engines": "ts-node src/documentation/print-engines-wiki.ts",
|
|
32
33
|
"wiki:search-api": "ts-node src/documentation/print-search-wiki.ts",
|
|
33
34
|
"wiki:linting-and-testing": "ts-node src/documentation/print-linting-and-testing-wiki.ts",
|
|
34
35
|
"wiki:interface": "ts-node src/documentation/print-interface-wiki.ts",
|
|
35
36
|
"build": "tsc --project .",
|
|
36
|
-
"build
|
|
37
|
-
"build:
|
|
38
|
-
"build:copy-wasm
|
|
37
|
+
"build-dev": "npm run build && npm run build:copy-wasm",
|
|
38
|
+
"build:bundle-flowr": "npm run build && esbuild --bundle dist/src/cli/flowr.js --platform=node --bundle --minify --external:clipboardy --target=node22 --outfile=dist/src/cli/flowr.min.js && npm run build:copy-wasm-min",
|
|
39
|
+
"build:copy-wasm": "mkdir -p dist/src/r-bridge/lang-4.x/tree-sitter/ && cp src/r-bridge/lang-4.x/tree-sitter/tree-sitter-r.wasm src/r-bridge/lang-4.x/tree-sitter/tree-sitter.wasm dist/src/r-bridge/lang-4.x/tree-sitter/",
|
|
40
|
+
"build:copy-wasm-min": "mkdir -p dist/src/cli && cp src/r-bridge/lang-4.x/tree-sitter/tree-sitter-r.wasm src/r-bridge/lang-4.x/tree-sitter/tree-sitter.wasm dist/src/cli",
|
|
39
41
|
"lint-local": "npx eslint --version && npx eslint src/ test/ --rule \"no-warning-comments: off\"",
|
|
40
42
|
"lint": "npm run license-compat -- --summary && npx eslint --version && npx eslint src/ test/",
|
|
41
43
|
"license-compat": "license-checker --onlyAllow 'MIT;MIT OR X11;GPLv2;LGPL;GNUGPL;ISC;Apache-2.0;FreeBSD;BSD-2-Clause;clearbsd;ModifiedBSD;BSD-3-Clause;Python-2.0;Unlicense;WTFPL;BlueOak-1.0.0;CC-BY-4.0;CC-BY-3.0;CC0-1.0;0BSD'",
|
|
@@ -166,7 +168,7 @@
|
|
|
166
168
|
"npm run lint",
|
|
167
169
|
"npm run test-full"
|
|
168
170
|
],
|
|
169
|
-
"after:bump": "npm run build
|
|
171
|
+
"after:bump": "npm run build-dev",
|
|
170
172
|
"after:git:release": "echo After git push, before github release",
|
|
171
173
|
"after:release": "echo Successfully released ${name} v${version} to ${repo.repository}."
|
|
172
174
|
},
|
|
@@ -195,7 +197,7 @@
|
|
|
195
197
|
"@types/ws": "^8.5.10",
|
|
196
198
|
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
|
197
199
|
"@vitest/coverage-v8": "^2.1.4",
|
|
198
|
-
"esbuild": "^0.
|
|
200
|
+
"esbuild": "^0.25.0",
|
|
199
201
|
"eslint": "^8.57.1",
|
|
200
202
|
"license-checker": "^25.0.1",
|
|
201
203
|
"npm-run-all": "^4.1.5",
|
|
@@ -210,6 +212,7 @@
|
|
|
210
212
|
},
|
|
211
213
|
"dependencies": {
|
|
212
214
|
"@xmldom/xmldom": "^0.9.2",
|
|
215
|
+
"clipboardy": "^4.0.0",
|
|
213
216
|
"command-line-args": "^6.0.0",
|
|
214
217
|
"command-line-usage": "^7.0.3",
|
|
215
218
|
"joi": "^17.13.3",
|