@eagleoutice/flowr 2.7.3 → 2.7.4
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.7.
|
|
27
|
+
flowR repl using flowR v2.7.3, R grammar v14 (tree-sitter engine)
|
|
28
28
|
R> :query @linter "read.csv(\"/root/x.txt\")"
|
|
29
29
|
```
|
|
30
30
|
|
|
@@ -33,21 +33,21 @@ It offers a wide variety of features, for example:
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
```text
|
|
36
|
-
Query: [;1mlinter[0m (
|
|
36
|
+
Query: [;1mlinter[0m (2 ms)
|
|
37
37
|
╰ **Deprecated Functions** (deprecated-functions):
|
|
38
38
|
╰ _Metadata_: <code>{"totalCalls":0,"totalFunctionDefinitions":0,"searchTimeMs":0,"processTimeMs":0}</code>
|
|
39
39
|
╰ **File Path Validity** (file-path-validity):
|
|
40
40
|
╰ certain:
|
|
41
41
|
╰ Path `/root/x.txt` at 1.1-23
|
|
42
|
-
╰ _Metadata_: <code>{"totalReads":1,"totalUnknown":0,"totalWritesBeforeAlways":0,"totalValid":0,"searchTimeMs":
|
|
42
|
+
╰ _Metadata_: <code>{"totalReads":1,"totalUnknown":0,"totalWritesBeforeAlways":0,"totalValid":0,"searchTimeMs":1,"processTimeMs":0}</code>
|
|
43
43
|
╰ **Seeded Randomness** (seeded-randomness):
|
|
44
44
|
╰ _Metadata_: <code>{"consumerCalls":0,"callsWithFunctionProducers":0,"callsWithAssignmentProducers":0,"callsWithNonConstantProducers":0,"callsWithOtherBranchProducers":0,"searchTimeMs":0,"processTimeMs":0}</code>
|
|
45
45
|
╰ **Absolute Paths** (absolute-file-paths):
|
|
46
46
|
╰ certain:
|
|
47
47
|
╰ Path `/root/x.txt` at 1.1-23
|
|
48
|
-
╰ _Metadata_: <code>{"totalConsidered":1,"totalUnknown":0,"searchTimeMs":
|
|
48
|
+
╰ _Metadata_: <code>{"totalConsidered":1,"totalUnknown":0,"searchTimeMs":0,"processTimeMs":0}</code>
|
|
49
49
|
╰ **Unused Definitions** (unused-definitions):
|
|
50
|
-
╰ _Metadata_: <code>{"totalConsidered":0,"searchTimeMs":0,"processTimeMs":
|
|
50
|
+
╰ _Metadata_: <code>{"totalConsidered":0,"searchTimeMs":0,"processTimeMs":1}</code>
|
|
51
51
|
╰ **Naming Convention** (naming-convention):
|
|
52
52
|
╰ _Metadata_: <code>{"numMatches":0,"numBreak":0,"searchTimeMs":0,"processTimeMs":0}</code>
|
|
53
53
|
╰ **Network Functions** (network-functions):
|
|
@@ -58,7 +58,7 @@ It offers a wide variety of features, for example:
|
|
|
58
58
|
╰ _Metadata_: <code>{"consideredNodes":5,"searchTimeMs":0,"processTimeMs":0}</code>
|
|
59
59
|
╰ **Useless Loops** (useless-loop):
|
|
60
60
|
╰ _Metadata_: <code>{"numOfUselessLoops":0,"searchTimeMs":0,"processTimeMs":0}</code>
|
|
61
|
-
[;3mAll queries together required ≈
|
|
61
|
+
[;3mAll queries together required ≈2 ms (1ms accuracy, total 3 ms)[0m[0m
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
|
|
@@ -82,7 +82,7 @@ It offers a wide variety of features, for example:
|
|
|
82
82
|
|
|
83
83
|
Query: **linter** (3 ms)\
|
|
84
84
|
╰ **Deprecated Functions** (deprecated-functions):\
|
|
85
|
-
╰ _Metadata_: <code>{"totalCalls":0,"totalFunctionDefinitions":0,"searchTimeMs":
|
|
85
|
+
╰ _Metadata_: <code>{"totalCalls":0,"totalFunctionDefinitions":0,"searchTimeMs":0,"processTimeMs":0}</code>\
|
|
86
86
|
╰ **File Path Validity** (file-path-validity):\
|
|
87
87
|
╰ certain:\
|
|
88
88
|
╰ Path `/root/x.txt` at 1.1-23\
|
|
@@ -92,7 +92,7 @@ It offers a wide variety of features, for example:
|
|
|
92
92
|
╰ **Absolute Paths** (absolute-file-paths):\
|
|
93
93
|
╰ certain:\
|
|
94
94
|
╰ Path `/root/x.txt` at 1.1-23\
|
|
95
|
-
╰ _Metadata_: <code>{"totalConsidered":1,"totalUnknown":0,"searchTimeMs":
|
|
95
|
+
╰ _Metadata_: <code>{"totalConsidered":1,"totalUnknown":0,"searchTimeMs":1,"processTimeMs":0}</code>\
|
|
96
96
|
╰ **Unused Definitions** (unused-definitions):\
|
|
97
97
|
╰ _Metadata_: <code>{"totalConsidered":0,"searchTimeMs":0,"processTimeMs":0}</code>\
|
|
98
98
|
╰ **Naming Convention** (naming-convention):\
|
|
@@ -100,7 +100,7 @@ It offers a wide variety of features, for example:
|
|
|
100
100
|
╰ **Network Functions** (network-functions):\
|
|
101
101
|
╰ _Metadata_: <code>{"totalCalls":0,"totalFunctionDefinitions":0,"searchTimeMs":0,"processTimeMs":0}</code>\
|
|
102
102
|
╰ **Dataframe Access Validation** (dataframe-access-validation):\
|
|
103
|
-
╰ _Metadata_: <code>{"numOperations":0,"numAccesses":0,"totalAccessed":0,"searchTimeMs":0,"processTimeMs":
|
|
103
|
+
╰ _Metadata_: <code>{"numOperations":0,"numAccesses":0,"totalAccessed":0,"searchTimeMs":0,"processTimeMs":1}</code>\
|
|
104
104
|
╰ **Dead Code** (dead-code):\
|
|
105
105
|
╰ _Metadata_: <code>{"consideredNodes":5,"searchTimeMs":0,"processTimeMs":0}</code>\
|
|
106
106
|
╰ **Useless Loops** (useless-loop):\
|
|
@@ -126,7 +126,7 @@ It offers a wide variety of features, for example:
|
|
|
126
126
|
".meta": {
|
|
127
127
|
"totalCalls": 0,
|
|
128
128
|
"totalFunctionDefinitions": 0,
|
|
129
|
-
"searchTimeMs":
|
|
129
|
+
"searchTimeMs": 0,
|
|
130
130
|
"processTimeMs": 0
|
|
131
131
|
}
|
|
132
132
|
},
|
|
@@ -180,8 +180,8 @@ It offers a wide variety of features, for example:
|
|
|
180
180
|
".meta": {
|
|
181
181
|
"totalConsidered": 1,
|
|
182
182
|
"totalUnknown": 0,
|
|
183
|
-
"searchTimeMs":
|
|
184
|
-
"processTimeMs":
|
|
183
|
+
"searchTimeMs": 1,
|
|
184
|
+
"processTimeMs": 0
|
|
185
185
|
}
|
|
186
186
|
},
|
|
187
187
|
"unused-definitions": {
|
|
@@ -217,7 +217,7 @@ It offers a wide variety of features, for example:
|
|
|
217
217
|
"numAccesses": 0,
|
|
218
218
|
"totalAccessed": 0,
|
|
219
219
|
"searchTimeMs": 0,
|
|
220
|
-
"processTimeMs":
|
|
220
|
+
"processTimeMs": 1
|
|
221
221
|
}
|
|
222
222
|
},
|
|
223
223
|
"dead-code": {
|
|
@@ -307,7 +307,7 @@ It offers a wide variety of features, for example:
|
|
|
307
307
|
|
|
308
308
|
```shell
|
|
309
309
|
$ docker run -it --rm eagleoutice/flowr # or npm run flowr
|
|
310
|
-
flowR repl using flowR v2.7.
|
|
310
|
+
flowR repl using flowR v2.7.3, R grammar v14 (tree-sitter engine)
|
|
311
311
|
R> :query @static-slice (11@sum) file://test/testfiles/example.R
|
|
312
312
|
```
|
|
313
313
|
|
|
@@ -321,7 +321,7 @@ It offers a wide variety of features, for example:
|
|
|
321
321
|
N <- 10
|
|
322
322
|
for(i in 1:(N-1)) sum <- sum + i + w
|
|
323
323
|
sum
|
|
324
|
-
[;3mAll queries together required ≈
|
|
324
|
+
[;3mAll queries together required ≈2 ms (1ms accuracy, total 2 ms)[0m[0m
|
|
325
325
|
```
|
|
326
326
|
|
|
327
327
|
|
|
@@ -355,7 +355,7 @@ It offers a wide variety of features, for example:
|
|
|
355
355
|
|
|
356
356
|
|
|
357
357
|
* 🚀 **fast data- and control-flow graphs**\
|
|
358
|
-
Within just <i><span title="This measurement is automatically fetched from the latest benchmark!">
|
|
358
|
+
Within just <i><span title="This measurement is automatically fetched from the latest benchmark!">120.3 ms</span></i> (as of Dec 21, 2025),
|
|
359
359
|
_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,
|
|
360
360
|
and consult the [wiki pages](https://github.com/flowr-analysis/flowr/wiki/Dataflow-Graph) for more details on the dataflow graph.
|
|
361
361
|
|
|
@@ -391,7 +391,7 @@ It offers a wide variety of features, for example:
|
|
|
391
391
|
|
|
392
392
|
```shell
|
|
393
393
|
$ docker run -it --rm eagleoutice/flowr # or npm run flowr
|
|
394
|
-
flowR repl using flowR v2.7.
|
|
394
|
+
flowR repl using flowR v2.7.3, R grammar v14 (tree-sitter engine)
|
|
395
395
|
R> :dataflow* test/testfiles/example.R
|
|
396
396
|
```
|
|
397
397
|
|
|
@@ -696,7 +696,7 @@ It offers a wide variety of features, for example:
|
|
|
696
696
|
```
|
|
697
697
|
|
|
698
698
|
|
|
699
|
-
(The analysis required
|
|
699
|
+
(The analysis required _2.9 ms_ (including parse and normalize, using the [tree-sitter](https://github.com/flowr-analysis/flowr/wiki/Engines) engine) within the generation environment.)
|
|
700
700
|
|
|
701
701
|
|
|
702
702
|
|
package/dataflow/extractor.js
CHANGED
|
@@ -60,6 +60,8 @@ exports.processors = {
|
|
|
60
60
|
function resolveLinkToSideEffects(ast, graph) {
|
|
61
61
|
let cf = undefined;
|
|
62
62
|
let knownCalls;
|
|
63
|
+
let allCallNames = [];
|
|
64
|
+
const killedRegexes = new Set();
|
|
63
65
|
const handled = new Set();
|
|
64
66
|
for (const s of graph.unknownSideEffects) {
|
|
65
67
|
if (typeof s !== 'object') {
|
|
@@ -69,12 +71,23 @@ function resolveLinkToSideEffects(ast, graph) {
|
|
|
69
71
|
cf = (0, extract_cfg_1.extractCfgQuick)(ast);
|
|
70
72
|
if (graph.unknownSideEffects.size > 20) {
|
|
71
73
|
knownCalls = (0, extract_cfg_1.getCallsInCfg)(cf, graph);
|
|
74
|
+
allCallNames = Array.from(new Set(knownCalls.values().map(c => c.name)));
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
77
|
else if (handled.has(s.id)) {
|
|
75
78
|
continue;
|
|
76
79
|
}
|
|
77
80
|
handled.add(s.id);
|
|
81
|
+
const regexKey = s.linkTo.callName.source + '//' + s.linkTo.callName.flags;
|
|
82
|
+
if (killedRegexes.has(regexKey)) {
|
|
83
|
+
// we already know we will not find it!
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
else if (allCallNames.length > 0 && !allCallNames.some(name => s.linkTo.callName.test(name))) {
|
|
87
|
+
// we know no call matches the regex
|
|
88
|
+
killedRegexes.add(regexKey);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
78
91
|
/* this has to change whenever we add a new link to relations because we currently offer no abstraction for the type */
|
|
79
92
|
const potentials = (0, identify_link_to_last_call_relation_1.identifyLinkToLastCallRelation)(s.id, cf.graph, graph, s.linkTo, knownCalls);
|
|
80
93
|
for (const pot of potentials) {
|
package/package.json
CHANGED
|
@@ -191,6 +191,7 @@ async function executeCallContextQueries({ analyzer }, queries) {
|
|
|
191
191
|
if (requiresCfg) {
|
|
192
192
|
cfg = await analyzer.controlflow([], cfg_kind_1.CfgKind.WithDataflow);
|
|
193
193
|
}
|
|
194
|
+
const calls = cfg ? (0, extract_cfg_1.getCallsInCfg)(cfg, dataflow.graph) : undefined;
|
|
194
195
|
const queriesWhichWantAliases = promotedQueries.filter(q => q.includeAliases);
|
|
195
196
|
for (const [nodeId, info] of dataflow.graph.verticesOfType(vertex_1.VertexType.FunctionCall)) {
|
|
196
197
|
/* if we have a vertex, and we check for aliased calls, we want to know if we define this as desired! */
|
|
@@ -209,7 +210,6 @@ async function executeCallContextQueries({ analyzer }, queries) {
|
|
|
209
210
|
}
|
|
210
211
|
}
|
|
211
212
|
}
|
|
212
|
-
const calls = cfg ? (0, extract_cfg_1.getCallsInCfg)(cfg, dataflow.graph) : undefined;
|
|
213
213
|
for (const query of promotedQueries.filter(q => !q.includeAliases && (q.callName instanceof RegExp ? q.callName.test(info.name) : q.callName.has(info.name)))) {
|
|
214
214
|
const file = ast.idMap.get(nodeId)?.info.file;
|
|
215
215
|
if (!doesFilepathMatch(file, query.fileFilter)) {
|
|
@@ -252,7 +252,7 @@ async function executeCallContextQueries({ analyzer }, queries) {
|
|
|
252
252
|
id: nodeId,
|
|
253
253
|
name: info.name,
|
|
254
254
|
calls: targets,
|
|
255
|
-
linkedIds: linkedIds ?
|
|
255
|
+
linkedIds: linkedIds ? Array.from(linkedIds) : undefined
|
|
256
256
|
}));
|
|
257
257
|
}
|
|
258
258
|
}
|
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.7.
|
|
9
|
+
const version = '2.7.4';
|
|
10
10
|
/**
|
|
11
11
|
* Retrieves the current flowR version as a new {@link SemVer} object.
|
|
12
12
|
*/
|