@eagleoutice/flowr 2.0.4 → 2.0.6
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 +1 -1
- package/dataflow/internal/linker.js +1 -1
- package/package.json +1 -1
- package/r-bridge/init.js +2 -1
- package/r-bridge/lang-4.x/ast/model/type.d.ts +6 -0
- package/r-bridge/lang-4.x/ast/parser/json/format.js +7 -1
- package/r-bridge/lang-4.x/ast/parser/xml/internal/functions/normalize-call.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/xml/internal/loops/normalize-for.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/xml/internal/normalize-access.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/xml/internal/operators/normalize-binary.js +7 -5
- package/r-bridge/lang-4.x/ast/parser/xml/internal/structure/normalize-expressions.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/parser/xml/internal/structure/normalize-expressions.js +4 -4
- package/r-bridge/lang-4.x/ast/parser/xml/internal/structure/normalize-single-node.js +1 -0
- package/r-bridge/lang-4.x/ast/parser/xml/normalize-meta.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/parser/xml/normalize-meta.js +1 -1
- package/r-bridge/shell.js +3 -1
- package/util/version.js +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
[](https://github.com/Code-Inspect/flowr/actions/workflows/qa.yaml) [](https://codecov.io/gh/Code-Inspect/flowr) [](https://hub.docker.com/r/eagleoutice/flowr) [](https://github.com/Code-Inspect/flowr/releases/latest) [](https://marketplace.visualstudio.com/items?itemName=code-inspect.vscode-flowr)
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
*flowR* is a static [dataflow analyzer](https://en.wikipedia.org/wiki/Data-flow_analysis) and [program slicer](https://github.com/Code-Inspect/flowr/wiki/Terminology#program-slice) for the [*R*](https://www.r-project.org/) programming language (currently tested for versions `4.x`). It is available as a [Visual Studio Code extension](https://marketplace.visualstudio.com/items?itemName=code-inspect.vscode-flowr) and as a [docker image](https://hub.docker.com/r/eagleoutice/flowr).
|
|
5
|
+
*flowR* is a static [dataflow analyzer](https://en.wikipedia.org/wiki/Data-flow_analysis) and [program slicer](https://github.com/Code-Inspect/flowr/wiki/Terminology#program-slice) for the [*R*](https://www.r-project.org/) programming language (currently tested for versions `4.x` and `3.6.x`). It is available as a [Visual Studio Code extension](https://marketplace.visualstudio.com/items?itemName=code-inspect.vscode-flowr) and as a [docker image](https://hub.docker.com/r/eagleoutice/flowr).
|
|
6
6
|
|
|
7
7
|
## ⭐ Getting Started
|
|
8
8
|
|
|
@@ -55,7 +55,7 @@ function linkArgumentsOnCall(args, params, graph) {
|
|
|
55
55
|
graph.addEdge(arg.nodeId, specialDotParameter.name.info.id, { type: 16 /* EdgeType.DefinesOnCall */ });
|
|
56
56
|
}
|
|
57
57
|
else {
|
|
58
|
-
logger_1.dataflowLogger.
|
|
58
|
+
logger_1.dataflowLogger.warn(`skipping argument ${i} as there is no corresponding parameter - R should block that`);
|
|
59
59
|
}
|
|
60
60
|
continue;
|
|
61
61
|
}
|
package/package.json
CHANGED
package/r-bridge/init.js
CHANGED
|
@@ -7,8 +7,9 @@ exports.ErrorMarker = 'err';
|
|
|
7
7
|
function initCommand(eol) {
|
|
8
8
|
/* define the get function complete wrapped in a try so that we can handle failures gracefully on stdout
|
|
9
9
|
* furthermore, we compile for performance reasons
|
|
10
|
+
* Please note that we add a `flowr_output` assignment before to avoid issues with earlier R versions
|
|
10
11
|
*/
|
|
11
|
-
return 'flowr_get_ast<-compiler::cmpfun(function(...){tryCatch({'
|
|
12
|
+
return 'flowr_output<-NULL;flowr_get_ast<-compiler::cmpfun(function(...){tryCatch({'
|
|
12
13
|
/* the actual code to parse the R code, ... allows us to keep the old 'file=path' and 'text=content' semantics. we define flowr_output using the super assignment to persist it in the env! */
|
|
13
14
|
+ 'flowr_output<<-getParseData(parse(...,keep.source=TRUE),includeText=TRUE);'
|
|
14
15
|
/* json conversion of the output, dataframe="values" allows us to receive a list of lists (which is more compact)!
|
|
@@ -138,6 +138,12 @@ export declare const enum RawRType {
|
|
|
138
138
|
* https://github.com/REditorSupport/languageserver/pull/328
|
|
139
139
|
*/
|
|
140
140
|
ExprOfAssignOrHelp = "expr_or_assign_or_help",
|
|
141
|
+
/**
|
|
142
|
+
* Pre-4.0 version of expr_or_assign_or_help, which was seemingly silently renamed here:
|
|
143
|
+
* https://github.com/wch/r-source/commit/84bbf385f909c0223924c310af6c7c77aa810234
|
|
144
|
+
* (Also see {@link ExprOfAssignOrHelp} documentation for more context.)
|
|
145
|
+
*/
|
|
146
|
+
LegacyEqualAssign = "equal_assign",
|
|
141
147
|
/** T65 */
|
|
142
148
|
ExpressionList = "exprlist"
|
|
143
149
|
}
|
|
@@ -8,7 +8,13 @@ exports.RootId = 0;
|
|
|
8
8
|
* Parses the given data and sets child relationship, return the list of root entries (with a parent of {@link RootId}).
|
|
9
9
|
*/
|
|
10
10
|
function prepareParsedData(data) {
|
|
11
|
-
|
|
11
|
+
let json;
|
|
12
|
+
try {
|
|
13
|
+
json = JSON.parse(`[${data}]`);
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
throw new Error(`Failed to parse data ${data}: ${e?.message}`);
|
|
17
|
+
}
|
|
12
18
|
(0, assert_1.guard)(Array.isArray(json), () => `Expected ${data} to be an array but was not`);
|
|
13
19
|
const ret = new Map(json.map(([line1, col1, line2, col2, id, parent, token, terminal, text]) => {
|
|
14
20
|
return [id, { line1, col1, line2, col2, id, parent, token: (0, retriever_1.removeRQuotes)(token), terminal, text }];
|
|
@@ -22,7 +22,7 @@ const normalize_symbol_1 = require("../values/normalize-symbol");
|
|
|
22
22
|
*/
|
|
23
23
|
function tryNormalizeFunctionCall(data, mappedWithName) {
|
|
24
24
|
const fnBase = mappedWithName[0];
|
|
25
|
-
if (fnBase.name !== "expr" /* RawRType.Expression */ && fnBase.name !== "expr_or_assign_or_help" /* RawRType.ExprOfAssignOrHelp */) {
|
|
25
|
+
if (fnBase.name !== "expr" /* RawRType.Expression */ && fnBase.name !== "expr_or_assign_or_help" /* RawRType.ExprOfAssignOrHelp */ && fnBase.name !== "equal_assign" /* RawRType.LegacyEqualAssign */) {
|
|
26
26
|
parser_1.parseLog.trace(`expected function call name to be wrapped an expression, yet received ${fnBase.name}`);
|
|
27
27
|
return undefined;
|
|
28
28
|
}
|
|
@@ -18,7 +18,7 @@ function tryNormalizeFor(data, [forToken, head, body]) {
|
|
|
18
18
|
else if (head.name !== "forcond" /* RawRType.ForCondition */) {
|
|
19
19
|
throw new input_format_1.XmlParseError(`expected condition for for-loop but found ${JSON.stringify(head)}`);
|
|
20
20
|
}
|
|
21
|
-
else if (body.name !== "expr" /* RawRType.Expression */ && body.name !== "expr_or_assign_or_help" /* RawRType.ExprOfAssignOrHelp */) {
|
|
21
|
+
else if (body.name !== "expr" /* RawRType.Expression */ && body.name !== "expr_or_assign_or_help" /* RawRType.ExprOfAssignOrHelp */ && body.name !== "equal_assign" /* RawRType.LegacyEqualAssign */) {
|
|
22
22
|
throw new input_format_1.XmlParseError(`expected expr body for for-loop but found ${JSON.stringify(body)}`);
|
|
23
23
|
}
|
|
24
24
|
parser_1.parseLog.debug('trying to parse for-loop');
|
|
@@ -72,7 +72,7 @@ function tryNormalizeAccess(data, mappedWithName) {
|
|
|
72
72
|
return undefined;
|
|
73
73
|
}
|
|
74
74
|
const accessed = mappedWithName[0];
|
|
75
|
-
if (accessed.name !== "expr" /* RawRType.Expression */ && accessed.name !== "expr_or_assign_or_help" /* RawRType.ExprOfAssignOrHelp */) {
|
|
75
|
+
if (accessed.name !== "expr" /* RawRType.Expression */ && accessed.name !== "expr_or_assign_or_help" /* RawRType.ExprOfAssignOrHelp */ && accessed.name !== "equal_assign" /* RawRType.LegacyEqualAssign */) {
|
|
76
76
|
parser_1.parseLog.trace(`expected accessed element to be wrapped an expression, yet received ${accessed.name}`);
|
|
77
77
|
return undefined;
|
|
78
78
|
}
|
|
@@ -33,7 +33,9 @@ function parseBinaryOp(data, lhs, operator, rhs) {
|
|
|
33
33
|
const operationName = (0, normalize_meta_1.retrieveOpName)(operator);
|
|
34
34
|
const { location, content } = (0, normalize_meta_1.retrieveMetaStructure)(operator.content);
|
|
35
35
|
if ((0, strings_1.startAndEndsWith)(operationName, '%')) {
|
|
36
|
-
|
|
36
|
+
const lhsLoc = parsedLhs.type === "RExpressionList" /* RType.ExpressionList */ ? parsedLhs.grouping?.[0].location : parsedLhs.location;
|
|
37
|
+
const rhsLoc = parsedRhs.type === "RExpressionList" /* RType.ExpressionList */ ? parsedRhs.grouping?.[0].location : parsedRhs.location;
|
|
38
|
+
(0, assert_1.guard)(lhsLoc !== undefined && rhsLoc !== undefined, () => `special op lhs and rhs must have a locations, but ${JSON.stringify(parsedLhs)} || ${JSON.stringify(lhsLoc)} and ${JSON.stringify(parsedRhs)} || || ${JSON.stringify(rhsLoc)})`);
|
|
37
39
|
// parse as infix function call!
|
|
38
40
|
return {
|
|
39
41
|
type: "RFunctionCall" /* RType.FunctionCall */,
|
|
@@ -52,18 +54,18 @@ function parseBinaryOp(data, lhs, operator, rhs) {
|
|
|
52
54
|
arguments: [
|
|
53
55
|
{
|
|
54
56
|
type: "RArgument" /* RType.Argument */,
|
|
55
|
-
location:
|
|
57
|
+
location: lhsLoc,
|
|
56
58
|
value: parsedLhs,
|
|
57
59
|
name: undefined,
|
|
58
|
-
lexeme: parsedLhs.lexeme,
|
|
60
|
+
lexeme: parsedLhs.lexeme ?? '',
|
|
59
61
|
info: {}
|
|
60
62
|
},
|
|
61
63
|
{
|
|
62
64
|
type: "RArgument" /* RType.Argument */,
|
|
63
|
-
location:
|
|
65
|
+
location: rhsLoc,
|
|
64
66
|
value: parsedRhs,
|
|
65
67
|
name: undefined,
|
|
66
|
-
lexeme: parsedRhs.lexeme,
|
|
68
|
+
lexeme: parsedRhs.lexeme ?? '',
|
|
67
69
|
info: {}
|
|
68
70
|
}
|
|
69
71
|
],
|
|
@@ -7,4 +7,4 @@ export declare function splitComments(tokens: readonly NamedXmlBasedJson[]): {
|
|
|
7
7
|
others: NamedXmlBasedJson[];
|
|
8
8
|
};
|
|
9
9
|
export declare function normalizeExpressions(data: NormalizerData, tokens: readonly XmlBasedJson[] | readonly NamedXmlBasedJson[]): (RNode | RDelimiter)[];
|
|
10
|
-
export declare function parseNodesWithUnknownType(data: NormalizerData, mappedWithName: readonly NamedXmlBasedJson[]): (RNode | RDelimiter)[];
|
|
10
|
+
export declare function parseNodesWithUnknownType(data: NormalizerData, mappedWithName: readonly NamedXmlBasedJson[] | undefined): (RNode | RDelimiter)[];
|
|
@@ -18,7 +18,7 @@ const normalize_if_then_else_1 = require("../control/normalize-if-then-else");
|
|
|
18
18
|
const normalize_comment_1 = require("../other/normalize-comment");
|
|
19
19
|
function normalizeMappedWithoutSemicolonBasedOnType(mappedWithName, data) {
|
|
20
20
|
let result = undefined;
|
|
21
|
-
switch (mappedWithName
|
|
21
|
+
switch (mappedWithName?.length) {
|
|
22
22
|
case 1:
|
|
23
23
|
result = (0, normalize_single_node_1.normalizeSingleNode)(data, mappedWithName[0]);
|
|
24
24
|
break;
|
|
@@ -67,7 +67,7 @@ function splitExprs(tokens) {
|
|
|
67
67
|
last = i + 1;
|
|
68
68
|
}
|
|
69
69
|
else {
|
|
70
|
-
const thisExpr = token.name === "expr" /* RawRType.Expression */ || token.name === "expr_or_assign_or_help" /* RawRType.ExprOfAssignOrHelp */;
|
|
70
|
+
const thisExpr = token.name === "expr" /* RawRType.Expression */ || token.name === "expr_or_assign_or_help" /* RawRType.ExprOfAssignOrHelp */ || token.name === "equal_assign" /* RawRType.LegacyEqualAssign */;
|
|
71
71
|
if (thisExpr && lastExpr) {
|
|
72
72
|
if (i > last) {
|
|
73
73
|
segments.push(tokens.slice(last, i));
|
|
@@ -93,7 +93,7 @@ function handleExpressionList(raw) {
|
|
|
93
93
|
return { segments: [], comments: [], braces: undefined };
|
|
94
94
|
}
|
|
95
95
|
const { comments, others: tokens } = splitComments(raw);
|
|
96
|
-
const first = tokens[0]
|
|
96
|
+
const first = tokens[0]?.name;
|
|
97
97
|
if (first === "{" /* RawRType.BraceLeft */) {
|
|
98
98
|
const endType = tokens[tokens.length - 1].name;
|
|
99
99
|
(0, assert_1.guard)(endType === "}" /* RawRType.BraceRight */, () => `expected a brace at the end of the expression list as well, but ${endType} :: ${JSON.stringify(tokens[tokens.length - 1], json_1.jsonReplacer)}`);
|
|
@@ -172,7 +172,7 @@ exports.normalizeExpressions = normalizeExpressions;
|
|
|
172
172
|
function parseNodesWithUnknownType(data, mappedWithName) {
|
|
173
173
|
const parsedNodes = [];
|
|
174
174
|
// used to indicate the new root node of this set of nodes
|
|
175
|
-
for (const elem of mappedWithName) {
|
|
175
|
+
for (const elem of mappedWithName ?? []) {
|
|
176
176
|
const retrieved = (0, normalize_single_node_1.normalizeSingleNode)(data, elem);
|
|
177
177
|
parsedNodes.push(retrieved);
|
|
178
178
|
}
|
|
@@ -35,6 +35,7 @@ function normalizeSingleNode(data, elem) {
|
|
|
35
35
|
case "exprlist" /* RawRType.ExpressionList */:
|
|
36
36
|
case "expr" /* RawRType.Expression */:
|
|
37
37
|
case "expr_or_assign_or_help" /* RawRType.ExprOfAssignOrHelp */:
|
|
38
|
+
case "equal_assign" /* RawRType.LegacyEqualAssign */:
|
|
38
39
|
return (0, normalize_expression_1.normalizeExpression)(data, elem.content);
|
|
39
40
|
case "NUM_CONST" /* RawRType.NumericConst */:
|
|
40
41
|
return (0, normalize_number_1.normalizeNumber)(data, elem.content);
|
|
@@ -32,7 +32,7 @@ export declare function assureTokenType(obj: XmlBasedJson, expectedName: RawRTyp
|
|
|
32
32
|
* @param content - the json object to extract the token-type from
|
|
33
33
|
*/
|
|
34
34
|
export declare function getTokenType(content: XmlBasedJson): RawRType;
|
|
35
|
-
export declare function getWithTokenType(obj: XmlBasedJson[]): {
|
|
35
|
+
export declare function getWithTokenType(obj: readonly XmlBasedJson[]): {
|
|
36
36
|
name: RawRType;
|
|
37
37
|
content: XmlBasedJson;
|
|
38
38
|
}[];
|
package/r-bridge/shell.js
CHANGED
|
@@ -51,7 +51,9 @@ exports.DEFAULT_OUTPUT_COLLECTOR_CONFIGURATION = {
|
|
|
51
51
|
exports.DEFAULT_R_PATH = (0, os_1.getPlatform)() === 'windows' ? 'R.exe' : 'R';
|
|
52
52
|
exports.DEFAULT_R_SHELL_EXEC_OPTIONS = {
|
|
53
53
|
pathToRExecutable: (0, config_1.getConfig)().rPath ?? exports.DEFAULT_R_PATH,
|
|
54
|
-
|
|
54
|
+
// -s is a short form of --no-echo (and the old version --slave), but this one works in R 3 and 4
|
|
55
|
+
// (see https://github.com/wch/r-source/commit/f1ff49e74593341c74c20de9517f31a22c8bcb04)
|
|
56
|
+
commandLineOptions: ['--vanilla', '--quiet', '--no-save', '-s'],
|
|
55
57
|
cwd: process.cwd(),
|
|
56
58
|
env: undefined,
|
|
57
59
|
eol: '\n',
|
package/util/version.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.flowrVersion = void 0;
|
|
4
4
|
const semver_1 = require("semver");
|
|
5
5
|
// this is automatically replaced with the current version by release-it
|
|
6
|
-
const version = '2.0.
|
|
6
|
+
const version = '2.0.6';
|
|
7
7
|
function flowrVersion() {
|
|
8
8
|
return new semver_1.SemVer(version);
|
|
9
9
|
}
|