@eagleoutice/flowr 2.7.2 → 2.7.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 +20 -20
- package/abstract-interpretation/data-frame/mappers/arguments.d.ts +5 -0
- package/abstract-interpretation/data-frame/mappers/arguments.js +20 -0
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +11 -18
- package/abstract-interpretation/data-frame/resolve-args.d.ts +1 -1
- package/abstract-interpretation/data-frame/resolve-args.js +1 -1
- package/abstract-interpretation/data-frame/semantics.js +3 -3
- package/package.json +1 -1
- package/project/context/flowr-analyzer-context.js +3 -1
- package/project/context/flowr-analyzer-dependencies-context.d.ts +3 -2
- package/project/context/flowr-analyzer-dependencies-context.js +4 -2
- package/project/context/flowr-analyzer-functions-context.d.ts +29 -0
- package/project/context/flowr-analyzer-functions-context.js +68 -0
- package/project/plugins/file-plugins/files/flowr-namespace-file.d.ts +32 -0
- package/project/plugins/file-plugins/files/flowr-namespace-file.js +102 -0
- package/project/plugins/file-plugins/flowr-analyzer-namespace-file-plugin.d.ts +22 -0
- package/project/plugins/file-plugins/flowr-analyzer-namespace-file-plugin.js +34 -0
- package/project/plugins/flowr-analyzer-plugin-defaults.js +2 -0
- package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-description-file-plugin.js +5 -1
- package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-namespace-file-plugin.d.ts +10 -0
- package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-namespace-file-plugin.js +56 -0
- package/project/plugins/package-version-plugins/package.d.ts +15 -2
- package/project/plugins/package-version-plugins/package.js +33 -5
- package/project/plugins/plugin-registry.d.ts +2 -1
- package/project/plugins/plugin-registry.js +2 -0
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +2 -1
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +2 -0
- package/queries/catalog/dependencies-query/dependencies-query-format.js +2 -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.7.
|
|
27
|
+
flowR repl using flowR v2.7.2, R grammar v14 (tree-sitter engine)
|
|
28
28
|
R> :query @linter "read.csv(\"/root/x.txt\")"
|
|
29
29
|
```
|
|
30
30
|
|
|
@@ -33,19 +33,19 @@ It offers a wide variety of features, for example:
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
```text
|
|
36
|
-
Query: [;1mlinter[0m (
|
|
36
|
+
Query: [;1mlinter[0m (1 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":0,"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":1,"processTimeMs":0}</code>
|
|
49
49
|
╰ **Unused Definitions** (unused-definitions):
|
|
50
50
|
╰ _Metadata_: <code>{"totalConsidered":0,"searchTimeMs":0,"processTimeMs":0}</code>
|
|
51
51
|
╰ **Naming Convention** (naming-convention):
|
|
@@ -55,10 +55,10 @@ It offers a wide variety of features, for example:
|
|
|
55
55
|
╰ **Dataframe Access Validation** (dataframe-access-validation):
|
|
56
56
|
╰ _Metadata_: <code>{"numOperations":0,"numAccesses":0,"totalAccessed":0,"searchTimeMs":0,"processTimeMs":0}</code>
|
|
57
57
|
╰ **Dead Code** (dead-code):
|
|
58
|
-
╰ _Metadata_: <code>{"consideredNodes":5,"searchTimeMs":
|
|
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 ≈1 ms (1ms accuracy, total 2 ms)[0m[0m
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
|
|
@@ -82,17 +82,17 @@ 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":1,"processTimeMs":0}</code>\
|
|
86
86
|
╰ **File Path Validity** (file-path-validity):\
|
|
87
87
|
╰ certain:\
|
|
88
88
|
╰ Path `/root/x.txt` at 1.1-23\
|
|
89
89
|
╰ _Metadata_: <code>{"totalReads":1,"totalUnknown":0,"totalWritesBeforeAlways":0,"totalValid":0,"searchTimeMs":1,"processTimeMs":0}</code>\
|
|
90
90
|
╰ **Seeded Randomness** (seeded-randomness):\
|
|
91
|
-
╰ _Metadata_: <code>{"consumerCalls":0,"callsWithFunctionProducers":0,"callsWithAssignmentProducers":0,"callsWithNonConstantProducers":0,"callsWithOtherBranchProducers":0,"searchTimeMs":0,"processTimeMs":
|
|
91
|
+
╰ _Metadata_: <code>{"consumerCalls":0,"callsWithFunctionProducers":0,"callsWithAssignmentProducers":0,"callsWithNonConstantProducers":0,"callsWithOtherBranchProducers":0,"searchTimeMs":0,"processTimeMs":0}</code>\
|
|
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":0,"processTimeMs":
|
|
95
|
+
╰ _Metadata_: <code>{"totalConsidered":1,"totalUnknown":0,"searchTimeMs":0,"processTimeMs":1}</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,16 +100,16 @@ 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":0}</code>\
|
|
104
104
|
╰ **Dead Code** (dead-code):\
|
|
105
105
|
╰ _Metadata_: <code>{"consideredNodes":5,"searchTimeMs":0,"processTimeMs":0}</code>\
|
|
106
106
|
╰ **Useless Loops** (useless-loop):\
|
|
107
107
|
╰ _Metadata_: <code>{"numOfUselessLoops":0,"searchTimeMs":0,"processTimeMs":0}</code>\
|
|
108
|
-
_All queries together required ≈3 ms (1ms accuracy, total
|
|
108
|
+
_All queries together required ≈3 ms (1ms accuracy, total 4 ms)_
|
|
109
109
|
|
|
110
110
|
<details> <summary style="color:gray">Show Detailed Results as Json</summary>
|
|
111
111
|
|
|
112
|
-
The analysis required _3.
|
|
112
|
+
The analysis required _3.5 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.
|
|
@@ -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": 1,
|
|
130
130
|
"processTimeMs": 0
|
|
131
131
|
}
|
|
132
132
|
},
|
|
@@ -161,7 +161,7 @@ It offers a wide variety of features, for example:
|
|
|
161
161
|
"callsWithNonConstantProducers": 0,
|
|
162
162
|
"callsWithOtherBranchProducers": 0,
|
|
163
163
|
"searchTimeMs": 0,
|
|
164
|
-
"processTimeMs":
|
|
164
|
+
"processTimeMs": 0
|
|
165
165
|
}
|
|
166
166
|
},
|
|
167
167
|
"absolute-file-paths": {
|
|
@@ -181,7 +181,7 @@ It offers a wide variety of features, for example:
|
|
|
181
181
|
"totalConsidered": 1,
|
|
182
182
|
"totalUnknown": 0,
|
|
183
183
|
"searchTimeMs": 0,
|
|
184
|
-
"processTimeMs":
|
|
184
|
+
"processTimeMs": 1
|
|
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": 0
|
|
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.2, R grammar v14 (tree-sitter engine)
|
|
311
311
|
R> :query @static-slice (11@sum) file://test/testfiles/example.R
|
|
312
312
|
```
|
|
313
313
|
|
|
@@ -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!">123.4 ms</span></i> (as of Dec 17, 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.2, 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 _5.0 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
|
|
|
@@ -6,6 +6,7 @@ import { type RFunctionArgument, type RFunctionCall, EmptyArgument } from '../..
|
|
|
6
6
|
import type { RSymbol } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
7
7
|
import type { ParentInformation } from '../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
8
8
|
import { RNull } from '../../../r-bridge/lang-4.x/convert-values';
|
|
9
|
+
import type { RParseRequest } from '../../../r-bridge/retriever';
|
|
9
10
|
import type { DataFrameShapeInferenceVisitor } from '../shape-inference';
|
|
10
11
|
/**
|
|
11
12
|
* The location of a function parameter for mapping function call arguments to function parameters.
|
|
@@ -107,3 +108,7 @@ export declare function isRNull(node: RFunctionArgument<ParentInformation> | und
|
|
|
107
108
|
* Checks whether a string is a valid columns name according to the flag `check.names` in R.
|
|
108
109
|
*/
|
|
109
110
|
export declare function isValidColName(colname: string | undefined): boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Parses a text of file parse request using the provided parser function.
|
|
113
|
+
*/
|
|
114
|
+
export declare function parseRequestContent(request: RParseRequest, parser: (line: Buffer | string, lineNumber: number) => void, maxLines?: number): boolean;
|
|
@@ -12,15 +12,20 @@ exports.isDataFrameArgument = isDataFrameArgument;
|
|
|
12
12
|
exports.isNamedArgument = isNamedArgument;
|
|
13
13
|
exports.isRNull = isRNull;
|
|
14
14
|
exports.isValidColName = isValidColName;
|
|
15
|
+
exports.parseRequestContent = parseRequestContent;
|
|
15
16
|
const vertex_1 = require("../../../dataflow/graph/vertex");
|
|
16
17
|
const make_argument_1 = require("../../../dataflow/internal/process/functions/call/argument/make-argument");
|
|
17
18
|
const r_function_call_1 = require("../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
18
19
|
const visitor_1 = require("../../../r-bridge/lang-4.x/ast/model/processing/visitor");
|
|
19
20
|
const type_1 = require("../../../r-bridge/lang-4.x/ast/model/type");
|
|
20
21
|
const convert_values_1 = require("../../../r-bridge/lang-4.x/convert-values");
|
|
22
|
+
const assert_1 = require("../../../util/assert");
|
|
23
|
+
const files_1 = require("../../../util/files");
|
|
21
24
|
const resolve_args_1 = require("../resolve-args");
|
|
22
25
|
/** Regular expression representing valid columns names, e.g. for `data.frame` */
|
|
23
26
|
const ColNamesRegex = /^[A-Za-z.][A-Za-z0-9_.]*$/;
|
|
27
|
+
/** Regular expression representing line terminations (LF, CRLF, CR) */
|
|
28
|
+
const LineTerminationRegex = /\r\n|\r|\n/;
|
|
24
29
|
/**
|
|
25
30
|
* Escapes a regular expression given as string by escaping all special regular expression characters.
|
|
26
31
|
* @param text - The text to escape
|
|
@@ -181,4 +186,19 @@ function isRNull(node) {
|
|
|
181
186
|
function isValidColName(colname) {
|
|
182
187
|
return colname !== undefined && ColNamesRegex.test(colname);
|
|
183
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* Parses a text of file parse request using the provided parser function.
|
|
191
|
+
*/
|
|
192
|
+
function parseRequestContent(request, parser, maxLines) {
|
|
193
|
+
const requestType = request.request;
|
|
194
|
+
switch (requestType) {
|
|
195
|
+
case 'text':
|
|
196
|
+
(0, resolve_args_1.unescapeSpecialChars)(request.content).split(LineTerminationRegex).forEach(parser);
|
|
197
|
+
return true;
|
|
198
|
+
case 'file':
|
|
199
|
+
return (0, files_1.readLineByLineSync)(request.content, parser, maxLines);
|
|
200
|
+
default:
|
|
201
|
+
(0, assert_1.assertUnreachable)(requestType);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
184
204
|
//# sourceMappingURL=arguments.js.map
|
|
@@ -8,7 +8,6 @@ const r_function_call_1 = require("../../../r-bridge/lang-4.x/ast/model/nodes/r-
|
|
|
8
8
|
const type_1 = require("../../../r-bridge/lang-4.x/ast/model/type");
|
|
9
9
|
const retriever_1 = require("../../../r-bridge/retriever");
|
|
10
10
|
const assert_1 = require("../../../util/assert");
|
|
11
|
-
const files_1 = require("../../../util/files");
|
|
12
11
|
const dataframe_domain_1 = require("../dataframe-domain");
|
|
13
12
|
const resolve_args_1 = require("../resolve-args");
|
|
14
13
|
const arguments_1 = require("./arguments");
|
|
@@ -638,7 +637,7 @@ function mapDataFrameRead(args, params, inference, info) {
|
|
|
638
637
|
}
|
|
639
638
|
}
|
|
640
639
|
};
|
|
641
|
-
const allLines = parseRequestContent(request, parseLine, info.ctx.config.abstractInterpretation.dataFrame.readLoadedData.maxReadLines);
|
|
640
|
+
const allLines = (0, arguments_1.parseRequestContent)(request, parseLine, info.ctx.config.abstractInterpretation.dataFrame.readLoadedData.maxReadLines);
|
|
642
641
|
let colnames;
|
|
643
642
|
if (header) {
|
|
644
643
|
colnames = (0, arguments_1.filterValidNames)(firstLine, checkNames, noDupNames, params.noEmptyNames);
|
|
@@ -1105,6 +1104,7 @@ function getRequestFromRead(fileNameArg, textArg, params, info) {
|
|
|
1105
1104
|
if (fileNameArg !== undefined && fileNameArg !== r_function_call_1.EmptyArgument) {
|
|
1106
1105
|
const fileName = (0, resolve_args_1.resolveIdToArgValue)(fileNameArg, info);
|
|
1107
1106
|
if (typeof fileName === 'string') {
|
|
1107
|
+
const text = (0, resolve_args_1.unescapeSpecialChars)(fileName);
|
|
1108
1108
|
source = fileName;
|
|
1109
1109
|
const referenceChain = fileNameArg.info.file ? [fileNameArg.info.file] : [];
|
|
1110
1110
|
const sources = (0, built_in_source_1.findSource)(info.ctx.config.solver.resolveSource, fileName, { referenceChain, ctx: info.ctx });
|
|
@@ -1113,9 +1113,9 @@ function getRequestFromRead(fileNameArg, textArg, params, info) {
|
|
|
1113
1113
|
// create request from resolved source file path
|
|
1114
1114
|
request = { request: 'file', content: sources[0] };
|
|
1115
1115
|
}
|
|
1116
|
-
else if (params.text === undefined &&
|
|
1116
|
+
else if (params.text === undefined && text.includes('\n')) {
|
|
1117
1117
|
// create request from string if file name argument contains newline
|
|
1118
|
-
request = (0, retriever_1.requestFromInput)(
|
|
1118
|
+
request = (0, retriever_1.requestFromInput)(text);
|
|
1119
1119
|
}
|
|
1120
1120
|
}
|
|
1121
1121
|
}
|
|
@@ -1129,25 +1129,13 @@ function getRequestFromRead(fileNameArg, textArg, params, info) {
|
|
|
1129
1129
|
request = request ? info.ctx.files.resolveRequest(request).r : undefined;
|
|
1130
1130
|
return { source, request };
|
|
1131
1131
|
}
|
|
1132
|
-
function parseRequestContent(request, parser, maxLines) {
|
|
1133
|
-
const requestType = request.request;
|
|
1134
|
-
switch (requestType) {
|
|
1135
|
-
case 'text':
|
|
1136
|
-
request.content.split('\n').forEach(parser);
|
|
1137
|
-
return true;
|
|
1138
|
-
case 'file':
|
|
1139
|
-
return (0, files_1.readLineByLineSync)(request.content, parser, maxLines);
|
|
1140
|
-
default:
|
|
1141
|
-
(0, assert_1.assertUnreachable)(requestType);
|
|
1142
|
-
}
|
|
1143
|
-
}
|
|
1144
1132
|
/**
|
|
1145
1133
|
* Gets all entries from a line of a CSV file using a custom separator char, quote char, and comment char
|
|
1146
1134
|
*/
|
|
1147
1135
|
function getEntriesFromCsvLine(line, sep = ',', quote = '"', comment = '', trim = true) {
|
|
1148
1136
|
sep = (0, arguments_1.escapeRegExp)(sep, true); // only allow tokens like `\s`, `\t`, or `\n` in separator, quote, and comment chars
|
|
1149
|
-
quote = (0, arguments_1.escapeRegExp)(quote
|
|
1150
|
-
comment = (0, arguments_1.escapeRegExp)(comment
|
|
1137
|
+
quote = (0, arguments_1.escapeRegExp)(quote);
|
|
1138
|
+
comment = (0, arguments_1.escapeRegExp)(comment);
|
|
1151
1139
|
const quantifier = sep === '\\s' ? '+' : '*'; // do not allow unquoted empty entries in whitespace-sparated files
|
|
1152
1140
|
const LineCommentRegex = new RegExp(`[${comment}].*`);
|
|
1153
1141
|
const CsvEntryRegex = new RegExp(`(?<=^|[${sep}])(?:[${quote}]((?:[^${quote}]|[${quote}]{2})*)[${quote}]|([^${sep}]${quantifier}))`, 'g');
|
|
@@ -1172,6 +1160,11 @@ function getSelectedColumns(args, info) {
|
|
|
1172
1160
|
selectedCols = joinColumns(selectedCols, result.selectedCols);
|
|
1173
1161
|
unselectedCols = joinColumns(unselectedCols, result.unselectedCols);
|
|
1174
1162
|
}
|
|
1163
|
+
else if (arg.value?.type === type_1.RType.UnaryOp && arg.value.operator === '+' && info.idMap !== undefined) {
|
|
1164
|
+
const result = getSelectedColumns([(0, make_argument_1.toUnnamedArgument)(arg.value.operand, info.idMap)], info);
|
|
1165
|
+
selectedCols = joinColumns(selectedCols, result.selectedCols);
|
|
1166
|
+
unselectedCols = joinColumns(unselectedCols, result.unselectedCols);
|
|
1167
|
+
}
|
|
1175
1168
|
else if (arg.value?.type === type_1.RType.UnaryOp && arg.value.operator === '-' && info.idMap !== undefined) {
|
|
1176
1169
|
const result = getSelectedColumns([(0, make_argument_1.toUnnamedArgument)(arg.value.operand, info.idMap)], info);
|
|
1177
1170
|
selectedCols = joinColumns(selectedCols, result.unselectedCols);
|
|
@@ -35,7 +35,7 @@ export declare function unescapeQuotes(argument: undefined): undefined;
|
|
|
35
35
|
export declare function unescapeQuotes(argument: string): string;
|
|
36
36
|
export declare function unescapeQuotes(argument: string | undefined): string | undefined;
|
|
37
37
|
/**
|
|
38
|
-
* Unescapes escape sequences like `\n`, `\t`, `\'`, `\"`, `\\` back into actual newlines, tabs, quotes, and backslashes
|
|
38
|
+
* Unescapes escape sequences like `\r`, `\n`, `\t`, `\'`, `\"`, `\\` back into actual newlines, tabs, quotes, and backslashes
|
|
39
39
|
*/
|
|
40
40
|
export declare function unescapeSpecialChars(argument: undefined): undefined;
|
|
41
41
|
export declare function unescapeSpecialChars(argument: string): string;
|
|
@@ -113,6 +113,6 @@ function unescapeSpecialChars(argument) {
|
|
|
113
113
|
if (argument === undefined) {
|
|
114
114
|
return undefined;
|
|
115
115
|
}
|
|
116
|
-
return unescapeQuotes(argument).replaceAll('\\n', '\n').replaceAll('\\t', '\t').replaceAll('\\\\', '\\');
|
|
116
|
+
return unescapeQuotes(argument).replaceAll('\\r', '\r').replaceAll('\\n', '\n').replaceAll('\\t', '\t').replaceAll('\\\\', '\\');
|
|
117
117
|
}
|
|
118
118
|
//# sourceMappingURL=resolve-args.js.map
|
|
@@ -346,13 +346,13 @@ function applyJoinSemantics(value, { other, by }, options) {
|
|
|
346
346
|
let rows;
|
|
347
347
|
switch (joinType) {
|
|
348
348
|
case 'inner':
|
|
349
|
-
rows = value.rows.
|
|
349
|
+
rows = value.rows.max(other.rows).widenDown();
|
|
350
350
|
break;
|
|
351
351
|
case 'left':
|
|
352
|
-
rows = value.rows;
|
|
352
|
+
rows = value.rows.max(other.rows.isValue() ? [0, other.rows.value[1]] : lattice_1.Bottom);
|
|
353
353
|
break;
|
|
354
354
|
case 'right':
|
|
355
|
-
rows = other.rows;
|
|
355
|
+
rows = other.rows.max(value.rows.isValue() ? [0, value.rows.value[1]] : lattice_1.Bottom);
|
|
356
356
|
break;
|
|
357
357
|
case 'full':
|
|
358
358
|
rows = mergeInterval(value.rows, other.rows);
|
package/package.json
CHANGED
|
@@ -7,6 +7,7 @@ const flowr_analyzer_files_context_1 = require("./flowr-analyzer-files-context")
|
|
|
7
7
|
const flowr_analyzer_dependencies_context_1 = require("./flowr-analyzer-dependencies-context");
|
|
8
8
|
const flowr_analyzer_plugin_1 = require("../plugins/flowr-analyzer-plugin");
|
|
9
9
|
const flowr_analyzer_loading_order_context_1 = require("./flowr-analyzer-loading-order-context");
|
|
10
|
+
const flowr_analyzer_functions_context_1 = require("./flowr-analyzer-functions-context");
|
|
10
11
|
const arrays_1 = require("../../util/collections/arrays");
|
|
11
12
|
const retriever_1 = require("../../r-bridge/retriever");
|
|
12
13
|
const config_1 = require("../../config");
|
|
@@ -33,8 +34,9 @@ class FlowrAnalyzerContext {
|
|
|
33
34
|
this.config = config;
|
|
34
35
|
const loadingOrder = new flowr_analyzer_loading_order_context_1.FlowrAnalyzerLoadingOrderContext(this, plugins.get(flowr_analyzer_plugin_1.PluginType.LoadingOrder));
|
|
35
36
|
this.files = new flowr_analyzer_files_context_1.FlowrAnalyzerFilesContext(loadingOrder, (plugins.get(flowr_analyzer_plugin_1.PluginType.ProjectDiscovery) ?? []), (plugins.get(flowr_analyzer_plugin_1.PluginType.FileLoad) ?? []));
|
|
36
|
-
this.deps = new flowr_analyzer_dependencies_context_1.FlowrAnalyzerDependenciesContext(this, (plugins.get(flowr_analyzer_plugin_1.PluginType.DependencyIdentification) ?? []));
|
|
37
37
|
this.env = new flowr_analyzer_environment_context_1.FlowrAnalyzerEnvironmentContext(this);
|
|
38
|
+
const functions = new flowr_analyzer_functions_context_1.FlowrAnalyzerFunctionsContext(this);
|
|
39
|
+
this.deps = new flowr_analyzer_dependencies_context_1.FlowrAnalyzerDependenciesContext(functions, (plugins.get(flowr_analyzer_plugin_1.PluginType.DependencyIdentification) ?? []));
|
|
38
40
|
}
|
|
39
41
|
/** delegate request addition */
|
|
40
42
|
addRequests(requests) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AbstractFlowrAnalyzerContext } from './abstract-flowr-analyzer-context';
|
|
2
2
|
import { FlowrAnalyzerPackageVersionsPlugin } from '../plugins/package-version-plugins/flowr-analyzer-package-versions-plugin';
|
|
3
3
|
import type { Package } from '../plugins/package-version-plugins/package';
|
|
4
|
-
import type {
|
|
4
|
+
import type { FlowrAnalyzerFunctionsContext } from './flowr-analyzer-functions-context';
|
|
5
5
|
/**
|
|
6
6
|
* This is a read-only interface to the {@link FlowrAnalyzerDependenciesContext}.
|
|
7
7
|
* It prevents you from modifying the dependencies, but allows you to inspect them (which is probably what you want when using the {@link FlowrAnalyzer}).
|
|
@@ -28,10 +28,11 @@ export interface ReadOnlyFlowrAnalyzerDependenciesContext {
|
|
|
28
28
|
*/
|
|
29
29
|
export declare class FlowrAnalyzerDependenciesContext extends AbstractFlowrAnalyzerContext<undefined, void, FlowrAnalyzerPackageVersionsPlugin> implements ReadOnlyFlowrAnalyzerDependenciesContext {
|
|
30
30
|
readonly name = "flowr-analyzer-dependencies-context";
|
|
31
|
+
readonly functionsContext: FlowrAnalyzerFunctionsContext;
|
|
31
32
|
private dependencies;
|
|
32
33
|
private staticsLoaded;
|
|
33
34
|
reset(): void;
|
|
34
|
-
constructor(
|
|
35
|
+
constructor(functionsContext: FlowrAnalyzerFunctionsContext, plugins?: readonly FlowrAnalyzerPackageVersionsPlugin[]);
|
|
35
36
|
resolveStaticDependencies(): void;
|
|
36
37
|
addDependency(pkg: Package): void;
|
|
37
38
|
getDependency(name: string): Package | undefined;
|
|
@@ -10,14 +10,16 @@ const flowr_analyzer_package_versions_plugin_1 = require("../plugins/package-ver
|
|
|
10
10
|
*/
|
|
11
11
|
class FlowrAnalyzerDependenciesContext extends abstract_flowr_analyzer_context_1.AbstractFlowrAnalyzerContext {
|
|
12
12
|
name = 'flowr-analyzer-dependencies-context';
|
|
13
|
+
functionsContext;
|
|
13
14
|
dependencies = new Map();
|
|
14
15
|
staticsLoaded = false;
|
|
15
16
|
reset() {
|
|
16
17
|
this.dependencies = new Map();
|
|
17
18
|
this.staticsLoaded = false;
|
|
18
19
|
}
|
|
19
|
-
constructor(
|
|
20
|
-
super(
|
|
20
|
+
constructor(functionsContext, plugins) {
|
|
21
|
+
super(functionsContext.getAttachedContext(), flowr_analyzer_package_versions_plugin_1.FlowrAnalyzerPackageVersionsPlugin.defaultPlugin(), plugins);
|
|
22
|
+
this.functionsContext = functionsContext;
|
|
21
23
|
}
|
|
22
24
|
resolveStaticDependencies() {
|
|
23
25
|
this.applyPlugins(undefined);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AbstractFlowrAnalyzerContext } from './abstract-flowr-analyzer-context';
|
|
2
|
+
import type { FlowrAnalyzerContext } from './flowr-analyzer-context';
|
|
3
|
+
import { FlowrAnalyzerPackageVersionsPlugin } from '../plugins/package-version-plugins/flowr-analyzer-package-versions-plugin';
|
|
4
|
+
export declare enum FunctionTypes {
|
|
5
|
+
Function = "function",
|
|
6
|
+
ExportTypes = "exportTypes",
|
|
7
|
+
S3 = "S3"
|
|
8
|
+
}
|
|
9
|
+
export interface FunctionInfo {
|
|
10
|
+
name: string;
|
|
11
|
+
packageOrigin: string;
|
|
12
|
+
isExported: boolean;
|
|
13
|
+
isS3Generic: boolean;
|
|
14
|
+
s3TypeDispatch?: string;
|
|
15
|
+
inferredType?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ReadOnlyFlowrAnalyzerFunctionsContext {
|
|
18
|
+
readonly name: string;
|
|
19
|
+
getFunctionInfo(name: string, className?: string): FunctionInfo | FunctionInfo[] | undefined;
|
|
20
|
+
}
|
|
21
|
+
export declare class FlowrAnalyzerFunctionsContext extends AbstractFlowrAnalyzerContext<undefined, void, FlowrAnalyzerPackageVersionsPlugin> implements ReadOnlyFlowrAnalyzerFunctionsContext {
|
|
22
|
+
readonly name = "flowr-analyzer-functions-context";
|
|
23
|
+
private functionInfo;
|
|
24
|
+
constructor(ctx: FlowrAnalyzerContext, plugins?: readonly FlowrAnalyzerPackageVersionsPlugin[]);
|
|
25
|
+
addFunctionInfo(info: FunctionInfo): void;
|
|
26
|
+
private mergeFunctionInfo;
|
|
27
|
+
getFunctionInfo(pkg: string, name: string, s3TypeDispatch?: string): FunctionInfo | FunctionInfo[] | undefined;
|
|
28
|
+
reset(): void;
|
|
29
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FlowrAnalyzerFunctionsContext = exports.FunctionTypes = void 0;
|
|
4
|
+
const abstract_flowr_analyzer_context_1 = require("./abstract-flowr-analyzer-context");
|
|
5
|
+
const flowr_analyzer_package_versions_plugin_1 = require("../plugins/package-version-plugins/flowr-analyzer-package-versions-plugin");
|
|
6
|
+
const flowr_analyzer_package_versions_namespace_file_plugin_1 = require("../plugins/package-version-plugins/flowr-analyzer-package-versions-namespace-file-plugin");
|
|
7
|
+
var FunctionTypes;
|
|
8
|
+
(function (FunctionTypes) {
|
|
9
|
+
FunctionTypes["Function"] = "function";
|
|
10
|
+
FunctionTypes["ExportTypes"] = "exportTypes";
|
|
11
|
+
FunctionTypes["S3"] = "S3";
|
|
12
|
+
})(FunctionTypes || (exports.FunctionTypes = FunctionTypes = {}));
|
|
13
|
+
class FlowrAnalyzerFunctionsContext extends abstract_flowr_analyzer_context_1.AbstractFlowrAnalyzerContext {
|
|
14
|
+
name = 'flowr-analyzer-functions-context';
|
|
15
|
+
functionInfo = new Map();
|
|
16
|
+
constructor(ctx, plugins) {
|
|
17
|
+
super(ctx, flowr_analyzer_package_versions_plugin_1.FlowrAnalyzerPackageVersionsPlugin.defaultPlugin(), plugins);
|
|
18
|
+
}
|
|
19
|
+
addFunctionInfo(info) {
|
|
20
|
+
const list = this.functionInfo.get(info.name);
|
|
21
|
+
if (!list) {
|
|
22
|
+
this.functionInfo.set(info.name, [info]);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const other = list.find(e => e.name === info.name &&
|
|
26
|
+
e.packageOrigin === info.packageOrigin &&
|
|
27
|
+
e.s3TypeDispatch === info.s3TypeDispatch);
|
|
28
|
+
if (other) {
|
|
29
|
+
flowr_analyzer_package_versions_namespace_file_plugin_1.namespaceFileLog.warn('Namespace information is being merged!');
|
|
30
|
+
this.mergeFunctionInfo(other, info);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
list.push(info);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
mergeFunctionInfo(functionInfo, other) {
|
|
37
|
+
if (functionInfo.name !== other.name || functionInfo.packageOrigin !== other.packageOrigin) {
|
|
38
|
+
throw new Error(`Cannot merge FunctionInfo for ${functionInfo.name} and ${other.name}`);
|
|
39
|
+
}
|
|
40
|
+
if (functionInfo.s3TypeDispatch !== other.s3TypeDispatch) {
|
|
41
|
+
throw new Error(`Cannot merge FunctionInfo with different S3 dispatch for ${functionInfo.name}`);
|
|
42
|
+
}
|
|
43
|
+
if (!functionInfo.inferredType && other.inferredType) {
|
|
44
|
+
functionInfo.inferredType = other.inferredType;
|
|
45
|
+
}
|
|
46
|
+
functionInfo.isExported ||= other.isExported;
|
|
47
|
+
functionInfo.isS3Generic ||= other.isS3Generic;
|
|
48
|
+
}
|
|
49
|
+
getFunctionInfo(pkg, name, s3TypeDispatch) {
|
|
50
|
+
if (s3TypeDispatch) {
|
|
51
|
+
return this.functionInfo.get(`${name}`)?.find(e => e.packageOrigin === pkg && e.s3TypeDispatch === s3TypeDispatch);
|
|
52
|
+
}
|
|
53
|
+
else if (name.includes('.')) {
|
|
54
|
+
const parts = name.split('.');
|
|
55
|
+
s3TypeDispatch = parts.pop();
|
|
56
|
+
const splitName = parts.join('.');
|
|
57
|
+
if (this.functionInfo.has(splitName)) {
|
|
58
|
+
return this.functionInfo.get(splitName)?.find(e => e.packageOrigin === pkg && e.s3TypeDispatch === s3TypeDispatch);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return this.functionInfo.get(name)?.filter(e => e.packageOrigin === pkg);
|
|
62
|
+
}
|
|
63
|
+
reset() {
|
|
64
|
+
this.functionInfo = new Map();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.FlowrAnalyzerFunctionsContext = FlowrAnalyzerFunctionsContext;
|
|
68
|
+
//# sourceMappingURL=flowr-analyzer-functions-context.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { FileRole, FlowrFileProvider } from '../../../context/flowr-file';
|
|
2
|
+
import { FlowrFile } from '../../../context/flowr-file';
|
|
3
|
+
export interface NamespaceInfo {
|
|
4
|
+
exportedSymbols: string[];
|
|
5
|
+
exportedFunctions: string[];
|
|
6
|
+
exportS3Generics: Map<string, string[]>;
|
|
7
|
+
loadsWithSideEffects: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface NamespaceFormat {
|
|
10
|
+
current: NamespaceInfo;
|
|
11
|
+
[packageName: string]: NamespaceInfo;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* This decorates a text file and provides access to its content in the {@link NamespaceFormat}.
|
|
15
|
+
*/
|
|
16
|
+
export declare class FlowrNamespaceFile extends FlowrFile<NamespaceFormat> {
|
|
17
|
+
private readonly wrapped;
|
|
18
|
+
/**
|
|
19
|
+
* Prefer the static {@link FlowrNamespaceFile.from} method to create instances of this class as it will not re-create if already a namespace file
|
|
20
|
+
* and handle role assignments.
|
|
21
|
+
*/
|
|
22
|
+
constructor(file: FlowrFileProvider);
|
|
23
|
+
/**
|
|
24
|
+
* Loads and parses the content of the wrapped file in the {@link NamespaceFormat}.
|
|
25
|
+
* @see {@link parseNamespace} for details on the parsing logic.
|
|
26
|
+
*/
|
|
27
|
+
protected loadContent(): NamespaceFormat;
|
|
28
|
+
/**
|
|
29
|
+
* Namespace file lifter, this does not re-create if already a namespace file
|
|
30
|
+
*/
|
|
31
|
+
static from(file: FlowrFileProvider | FlowrNamespaceFile, role?: FileRole): FlowrNamespaceFile;
|
|
32
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FlowrNamespaceFile = void 0;
|
|
4
|
+
const flowr_file_1 = require("../../../context/flowr-file");
|
|
5
|
+
/**
|
|
6
|
+
* This decorates a text file and provides access to its content in the {@link NamespaceFormat}.
|
|
7
|
+
*/
|
|
8
|
+
class FlowrNamespaceFile extends flowr_file_1.FlowrFile {
|
|
9
|
+
wrapped;
|
|
10
|
+
/**
|
|
11
|
+
* Prefer the static {@link FlowrNamespaceFile.from} method to create instances of this class as it will not re-create if already a namespace file
|
|
12
|
+
* and handle role assignments.
|
|
13
|
+
*/
|
|
14
|
+
constructor(file) {
|
|
15
|
+
super(file.path(), file.role);
|
|
16
|
+
this.wrapped = file;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Loads and parses the content of the wrapped file in the {@link NamespaceFormat}.
|
|
20
|
+
* @see {@link parseNamespace} for details on the parsing logic.
|
|
21
|
+
*/
|
|
22
|
+
loadContent() {
|
|
23
|
+
return parseNamespace(this.wrapped);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Namespace file lifter, this does not re-create if already a namespace file
|
|
27
|
+
*/
|
|
28
|
+
static from(file, role) {
|
|
29
|
+
if (role) {
|
|
30
|
+
file.assignRole(role);
|
|
31
|
+
}
|
|
32
|
+
return file instanceof FlowrNamespaceFile ? file : new FlowrNamespaceFile(file);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.FlowrNamespaceFile = FlowrNamespaceFile;
|
|
36
|
+
const cleanLineCommentRegex = /^#.*$/gm;
|
|
37
|
+
/**
|
|
38
|
+
* Parses the given NAMESPACE file
|
|
39
|
+
*/
|
|
40
|
+
function parseNamespace(file) {
|
|
41
|
+
const result = {
|
|
42
|
+
current: {
|
|
43
|
+
exportedSymbols: [],
|
|
44
|
+
exportedFunctions: [],
|
|
45
|
+
exportS3Generics: new Map(),
|
|
46
|
+
loadsWithSideEffects: false,
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
const fileContent = file.content().toString().replaceAll(cleanLineCommentRegex, '').trim()
|
|
50
|
+
.split(/\r?\n/).filter(Boolean);
|
|
51
|
+
for (const line of fileContent) {
|
|
52
|
+
const match = line.trim().match(/^(\w+)\(([^)]*)\)$/);
|
|
53
|
+
if (!match) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const [, type, args] = match;
|
|
57
|
+
switch (type) {
|
|
58
|
+
case 'exportClasses':
|
|
59
|
+
case 'exportMethods':
|
|
60
|
+
result.current.exportedFunctions.push(args);
|
|
61
|
+
break;
|
|
62
|
+
case 'S3method':
|
|
63
|
+
{
|
|
64
|
+
const parts = args.split(',').map(s => s.trim());
|
|
65
|
+
if (parts.length !== 2) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const [pkg, func] = parts;
|
|
69
|
+
let arr = result.current.exportS3Generics.get(pkg);
|
|
70
|
+
if (!arr) {
|
|
71
|
+
arr = [];
|
|
72
|
+
result.current.exportS3Generics.set(pkg, arr);
|
|
73
|
+
}
|
|
74
|
+
arr.push(func);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case 'export':
|
|
78
|
+
result.current.exportedSymbols.push(args);
|
|
79
|
+
break;
|
|
80
|
+
case 'useDynLib':
|
|
81
|
+
{
|
|
82
|
+
const parts = args.split(',').map(s => s.trim());
|
|
83
|
+
if (parts.length !== 2) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const [pkg] = parts;
|
|
87
|
+
if (!result[pkg]) {
|
|
88
|
+
result[pkg] = {
|
|
89
|
+
exportedSymbols: [],
|
|
90
|
+
exportedFunctions: [],
|
|
91
|
+
exportS3Generics: new Map(),
|
|
92
|
+
loadsWithSideEffects: false,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
result[pkg].loadsWithSideEffects = true;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=flowr-namespace-file.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { FlowrAnalyzerFilePlugin } from './flowr-analyzer-file-plugin';
|
|
2
|
+
import { SemVer } from 'semver';
|
|
3
|
+
import type { PathLike } from 'fs';
|
|
4
|
+
import type { FlowrAnalyzerContext } from '../../context/flowr-analyzer-context';
|
|
5
|
+
import type { FlowrFileProvider } from '../../context/flowr-file';
|
|
6
|
+
import { FlowrNamespaceFile } from './files/flowr-namespace-file';
|
|
7
|
+
/**
|
|
8
|
+
* This plugin provides support for R `NAMESPACE` files.
|
|
9
|
+
*/
|
|
10
|
+
export declare class FlowrAnalyzerNamespaceFilePlugin extends FlowrAnalyzerFilePlugin {
|
|
11
|
+
readonly name = "flowr-analyzer-namespace-file-plugin";
|
|
12
|
+
readonly description = "This plugin provides support for NAMESPACE files and extracts their content into the NAMESPACEFormat.";
|
|
13
|
+
readonly version: SemVer;
|
|
14
|
+
private readonly pattern;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new instance of the NAMESPACE file plugin.
|
|
17
|
+
* @param filePattern - The pattern to identify NAMESPACE files, see {@link NamespaceFilePattern} for the default pattern.
|
|
18
|
+
*/
|
|
19
|
+
constructor(filePattern?: RegExp);
|
|
20
|
+
applies(file: PathLike): boolean;
|
|
21
|
+
process(_ctx: FlowrAnalyzerContext, file: FlowrFileProvider): FlowrNamespaceFile;
|
|
22
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FlowrAnalyzerNamespaceFilePlugin = void 0;
|
|
4
|
+
const flowr_analyzer_file_plugin_1 = require("./flowr-analyzer-file-plugin");
|
|
5
|
+
const semver_1 = require("semver");
|
|
6
|
+
const flowr_file_1 = require("../../context/flowr-file");
|
|
7
|
+
const flowr_namespace_file_1 = require("./files/flowr-namespace-file");
|
|
8
|
+
const built_in_source_1 = require("../../../dataflow/internal/process/functions/call/built-in/built-in-source");
|
|
9
|
+
const NamespaceFilePattern = /^NAMESPACE(\.txt)?$/i;
|
|
10
|
+
/**
|
|
11
|
+
* This plugin provides support for R `NAMESPACE` files.
|
|
12
|
+
*/
|
|
13
|
+
class FlowrAnalyzerNamespaceFilePlugin extends flowr_analyzer_file_plugin_1.FlowrAnalyzerFilePlugin {
|
|
14
|
+
name = 'flowr-analyzer-namespace-file-plugin';
|
|
15
|
+
description = 'This plugin provides support for NAMESPACE files and extracts their content into the NAMESPACEFormat.';
|
|
16
|
+
version = new semver_1.SemVer('0.1.0');
|
|
17
|
+
pattern;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new instance of the NAMESPACE file plugin.
|
|
20
|
+
* @param filePattern - The pattern to identify NAMESPACE files, see {@link NamespaceFilePattern} for the default pattern.
|
|
21
|
+
*/
|
|
22
|
+
constructor(filePattern = NamespaceFilePattern) {
|
|
23
|
+
super();
|
|
24
|
+
this.pattern = filePattern;
|
|
25
|
+
}
|
|
26
|
+
applies(file) {
|
|
27
|
+
return this.pattern.test((0, built_in_source_1.platformBasename)(file.toString()));
|
|
28
|
+
}
|
|
29
|
+
process(_ctx, file) {
|
|
30
|
+
return flowr_namespace_file_1.FlowrNamespaceFile.from(file, flowr_file_1.FileRole.Namespace);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.FlowrAnalyzerNamespaceFilePlugin = FlowrAnalyzerNamespaceFilePlugin;
|
|
34
|
+
//# sourceMappingURL=flowr-analyzer-namespace-file-plugin.js.map
|
|
@@ -7,6 +7,7 @@ const flowr_analyzer_loading_order_description_file_plugin_1 = require("./loadin
|
|
|
7
7
|
const flowr_analyzer_rmd_file_plugin_1 = require("./file-plugins/notebooks/flowr-analyzer-rmd-file-plugin");
|
|
8
8
|
const flowr_analyzer_qmd_file_plugin_1 = require("./file-plugins/notebooks/flowr-analyzer-qmd-file-plugin");
|
|
9
9
|
const flowr_analyzer_jupyter_file_plugin_1 = require("./file-plugins/notebooks/flowr-analyzer-jupyter-file-plugin");
|
|
10
|
+
const flowr_analyzer_namespace_file_plugin_1 = require("./file-plugins/flowr-analyzer-namespace-file-plugin");
|
|
10
11
|
const flowr_analyzer_news_file_plugin_1 = require("./file-plugins/flowr-analyzer-news-file-plugin");
|
|
11
12
|
/**
|
|
12
13
|
* Provides the default set of Flowr Analyzer plugins.
|
|
@@ -19,6 +20,7 @@ function FlowrAnalyzerPluginDefaults() {
|
|
|
19
20
|
new flowr_analyzer_rmd_file_plugin_1.FlowrAnalyzerRmdFilePlugin(),
|
|
20
21
|
new flowr_analyzer_qmd_file_plugin_1.FlowrAnalyzerQmdFilePlugin(),
|
|
21
22
|
new flowr_analyzer_jupyter_file_plugin_1.FlowrAnalyzerJupyterFilePlugin(),
|
|
23
|
+
new flowr_analyzer_namespace_file_plugin_1.FlowrAnalyzerNamespaceFilePlugin(),
|
|
22
24
|
new flowr_analyzer_news_file_plugin_1.FlowrAnalyzerNewsFilePlugin()
|
|
23
25
|
];
|
|
24
26
|
}
|
|
@@ -32,7 +32,11 @@ class FlowrAnalyzerPackageVersionsDescriptionFilePlugin extends flowr_analyzer_p
|
|
|
32
32
|
if (match) {
|
|
33
33
|
const [, name, operator, version] = match;
|
|
34
34
|
const range = package_1.Package.parsePackageVersionRange(operator, version);
|
|
35
|
-
ctx.deps.addDependency(new package_1.Package(
|
|
35
|
+
ctx.deps.addDependency(new package_1.Package({
|
|
36
|
+
name: name,
|
|
37
|
+
type: type,
|
|
38
|
+
versionConstraints: range ? [range] : undefined
|
|
39
|
+
}));
|
|
36
40
|
}
|
|
37
41
|
}
|
|
38
42
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FlowrAnalyzerPackageVersionsPlugin } from './flowr-analyzer-package-versions-plugin';
|
|
2
|
+
import { SemVer } from 'semver';
|
|
3
|
+
import type { FlowrAnalyzerContext } from '../../context/flowr-analyzer-context';
|
|
4
|
+
export declare const namespaceFileLog: import("tslog").Logger<import("tslog").ILogObj>;
|
|
5
|
+
export declare class FlowrAnalyzerPackageVersionsNamespaceFilePlugin extends FlowrAnalyzerPackageVersionsPlugin {
|
|
6
|
+
readonly name = "flowr-analyzer-package-version-namespace-file-plugin";
|
|
7
|
+
readonly description = "This plugin does...";
|
|
8
|
+
readonly version: SemVer;
|
|
9
|
+
process(ctx: FlowrAnalyzerContext): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FlowrAnalyzerPackageVersionsNamespaceFilePlugin = exports.namespaceFileLog = void 0;
|
|
4
|
+
const flowr_analyzer_package_versions_plugin_1 = require("./flowr-analyzer-package-versions-plugin");
|
|
5
|
+
const semver_1 = require("semver");
|
|
6
|
+
const package_1 = require("./package");
|
|
7
|
+
const flowr_file_1 = require("../../context/flowr-file");
|
|
8
|
+
const log_1 = require("../../../util/log");
|
|
9
|
+
exports.namespaceFileLog = log_1.log.getSubLogger({ name: 'flowr-analyzer-package-versions-namespace-file-plugin' });
|
|
10
|
+
class FlowrAnalyzerPackageVersionsNamespaceFilePlugin extends flowr_analyzer_package_versions_plugin_1.FlowrAnalyzerPackageVersionsPlugin {
|
|
11
|
+
name = 'flowr-analyzer-package-version-namespace-file-plugin';
|
|
12
|
+
description = 'This plugin does...';
|
|
13
|
+
version = new semver_1.SemVer('0.1.0');
|
|
14
|
+
process(ctx) {
|
|
15
|
+
const nmspcFiles = ctx.files.getFilesByRole(flowr_file_1.FileRole.Namespace);
|
|
16
|
+
exports.namespaceFileLog.info(`Found ${nmspcFiles.length} namespace files!`);
|
|
17
|
+
/** this will do the caching etc. for me */
|
|
18
|
+
const deps = nmspcFiles[0].content();
|
|
19
|
+
for (const pkg in deps) {
|
|
20
|
+
const info = deps[pkg];
|
|
21
|
+
ctx.deps.addDependency(new package_1.Package({
|
|
22
|
+
name: pkg,
|
|
23
|
+
namespaceInfo: info
|
|
24
|
+
}));
|
|
25
|
+
for (const exportedSymbol of info.exportedSymbols) {
|
|
26
|
+
ctx.deps.functionsContext.addFunctionInfo({
|
|
27
|
+
name: exportedSymbol,
|
|
28
|
+
packageOrigin: pkg,
|
|
29
|
+
isExported: true,
|
|
30
|
+
isS3Generic: false,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
for (const exportedFunction of info.exportedFunctions) {
|
|
34
|
+
ctx.deps.functionsContext.addFunctionInfo({
|
|
35
|
+
name: exportedFunction,
|
|
36
|
+
packageOrigin: pkg,
|
|
37
|
+
isExported: true,
|
|
38
|
+
isS3Generic: false,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
for (const [genericName, classes] of info.exportS3Generics.entries()) {
|
|
42
|
+
for (const s3TypeDispatch of classes) {
|
|
43
|
+
ctx.deps.functionsContext.addFunctionInfo({
|
|
44
|
+
name: genericName,
|
|
45
|
+
packageOrigin: pkg,
|
|
46
|
+
isExported: true,
|
|
47
|
+
isS3Generic: true,
|
|
48
|
+
s3TypeDispatch: s3TypeDispatch,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.FlowrAnalyzerPackageVersionsNamespaceFilePlugin = FlowrAnalyzerPackageVersionsNamespaceFilePlugin;
|
|
56
|
+
//# sourceMappingURL=flowr-analyzer-package-versions-namespace-file-plugin.js.map
|
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
import { Range } from 'semver';
|
|
2
|
+
import type { NamespaceInfo } from '../file-plugins/files/flowr-namespace-file';
|
|
2
3
|
export type PackageType = 'package' | 'system' | 'r';
|
|
4
|
+
export type PackageOptions = {
|
|
5
|
+
derivedVersion?: Range;
|
|
6
|
+
type?: PackageType;
|
|
7
|
+
dependencies?: Package[];
|
|
8
|
+
namespaceInfo?: NamespaceInfo;
|
|
9
|
+
versionConstraints?: Range[];
|
|
10
|
+
};
|
|
3
11
|
export declare class Package {
|
|
4
12
|
name: string;
|
|
5
13
|
derivedVersion?: Range;
|
|
6
14
|
type?: PackageType;
|
|
7
15
|
dependencies?: Package[];
|
|
16
|
+
namespaceInfo?: NamespaceInfo;
|
|
8
17
|
versionConstraints: Range[];
|
|
9
|
-
constructor(
|
|
18
|
+
constructor(info: {
|
|
19
|
+
name: string;
|
|
20
|
+
} & PackageOptions);
|
|
21
|
+
has(name: string, className?: string): boolean;
|
|
22
|
+
s3For(generic: string): string[];
|
|
10
23
|
mergeInPlace(other: Package): void;
|
|
11
|
-
addInfo(
|
|
24
|
+
addInfo(info: PackageOptions): void;
|
|
12
25
|
getInfo(): this;
|
|
13
26
|
deriveVersion(): Range | undefined;
|
|
14
27
|
static parsePackageVersionRange(constraint?: string, version?: string): Range | undefined;
|
|
@@ -8,22 +8,50 @@ class Package {
|
|
|
8
8
|
derivedVersion;
|
|
9
9
|
type;
|
|
10
10
|
dependencies;
|
|
11
|
+
namespaceInfo;
|
|
11
12
|
versionConstraints = [];
|
|
12
|
-
constructor(
|
|
13
|
-
this.name = name;
|
|
14
|
-
this.addInfo(
|
|
13
|
+
constructor(info) {
|
|
14
|
+
this.name = info.name;
|
|
15
|
+
this.addInfo(info);
|
|
16
|
+
}
|
|
17
|
+
has(name, className) {
|
|
18
|
+
if (!this.namespaceInfo) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
if (name.includes('.')) {
|
|
22
|
+
const [genericSplit, classSplit] = name.split('.');
|
|
23
|
+
const classes = this.namespaceInfo.exportS3Generics.get(genericSplit);
|
|
24
|
+
return classes ? classes.includes(classSplit) : false;
|
|
25
|
+
}
|
|
26
|
+
if (className) {
|
|
27
|
+
const classes = this.namespaceInfo.exportS3Generics.get(name);
|
|
28
|
+
return classes ? classes.includes(className) : false;
|
|
29
|
+
}
|
|
30
|
+
return this.namespaceInfo.exportedFunctions.includes(name) || this.namespaceInfo.exportedSymbols.includes(name);
|
|
31
|
+
}
|
|
32
|
+
s3For(generic) {
|
|
33
|
+
return this.namespaceInfo?.exportS3Generics.get(generic) ?? [];
|
|
15
34
|
}
|
|
16
35
|
mergeInPlace(other) {
|
|
17
36
|
(0, assert_1.guard)(this.name === other.name, 'Can only merge packages with the same name');
|
|
18
|
-
this.addInfo(
|
|
37
|
+
this.addInfo({
|
|
38
|
+
type: other.type,
|
|
39
|
+
dependencies: other.dependencies,
|
|
40
|
+
namespaceInfo: other.namespaceInfo,
|
|
41
|
+
versionConstraints: other.versionConstraints
|
|
42
|
+
});
|
|
19
43
|
}
|
|
20
|
-
addInfo(
|
|
44
|
+
addInfo(info) {
|
|
45
|
+
const { type, dependencies, namespaceInfo, versionConstraints } = info;
|
|
21
46
|
if (type !== undefined) {
|
|
22
47
|
this.type = type;
|
|
23
48
|
}
|
|
24
49
|
if (dependencies !== undefined) {
|
|
25
50
|
this.dependencies = dependencies;
|
|
26
51
|
}
|
|
52
|
+
if (namespaceInfo !== undefined) {
|
|
53
|
+
this.namespaceInfo = namespaceInfo;
|
|
54
|
+
}
|
|
27
55
|
if (versionConstraints !== undefined) {
|
|
28
56
|
this.derivedVersion ??= versionConstraints[0];
|
|
29
57
|
for (const constraint of versionConstraints) {
|
|
@@ -5,11 +5,12 @@ import { FlowrAnalyzerLoadingOrderDescriptionFilePlugin } from './loading-order-
|
|
|
5
5
|
import { FlowrAnalyzerRmdFilePlugin } from './file-plugins/notebooks/flowr-analyzer-rmd-file-plugin';
|
|
6
6
|
import { FlowrAnalyzerQmdFilePlugin } from './file-plugins/notebooks/flowr-analyzer-qmd-file-plugin';
|
|
7
7
|
import { FlowrAnalyzerJupyterFilePlugin } from './file-plugins/notebooks/flowr-analyzer-jupyter-file-plugin';
|
|
8
|
+
import { FlowrAnalyzerNamespaceFilePlugin } from './file-plugins/flowr-analyzer-namespace-file-plugin';
|
|
8
9
|
import { FlowrAnalyzerNewsFilePlugin } from './file-plugins/flowr-analyzer-news-file-plugin';
|
|
9
10
|
/**
|
|
10
11
|
* The built-in Flowr Analyzer plugins that are always available.
|
|
11
12
|
*/
|
|
12
|
-
export declare const BuiltInPlugins: [["file:description", typeof FlowrAnalyzerDescriptionFilePlugin], ["versions:description", typeof FlowrAnalyzerPackageVersionsDescriptionFilePlugin], ["loading-order:description", typeof FlowrAnalyzerLoadingOrderDescriptionFilePlugin], ["file:rmd", typeof FlowrAnalyzerRmdFilePlugin], ["file:qmd", typeof FlowrAnalyzerQmdFilePlugin], ["file:ipynb", typeof FlowrAnalyzerJupyterFilePlugin], ["file:news", typeof FlowrAnalyzerNewsFilePlugin]];
|
|
13
|
+
export declare const BuiltInPlugins: [["file:description", typeof FlowrAnalyzerDescriptionFilePlugin], ["versions:description", typeof FlowrAnalyzerPackageVersionsDescriptionFilePlugin], ["loading-order:description", typeof FlowrAnalyzerLoadingOrderDescriptionFilePlugin], ["file:rmd", typeof FlowrAnalyzerRmdFilePlugin], ["file:qmd", typeof FlowrAnalyzerQmdFilePlugin], ["file:ipynb", typeof FlowrAnalyzerJupyterFilePlugin], ["file:namespace", typeof FlowrAnalyzerNamespaceFilePlugin], ["file:news", typeof FlowrAnalyzerNewsFilePlugin]];
|
|
13
14
|
export type BuiltInFlowrPluginName = typeof BuiltInPlugins[number][0];
|
|
14
15
|
export type BuiltInFlowrPluginArgs<N extends BuiltInFlowrPluginName> = N extends typeof BuiltInPlugins[number][0] ? ConstructorParameters<Extract<typeof BuiltInPlugins[number], [N, PluginProducer]>[1]> : never;
|
|
15
16
|
type PluginProducer = new (...args: never[]) => FlowrAnalyzerPlugin;
|
|
@@ -11,6 +11,7 @@ const flowr_analyzer_rmd_file_plugin_1 = require("./file-plugins/notebooks/flowr
|
|
|
11
11
|
const flowr_analyzer_qmd_file_plugin_1 = require("./file-plugins/notebooks/flowr-analyzer-qmd-file-plugin");
|
|
12
12
|
const assert_1 = require("../../util/assert");
|
|
13
13
|
const flowr_analyzer_jupyter_file_plugin_1 = require("./file-plugins/notebooks/flowr-analyzer-jupyter-file-plugin");
|
|
14
|
+
const flowr_analyzer_namespace_file_plugin_1 = require("./file-plugins/flowr-analyzer-namespace-file-plugin");
|
|
14
15
|
const flowr_analyzer_news_file_plugin_1 = require("./file-plugins/flowr-analyzer-news-file-plugin");
|
|
15
16
|
/**
|
|
16
17
|
* The built-in Flowr Analyzer plugins that are always available.
|
|
@@ -22,6 +23,7 @@ exports.BuiltInPlugins = [
|
|
|
22
23
|
['file:rmd', flowr_analyzer_rmd_file_plugin_1.FlowrAnalyzerRmdFilePlugin],
|
|
23
24
|
['file:qmd', flowr_analyzer_qmd_file_plugin_1.FlowrAnalyzerQmdFilePlugin],
|
|
24
25
|
['file:ipynb', flowr_analyzer_jupyter_file_plugin_1.FlowrAnalyzerJupyterFilePlugin],
|
|
26
|
+
['file:namespace', flowr_analyzer_namespace_file_plugin_1.FlowrAnalyzerNamespaceFilePlugin],
|
|
25
27
|
['file:news', flowr_analyzer_news_file_plugin_1.FlowrAnalyzerNewsFilePlugin]
|
|
26
28
|
];
|
|
27
29
|
/**
|
|
@@ -119,7 +119,8 @@ function getResults(queries, { dataflow, config, normalize }, results, kind, fun
|
|
|
119
119
|
linkedIds: linked?.length ? linked : undefined,
|
|
120
120
|
value: value ?? defaultValue,
|
|
121
121
|
versionConstraints: dep?.versionConstraints,
|
|
122
|
-
derivedVersion: dep?.derivedVersion
|
|
122
|
+
derivedVersion: dep?.derivedVersion,
|
|
123
|
+
namespaceInfo: dep?.namespaceInfo
|
|
123
124
|
});
|
|
124
125
|
if (result) {
|
|
125
126
|
results.push(result);
|
|
@@ -6,6 +6,7 @@ import type { FunctionInfo } from './function-info/function-info';
|
|
|
6
6
|
import type { CallContextQueryResult } from '../call-context-query/call-context-query-format';
|
|
7
7
|
import type { Range } from 'semver';
|
|
8
8
|
import type { AsyncOrSync } from 'ts-essentials';
|
|
9
|
+
import type { NamespaceInfo } from '../../../project/plugins/file-plugins/files/flowr-namespace-file';
|
|
9
10
|
export declare const Unknown = "unknown";
|
|
10
11
|
export interface DependencyCategorySettings {
|
|
11
12
|
queryDisplayName?: string;
|
|
@@ -63,6 +64,7 @@ export interface DependencyInfo extends Record<string, unknown> {
|
|
|
63
64
|
value?: string;
|
|
64
65
|
versionConstraints?: Range[];
|
|
65
66
|
derivedVersion?: Range;
|
|
67
|
+
namespaceInfo?: NamespaceInfo;
|
|
66
68
|
}
|
|
67
69
|
/**
|
|
68
70
|
* Gets all dependency categories, including user-defined additional categories.
|
|
@@ -34,7 +34,8 @@ exports.DefaultDependencyCategories = {
|
|
|
34
34
|
functionName: (n.info.fullLexeme ?? n.lexeme).includes(':::') ? ':::' : '::',
|
|
35
35
|
value: n.namespace,
|
|
36
36
|
versionConstraints: dep?.versionConstraints,
|
|
37
|
-
derivedVersion: dep?.derivedVersion
|
|
37
|
+
derivedVersion: dep?.derivedVersion,
|
|
38
|
+
namespaceInfo: dep?.namespaceInfo
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
41
|
});
|
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.3';
|
|
10
10
|
/**
|
|
11
11
|
* Retrieves the current flowR version as a new {@link SemVer} object.
|
|
12
12
|
*/
|