@eagleoutice/flowr 2.10.2 → 2.10.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/README.md +15 -15
- package/documentation/wiki-cfg.js +3 -3
- package/documentation/wiki-query.js +29 -0
- package/package.json +3 -3
- package/queries/catalog/dependencies-query/function-info/write-functions.js +1 -1
- package/queries/catalog/input-sources-query/simple-input-classifier.js +3 -3
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +1 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +1 -1
- package/util/version.js +1 -1
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.10.
|
|
27
|
+
flowR repl using flowR v2.10.2, R grammar v14 (tree-sitter engine)
|
|
28
28
|
R> :query @linter "read.csv(\"/root/x.txt\")"
|
|
29
29
|
```
|
|
30
30
|
|
|
@@ -35,17 +35,17 @@ 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:
|
|
38
|
+
╰ Metadata: totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 0, 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:
|
|
42
|
+
╰ Metadata: totalReads: 1, totalUnknown: 0, totalWritesBeforeAlways: 0, totalValid: 0, searchTimeMs: 1, 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):
|
|
46
46
|
╰ certain:
|
|
47
47
|
╰ Path `/root/x.txt` at 1.1-23
|
|
48
|
-
╰ Metadata: totalConsidered: 1, totalUnknown: 0, searchTimeMs:
|
|
48
|
+
╰ Metadata: totalConsidered: 1, totalUnknown: 0, searchTimeMs: 0, processTimeMs: 0
|
|
49
49
|
╰ Unused Definitions (unused-definitions):
|
|
50
50
|
╰ Metadata: totalConsidered: 0, searchTimeMs: 0, processTimeMs: 0
|
|
51
51
|
╰ Naming Convention (naming-convention):
|
|
@@ -53,7 +53,7 @@ It offers a wide variety of features, for example:
|
|
|
53
53
|
╰ Network Functions (network-functions):
|
|
54
54
|
╰ Metadata: totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 0, processTimeMs: 0
|
|
55
55
|
╰ Dataframe Access Validation (dataframe-access-validation):
|
|
56
|
-
╰ Metadata: numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs:
|
|
56
|
+
╰ Metadata: numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs: 1
|
|
57
57
|
╰ Dead Code (dead-code):
|
|
58
58
|
╰ Metadata: consideredNodes: 5, searchTimeMs: 0, processTimeMs: 0
|
|
59
59
|
╰ Useless Loops (useless-loop):
|
|
@@ -106,9 +106,9 @@ It offers a wide variety of features, for example:
|
|
|
106
106
|
╰ **Network Functions** (network-functions):\
|
|
107
107
|
╰ _Metadata_: <code>totalCalls: 0, totalFunctionDefinitions: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
108
108
|
╰ **Dataframe Access Validation** (dataframe-access-validation):\
|
|
109
|
-
╰ _Metadata_: <code>numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs:
|
|
109
|
+
╰ _Metadata_: <code>numOperations: 0, numAccesses: 0, totalAccessed: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
110
110
|
╰ **Dead Code** (dead-code):\
|
|
111
|
-
╰ _Metadata_: <code>consideredNodes: 5, searchTimeMs:
|
|
111
|
+
╰ _Metadata_: <code>consideredNodes: 5, searchTimeMs: 1, processTimeMs: 0</code>\
|
|
112
112
|
╰ **Useless Loops** (useless-loop):\
|
|
113
113
|
╰ _Metadata_: <code>numOfUselessLoops: 0, searchTimeMs: 0, processTimeMs: 0</code>\
|
|
114
114
|
╰ **Problematic eval** (problematic-eval):\
|
|
@@ -121,7 +121,7 @@ It offers a wide variety of features, for example:
|
|
|
121
121
|
|
|
122
122
|
<details> <summary style="color:gray">Show Detailed Results as Json</summary>
|
|
123
123
|
|
|
124
|
-
The analysis required
|
|
124
|
+
The analysis required _2.5 ms_ (including parsing and normalization and the query) within the generation environment.
|
|
125
125
|
|
|
126
126
|
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.
|
|
127
127
|
Please consult the [Interface](https://github.com/flowr-analysis/flowr/wiki/Interface) wiki page for more information on how to get those.
|
|
@@ -230,14 +230,14 @@ It offers a wide variety of features, for example:
|
|
|
230
230
|
"numAccesses": 0,
|
|
231
231
|
"totalAccessed": 0,
|
|
232
232
|
"searchTimeMs": 0,
|
|
233
|
-
"processTimeMs":
|
|
233
|
+
"processTimeMs": 0
|
|
234
234
|
}
|
|
235
235
|
},
|
|
236
236
|
"dead-code": {
|
|
237
237
|
"results": [],
|
|
238
238
|
".meta": {
|
|
239
239
|
"consideredNodes": 5,
|
|
240
|
-
"searchTimeMs":
|
|
240
|
+
"searchTimeMs": 1,
|
|
241
241
|
"processTimeMs": 0
|
|
242
242
|
}
|
|
243
243
|
},
|
|
@@ -342,7 +342,7 @@ It offers a wide variety of features, for example:
|
|
|
342
342
|
|
|
343
343
|
```shell
|
|
344
344
|
$ docker run -it --rm eagleoutice/flowr # or npm run flowr
|
|
345
|
-
flowR repl using flowR v2.10.
|
|
345
|
+
flowR repl using flowR v2.10.2, R grammar v14 (tree-sitter engine)
|
|
346
346
|
R> :query @static-slice (11@sum) file://test/testfiles/example.R
|
|
347
347
|
```
|
|
348
348
|
|
|
@@ -356,7 +356,7 @@ It offers a wide variety of features, for example:
|
|
|
356
356
|
N <- 10
|
|
357
357
|
for(i in 1:(N-1)) sum <- sum + i + w
|
|
358
358
|
sum
|
|
359
|
-
All queries together required ≈
|
|
359
|
+
All queries together required ≈3 ms (1ms accuracy, total 3 ms)
|
|
360
360
|
```
|
|
361
361
|
|
|
362
362
|
|
|
@@ -390,7 +390,7 @@ It offers a wide variety of features, for example:
|
|
|
390
390
|
|
|
391
391
|
|
|
392
392
|
* 🚀 **fast call-graph, data-, and control-flow graphs**\
|
|
393
|
-
Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">
|
|
393
|
+
Within just [<i><span title="This measurement is automatically fetched from the latest benchmark!">100.4 ms</span></i> (as of Apr 2, 2026)](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark),
|
|
394
394
|
_flowR_ can analyze the data- and control-flow of the average real-world R script. See the [benchmarks](https://flowr-analysis.github.io/flowr/wiki/stats/benchmark) for more information,
|
|
395
395
|
and consult the [wiki pages](https://github.com/flowr-analysis/flowr/wiki/dataflow-graph) for more details on the [dataflow graphs](https://github.com/flowr-analysis/flowr/wiki/dataflow-graph) as well as [call graphs](https://github.com/flowr-analysis/flowr/wiki/dataflow-graph#perspectives-cg).
|
|
396
396
|
|
|
@@ -426,7 +426,7 @@ It offers a wide variety of features, for example:
|
|
|
426
426
|
|
|
427
427
|
```shell
|
|
428
428
|
$ docker run -it --rm eagleoutice/flowr # or npm run flowr
|
|
429
|
-
flowR repl using flowR v2.10.
|
|
429
|
+
flowR repl using flowR v2.10.2, R grammar v14 (tree-sitter engine)
|
|
430
430
|
R> :dataflow* test/testfiles/example.R
|
|
431
431
|
```
|
|
432
432
|
|
|
@@ -734,7 +734,7 @@ It offers a wide variety of features, for example:
|
|
|
734
734
|
```
|
|
735
735
|
|
|
736
736
|
|
|
737
|
-
(The analysis required
|
|
737
|
+
(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.)
|
|
738
738
|
|
|
739
739
|
|
|
740
740
|
|
|
@@ -201,7 +201,7 @@ ${(0, doc_structure_1.section)('Structure of the Control Flow Graph', 2, 'cfg-st
|
|
|
201
201
|
|
|
202
202
|
You can produce your very own control flow graph with ${ctx.link(extract_cfg_1.extractCfg)}.
|
|
203
203
|
The ${ctx.link(control_flow_graph_1.ControlFlowGraph)} class describes everything required to model the control flow graph, with its edge types described by
|
|
204
|
-
${ctx.link('CfgEdge')} and its vertices by ${ctx.link('
|
|
204
|
+
${ctx.link('CfgEdge')} and its vertices by ${ctx.link('CfgVertex')}.
|
|
205
205
|
However, you should be aware of the ${ctx.link('ControlFlowInformation')} interface which adds some additional information the CFG
|
|
206
206
|
(and is used during the construction of the CFG as well):
|
|
207
207
|
|
|
@@ -221,7 +221,7 @@ ${Object.entries(control_flow_graph_1.CfgVertexType).map(([key, value]) => `- \`
|
|
|
221
221
|
We use the ${ctx.link('CfgBasicBlockVertex')} to represent [basic blocks](#cfg-basic-blocks) and separate
|
|
222
222
|
expressions (${ctx.link('CfgExpressionVertex')}) and statements (${ctx.link('CfgStatementVertex')})
|
|
223
223
|
as control flow units with and without side effects (if you want to, you can see view statements as effectful expressions).
|
|
224
|
-
The markers (${ctx.link('
|
|
224
|
+
The markers (${ctx.link('CfgMarkerVertex')}) indicate the end of larger expressions/statements.
|
|
225
225
|
|
|
226
226
|
To signal these links, the expressions and statements contain information about the attached markers:
|
|
227
227
|
|
|
@@ -239,7 +239,7 @@ ${(0, doc_structure_1.block)({
|
|
|
239
239
|
content: `
|
|
240
240
|
Every CFG vertex has a ${ctx.link('NodeId')} that links it to the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized-AST) (although basic blocks will find no counterpart as they are a structuring element of the CFG).
|
|
241
241
|
Additionally, it may provide information on the called functions (in case that the current element is a function call).
|
|
242
|
-
Have a look at the ${ctx.link('
|
|
242
|
+
Have a look at the ${ctx.link('CfgBaseVertexWithMarker')} interface for more information.
|
|
243
243
|
`.trim()
|
|
244
244
|
})}
|
|
245
245
|
|
|
@@ -40,6 +40,7 @@ const does_call_query_executor_1 = require("../queries/catalog/does-call-query/d
|
|
|
40
40
|
const inspect_exception_query_executor_1 = require("../queries/catalog/inspect-exceptions-query/inspect-exception-query-executor");
|
|
41
41
|
const slice_direction_1 = require("../util/slice-direction");
|
|
42
42
|
const provenance_query_executor_1 = require("../queries/catalog/provenance-query/provenance-query-executor");
|
|
43
|
+
const input_sources_query_executor_1 = require("../queries/catalog/input-sources-query/input-sources-query-executor");
|
|
43
44
|
(0, doc_query_1.registerQueryDocumentation)('call-context', {
|
|
44
45
|
name: 'Call-Context Query',
|
|
45
46
|
type: 'active',
|
|
@@ -608,6 +609,34 @@ ${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
|
|
|
608
609
|
`;
|
|
609
610
|
}
|
|
610
611
|
});
|
|
612
|
+
(0, doc_query_1.registerQueryDocumentation)('input-sources', {
|
|
613
|
+
name: 'Input Sources Query',
|
|
614
|
+
type: 'active',
|
|
615
|
+
shortDescription: 'Classify the input sources of function calls',
|
|
616
|
+
functionName: input_sources_query_executor_1.executeInputSourcesQuery.name,
|
|
617
|
+
functionFile: '../queries/catalog/input-sources-query/input-sources-query-executor.ts',
|
|
618
|
+
buildExplanation: async (shell) => {
|
|
619
|
+
const exampleCode = `
|
|
620
|
+
f <- function(x) {
|
|
621
|
+
x <- x * 2
|
|
622
|
+
print(x)
|
|
623
|
+
}`.trim();
|
|
624
|
+
const criterion = '3@print';
|
|
625
|
+
return `
|
|
626
|
+
Given a [slicing criterion](${doc_files_1.FlowrWikiBaseRef}/Terminology#slicing-criterion) to
|
|
627
|
+
something like a function call, flowR classifies the types of all input sources (e.g., arguments).
|
|
628
|
+
|
|
629
|
+
To exemplify the query, consider the following code:
|
|
630
|
+
${(0, doc_code_1.codeBlock)('r', exampleCode)}
|
|
631
|
+
If you are interested in the input-sources of the \`print\` call, you can use:
|
|
632
|
+
|
|
633
|
+
${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
|
|
634
|
+
type: 'input-sources',
|
|
635
|
+
criterion
|
|
636
|
+
}], { showCode: false, shorthand: (0, doc_query_1.sliceQueryShorthand)([criterion], (0, doc_escape_1.escapeNewline)(exampleCode)) })}
|
|
637
|
+
`;
|
|
638
|
+
}
|
|
639
|
+
});
|
|
611
640
|
(0, doc_query_1.registerQueryDocumentation)('dependencies', {
|
|
612
641
|
name: 'Dependencies Query',
|
|
613
642
|
type: 'active',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eagleoutice/flowr",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.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": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"build": "tsc --project .",
|
|
33
33
|
"build-dev": "npm run build && npm run build:copy-wasm",
|
|
34
34
|
"build:bundle-flowr": "npm run build && esbuild --bundle dist/src/cli/flowr.js --platform=node --tree-shaking=true --minify --external:clipboardy --target=node22 --outfile=dist/src/cli/flowr.min.js && npm run build:copy-wasm",
|
|
35
|
-
"build:copy-wasm": "mkdir -p dist/node_modules/@
|
|
35
|
+
"build:copy-wasm": "mkdir -p dist/node_modules/@davisvaughan/tree-sitter-r/ && mkdir -p dist/node_modules/web-tree-sitter && cp node_modules/@davisvaughan/tree-sitter-r/tree-sitter-r.wasm dist/node_modules/@davisvaughan/tree-sitter-r/ && cp node_modules/web-tree-sitter/tree-sitter.wasm dist/node_modules/web-tree-sitter/",
|
|
36
36
|
"lint-local": "npx eslint --version && npx eslint src/ test/ --rule \"no-warning-comments: off\"",
|
|
37
37
|
"lint": "npm run license-compat -- --summary && npx eslint --version && npx eslint src/ test/",
|
|
38
38
|
"license-compat": "license-checker-rseidelsohn --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'",
|
|
@@ -198,7 +198,7 @@
|
|
|
198
198
|
"vitest": "^3.2.4"
|
|
199
199
|
},
|
|
200
200
|
"dependencies": {
|
|
201
|
-
"@
|
|
201
|
+
"@davisvaughan/tree-sitter-r": "^1.2.0",
|
|
202
202
|
"@jupyterlab/nbformat": "^4.5.4",
|
|
203
203
|
"@xmldom/xmldom": "^0.9.7",
|
|
204
204
|
"clipboardy": "^4.0.0",
|
|
@@ -7,7 +7,7 @@ const OutputRedirects = [
|
|
|
7
7
|
];
|
|
8
8
|
exports.WriteFunctions = [
|
|
9
9
|
{ package: 'base', name: 'save', argName: 'file', resolveValue: true },
|
|
10
|
-
{ package: 'base', name: 'save.image', argIdx: 1, argName: 'file', resolveValue: true },
|
|
10
|
+
{ package: 'base', name: 'save.image', argIdx: 1, argName: 'file', resolveValue: true, defaultValue: '.RData' },
|
|
11
11
|
{ package: 'base', name: 'write', argIdx: 1, argName: 'file', resolveValue: true },
|
|
12
12
|
{ package: 'base', name: 'dput', argIdx: 1, argName: 'file', resolveValue: true },
|
|
13
13
|
{ package: 'base', name: 'dump', argIdx: 1, argName: 'file', resolveValue: true },
|
|
@@ -102,8 +102,8 @@ class InputClassifier {
|
|
|
102
102
|
if (allConstLike) {
|
|
103
103
|
return this.classifyCdsAndReturn(call, (0, objects_1.compactRecord)({ id: call.id, type: [InputType.DerivedConstant], trace: InputTraceType.Pure, cds }));
|
|
104
104
|
}
|
|
105
|
-
|
|
106
|
-
return this.classifyCdsAndReturn(call, (0, objects_1.compactRecord)({ id: call.id, type:
|
|
105
|
+
argTypes.push(InputType.DerivedConstant);
|
|
106
|
+
return this.classifyCdsAndReturn(call, (0, objects_1.compactRecord)({ id: call.id, type: (0, arrays_1.uniqueArray)(argTypes), trace: InputTraceType.Known, cds }));
|
|
107
107
|
}
|
|
108
108
|
classifyVariable(vtx) {
|
|
109
109
|
const origins = df_helper_1.Dataflow.origin(this.dfg, vtx.id);
|
|
@@ -115,7 +115,7 @@ class InputClassifier {
|
|
|
115
115
|
let allPure = true;
|
|
116
116
|
for (const o of origins) {
|
|
117
117
|
if (o.type === 4 /* OriginType.ConstantOrigin */) {
|
|
118
|
-
types.push(InputType.
|
|
118
|
+
types.push(InputType.DerivedConstant);
|
|
119
119
|
continue;
|
|
120
120
|
}
|
|
121
121
|
if (o.type === 0 /* OriginType.ReadVariableOrigin */ || o.type === 1 /* OriginType.WriteVariableOrigin */) {
|
|
@@ -4,7 +4,7 @@ import type { RParseRequest } from '../../retriever';
|
|
|
4
4
|
import type { SyncParser, TreeSitterInformation } from '../../parser';
|
|
5
5
|
import type { TreeSitterEngineConfig } from '../../../config';
|
|
6
6
|
import type { ReadonlyFlowrAnalysisProvider } from '../../../project/flowr-analyzer';
|
|
7
|
-
export declare const DEFAULT_TREE_SITTER_R_WASM_PATH = "./node_modules/@
|
|
7
|
+
export declare const DEFAULT_TREE_SITTER_R_WASM_PATH = "./node_modules/@davisvaughan/tree-sitter-r/tree-sitter-r.wasm";
|
|
8
8
|
export declare const DEFAULT_TREE_SITTER_WASM_PATH = "./node_modules/web-tree-sitter/tree-sitter.wasm";
|
|
9
9
|
/**
|
|
10
10
|
* Synchronous and (way) faster alternative to the {@link RShell} using tree-sitter.
|
|
@@ -7,7 +7,7 @@ exports.TreeSitterExecutor = exports.DEFAULT_TREE_SITTER_WASM_PATH = exports.DEF
|
|
|
7
7
|
const web_tree_sitter_1 = __importDefault(require("web-tree-sitter"));
|
|
8
8
|
const log_1 = require("../../../util/log");
|
|
9
9
|
const fs_1 = __importDefault(require("fs"));
|
|
10
|
-
exports.DEFAULT_TREE_SITTER_R_WASM_PATH = './node_modules/@
|
|
10
|
+
exports.DEFAULT_TREE_SITTER_R_WASM_PATH = './node_modules/@davisvaughan/tree-sitter-r/tree-sitter-r.wasm';
|
|
11
11
|
exports.DEFAULT_TREE_SITTER_WASM_PATH = './node_modules/web-tree-sitter/tree-sitter.wasm';
|
|
12
12
|
const wasmLog = log_1.log.getSubLogger({ name: 'tree-sitter-wasm' });
|
|
13
13
|
/**
|
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.10.
|
|
9
|
+
const version = '2.10.3';
|
|
10
10
|
/**
|
|
11
11
|
* Retrieves the current flowR version as a new {@link SemVer} object.
|
|
12
12
|
*/
|