@eagleoutice/flowr 2.1.7 → 2.1.9
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 +2 -1
- package/abstract-interpretation/normalized-ast-fold.d.ts +124 -0
- package/abstract-interpretation/normalized-ast-fold.js +178 -0
- package/benchmark/summarizer/first-phase/process.js +6 -5
- package/cli/repl/commands/repl-dataflow.js +5 -2
- package/cli/repl/commands/repl-normalize.js +5 -2
- package/cli/repl/commands/repl-query.js +2 -2
- package/cli/repl/server/messages/message-query.js +1 -1
- package/cli/slicer-app.js +1 -1
- package/core/steps/pipeline/pipeline.d.ts +63 -0
- package/dataflow/environments/default-builtin-config.js +45 -6
- package/dataflow/environments/environment.d.ts +46 -8
- package/dataflow/environments/environment.js +24 -1
- package/dataflow/environments/identifier.d.ts +49 -7
- package/dataflow/environments/identifier.js +11 -2
- package/dataflow/environments/resolve-by-name.d.ts +5 -0
- package/dataflow/environments/resolve-by-name.js +14 -0
- package/dataflow/extractor.js +5 -4
- package/dataflow/graph/dataflowgraph-builder.d.ts +6 -0
- package/dataflow/graph/dataflowgraph-builder.js +8 -0
- package/dataflow/graph/edge.d.ts +10 -4
- package/dataflow/graph/edge.js +12 -5
- package/dataflow/graph/graph.d.ts +41 -3
- package/dataflow/graph/graph.js +39 -34
- package/dataflow/graph/vertex.d.ts +66 -7
- package/dataflow/graph/vertex.js +15 -0
- package/dataflow/info.d.ts +79 -11
- package/dataflow/info.js +20 -0
- package/dataflow/internal/linker.d.ts +4 -2
- package/dataflow/internal/linker.js +12 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +2 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +5 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +16 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +83 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +17 -7
- package/dataflow/internal/process/functions/call/common.js +1 -1
- package/documentation/doc-util/doc-dfg.d.ts +2 -2
- package/documentation/doc-util/doc-dfg.js +11 -16
- package/documentation/doc-util/doc-normalized-ast.js +1 -1
- package/documentation/doc-util/doc-types.d.ts +1 -1
- package/documentation/doc-util/doc-types.js +21 -0
- package/documentation/print-capabilities-markdown.js +1 -1
- package/documentation/print-dataflow-graph-wiki.js +44 -7
- package/documentation/print-linting-and-testing-wiki.js +60 -26
- package/documentation/print-normalized-ast-wiki.js +107 -5
- package/documentation/print-query-wiki.js +8 -1
- package/package.json +17 -3
- package/queries/catalog/call-context-query/call-context-query-executor.js +23 -2
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +29 -2
- package/queries/catalog/call-context-query/call-context-query-format.js +7 -1
- package/queries/catalog/call-context-query/cascade-action.d.ts +8 -0
- package/queries/catalog/call-context-query/cascade-action.js +13 -0
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +11 -1
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +41 -4
- package/queries/catalog/dependencies-query/dependencies-query-format.js +4 -0
- package/queries/query.d.ts +4 -4
- package/queries/query.js +17 -5
- package/r-bridge/lang-4.x/ast/model/model.d.ts +3 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +5 -1
- package/r-bridge/lang-4.x/ast/model/processing/node-id.d.ts +6 -1
- package/r-bridge/lang-4.x/ast/model/processing/node-id.js +6 -1
- package/r-bridge/lang-4.x/ast/model/processing/visitor.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/visitor.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/json/format.js +2 -2
- package/reconstruct/reconstruct.js +1 -1
- package/slicing/static/slice-call.d.ts +7 -2
- package/slicing/static/slice-call.js +33 -44
- package/slicing/static/static-slicer.d.ts +5 -1
- package/slicing/static/static-slicer.js +22 -8
- package/slicing/static/visiting-queue.d.ts +4 -4
- package/slicing/static/visiting-queue.js +5 -3
- package/statistics/output/print-stats.js +2 -1
- package/statistics/summarizer/post-process/histogram.js +2 -1
- package/statistics/summarizer/post-process/post-process-output.js +2 -1
- package/statistics/summarizer/second-phase/process.js +3 -3
- package/util/arrays.d.ts +1 -1
- package/util/arrays.js +3 -3
- package/util/assert.d.ts +1 -1
- package/util/assert.js +3 -2
- package/util/cfg/cfg.js +4 -2
- package/util/mermaid/cfg.js +1 -1
- package/util/summarizer.js +2 -2
- package/util/version.js +1 -1
package/README.md
CHANGED
|
@@ -34,7 +34,6 @@ We welcome every contribution! Please check out the [contributing guidelines](ht
|
|
|
34
34
|
### Contributors
|
|
35
35
|
|
|
36
36
|
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
37
|
-
<!--suppress ALL -->
|
|
38
37
|
<!-- prettier-ignore-start -->
|
|
39
38
|
<!-- markdownlint-disable -->
|
|
40
39
|
<table>
|
|
@@ -42,6 +41,7 @@ We welcome every contribution! Please check out the [contributing guidelines](ht
|
|
|
42
41
|
<tr>
|
|
43
42
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/EagleoutIce"><img src="https://avatars.githubusercontent.com/u/9303573?v=4?s=100" width="100px;" alt="Florian Sihler"/><br /><sub><b>Florian Sihler</b></sub></a><br /><a href="https://github.com/flowr-analysis/flowr/commits?author=EagleoutIce" title="Code">💻</a> <a href="#ideas-EagleoutIce" title="Ideas, Planning, & Feedback">🤔</a> <a href="#maintenance-EagleoutIce" title="Maintenance">🚧</a> <a href="#projectManagement-EagleoutIce" title="Project Management">📆</a> <a href="#research-EagleoutIce" title="Research">🔬</a> <a href="https://github.com/flowr-analysis/flowr/commits?author=EagleoutIce" title="Tests">⚠️</a> <a href="#talk-EagleoutIce" title="Talks">📢</a></td>
|
|
44
43
|
<td align="center" valign="top" width="14.28%"><a href="https://ellpeck.de/"><img src="https://avatars.githubusercontent.com/u/5741138?v=4?s=100" width="100px;" alt="Ell"/><br /><sub><b>Ell</b></sub></a><br /><a href="https://github.com/flowr-analysis/flowr/commits?author=Ellpeck" title="Code">💻</a> <a href="#maintenance-Ellpeck" title="Maintenance">🚧</a> <a href="https://github.com/flowr-analysis/flowr/commits?author=Ellpeck" title="Tests">⚠️</a> <a href="#plugin-Ellpeck" title="Plugin/utility libraries">🔌</a></td>
|
|
44
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gigalasr"><img src="https://avatars.githubusercontent.com/u/25102989?v=4?s=100" width="100px;" alt="Lars"/><br /><sub><b>Lars</b></sub></a><br /><a href="https://github.com/flowr-analysis/flowr/commits?author=gigalasr" title="Code">💻</a> <a href="https://github.com/flowr-analysis/flowr/commits?author=gigalasr" title="Tests">⚠️</a></td>
|
|
45
45
|
<td align="center" valign="top" width="14.28%"><a href="https://lukas.pietzschmann.org/"><img src="https://avatars.githubusercontent.com/u/49213919?v=4?s=100" width="100px;" alt="Lukas Pietzschmann"/><br /><sub><b>Lukas Pietzschmann</b></sub></a><br /><a href="https://github.com/flowr-analysis/flowr/commits?author=LukasPietzschmann" title="Code">💻</a> <a href="https://github.com/flowr-analysis/flowr/commits?author=LukasPietzschmann" title="Tests">⚠️</a></td>
|
|
46
46
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bjthehun"><img src="https://avatars.githubusercontent.com/u/38729215?v=4?s=100" width="100px;" alt="Benedikt Jutz"/><br /><sub><b>Benedikt Jutz</b></sub></a><br /><a href="https://github.com/flowr-analysis/flowr/commits?author=bjthehun" title="Code">💻</a> <a href="https://github.com/flowr-analysis/flowr/commits?author=bjthehun" title="Tests">⚠️</a></td>
|
|
47
47
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Core5563"><img src="https://avatars.githubusercontent.com/u/140061253?v=4?s=100" width="100px;" alt="Core5563"/><br /><sub><b>Core5563</b></sub></a><br /><a href="https://github.com/flowr-analysis/flowr/commits?author=Core5563" title="Code">💻</a> <a href="https://github.com/flowr-analysis/flowr/commits?author=Core5563" title="Tests">⚠️</a></td>
|
|
@@ -61,6 +61,7 @@ We welcome every contribution! Please check out the [contributing guidelines](ht
|
|
|
61
61
|
|
|
62
62
|
<!-- markdownlint-restore -->
|
|
63
63
|
<!-- prettier-ignore-end -->
|
|
64
|
+
|
|
64
65
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
65
66
|
|
|
66
67
|
----
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { NoInfo, RNode } from '../r-bridge/lang-4.x/ast/model/model';
|
|
2
|
+
import type { RExpressionList } from '../r-bridge/lang-4.x/ast/model/nodes/r-expression-list';
|
|
3
|
+
import type { RFunctionCall } from '../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
4
|
+
import { EmptyArgument } from '../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
5
|
+
import type { RFunctionDefinition } from '../r-bridge/lang-4.x/ast/model/nodes/r-function-definition';
|
|
6
|
+
import { RType } from '../r-bridge/lang-4.x/ast/model/type';
|
|
7
|
+
import type { RForLoop } from '../r-bridge/lang-4.x/ast/model/nodes/r-for-loop';
|
|
8
|
+
import type { RWhileLoop } from '../r-bridge/lang-4.x/ast/model/nodes/r-while-loop';
|
|
9
|
+
import type { RRepeatLoop } from '../r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop';
|
|
10
|
+
import type { RIfThenElse } from '../r-bridge/lang-4.x/ast/model/nodes/r-if-then-else';
|
|
11
|
+
import type { RBinaryOp } from '../r-bridge/lang-4.x/ast/model/nodes/r-binary-op';
|
|
12
|
+
import type { RPipe } from '../r-bridge/lang-4.x/ast/model/nodes/r-pipe';
|
|
13
|
+
import type { RUnaryOp } from '../r-bridge/lang-4.x/ast/model/nodes/r-unary-op';
|
|
14
|
+
import type { RParameter } from '../r-bridge/lang-4.x/ast/model/nodes/r-parameter';
|
|
15
|
+
import type { RArgument } from '../r-bridge/lang-4.x/ast/model/nodes/r-argument';
|
|
16
|
+
import type { RAccess } from '../r-bridge/lang-4.x/ast/model/nodes/r-access';
|
|
17
|
+
import type { RLogical } from '../r-bridge/lang-4.x/ast/model/nodes/r-logical';
|
|
18
|
+
import type { RBreak } from '../r-bridge/lang-4.x/ast/model/nodes/r-break';
|
|
19
|
+
import type { RComment } from '../r-bridge/lang-4.x/ast/model/nodes/r-comment';
|
|
20
|
+
import type { RNext } from '../r-bridge/lang-4.x/ast/model/nodes/r-next';
|
|
21
|
+
import type { RNumber } from '../r-bridge/lang-4.x/ast/model/nodes/r-number';
|
|
22
|
+
import type { RLineDirective } from '../r-bridge/lang-4.x/ast/model/nodes/r-line-directive';
|
|
23
|
+
import type { RString } from '../r-bridge/lang-4.x/ast/model/nodes/r-string';
|
|
24
|
+
import type { RSymbol } from '../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
25
|
+
type FoldOfType<T extends RType, Returns = void, Info = NoInfo> = (node: Extract<RNode<Info>, {
|
|
26
|
+
type: T;
|
|
27
|
+
}>) => Returns;
|
|
28
|
+
/** explicitly excludes types that are not visitable */
|
|
29
|
+
export type FoldableRType = Exclude<RType, RType.Delimiter>;
|
|
30
|
+
/**
|
|
31
|
+
* Describes the fold functions for each node type.
|
|
32
|
+
*/
|
|
33
|
+
export type NormalizedAstFold<Returns = void, Info = NoInfo> = {
|
|
34
|
+
[K in FoldableRType as `fold${Capitalize<K>}`]: FoldOfType<K, Returns, Info>;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Describes the type of a mapping object,
|
|
38
|
+
* which maps the type of the normalized AST node to the corresponding fold function.
|
|
39
|
+
*/
|
|
40
|
+
export type FittingNormalizedAstFold<Returns = void, Info = NoInfo> = Readonly<{
|
|
41
|
+
[K in FoldableRType]: FoldOfType<K, Returns, Info>;
|
|
42
|
+
}>;
|
|
43
|
+
export type SingleOrArrayOrNothing<T> = T | readonly (T | null | undefined)[] | null | undefined;
|
|
44
|
+
export type EntryExitVisitor<Info> = ((node: RNode<Info>) => void) | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Default implementation of a fold over the normalized AST (using the classic fold traversal).
|
|
47
|
+
* To modify the behavior, please extend this class and overwrite the methods of interest.
|
|
48
|
+
* You can control the value passing (`Returns` generic)
|
|
49
|
+
* by providing sensible Monoid behavior overwriting the {@link DefaultNormalizedAstFold#concat|concat} method
|
|
50
|
+
* and supplying the empty value in the constructor.
|
|
51
|
+
*
|
|
52
|
+
* @note By providing `entry` and `exit` you can use this as an extension to the simpler {@link visitAst} function but without
|
|
53
|
+
* the early termination within the visitors (for this, you can overwrite the respective `fold*` methods).
|
|
54
|
+
*
|
|
55
|
+
* @example First you want to create your own fold:
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* let marker = false;
|
|
59
|
+
* class MyNumberFold<Info> extends DefaultNormalizedAstFold<void, Info> {
|
|
60
|
+
* override foldRNumber(node: RNumber<Info>) {
|
|
61
|
+
* super.foldRNumber(node);
|
|
62
|
+
* marker = true;
|
|
63
|
+
* }
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
* This one does explicitly not use the return functionality (and hence acts more as a conventional visitor).
|
|
67
|
+
* Now let us suppose we have a normalized AST as an {@link RNode} in the variable `ast`
|
|
68
|
+
* and want to check if the AST contains a number:
|
|
69
|
+
*
|
|
70
|
+
* ```ts
|
|
71
|
+
* const result = new MyNumberFold().fold(ast);
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* Please take a look at the corresponding tests or the wiki pages for more information on how to use this fold.
|
|
75
|
+
*/
|
|
76
|
+
export declare class DefaultNormalizedAstFold<Returns = void, Info = NoInfo> implements NormalizedAstFold<Returns, Info> {
|
|
77
|
+
protected readonly enter: EntryExitVisitor<Info>;
|
|
78
|
+
protected readonly exit: EntryExitVisitor<Info>;
|
|
79
|
+
protected readonly empty: Returns;
|
|
80
|
+
/**
|
|
81
|
+
* Empty must provide a sensible default whenever you want to have `Returns` as non-`void`
|
|
82
|
+
* (e.g., whenever you want your visitors to be able to return a value).
|
|
83
|
+
*/
|
|
84
|
+
constructor(empty: Returns, enter?: EntryExitVisitor<Info>, exit?: EntryExitVisitor<Info>);
|
|
85
|
+
/**
|
|
86
|
+
* Monoid::concat
|
|
87
|
+
*
|
|
88
|
+
*
|
|
89
|
+
* @see {@link https://en.wikipedia.org/wiki/Monoid}
|
|
90
|
+
* @see {@link DefaultNormalizedAstFold#concatAll|concatAll}
|
|
91
|
+
*/
|
|
92
|
+
protected concat(_a: Returns, _b: Returns): Returns;
|
|
93
|
+
/**
|
|
94
|
+
* overwrite this method, if you have a faster way to concat multiple nodes
|
|
95
|
+
*
|
|
96
|
+
* @see {@link DefaultNormalizedAstFold#concatAll|concatAll}
|
|
97
|
+
*/
|
|
98
|
+
protected concatAll(nodes: readonly Returns[]): Returns;
|
|
99
|
+
fold(nodes: SingleOrArrayOrNothing<RNode<Info> | typeof EmptyArgument>): Returns;
|
|
100
|
+
protected foldSingle(node: RNode<Info>): Returns;
|
|
101
|
+
foldRAccess(access: RAccess<Info>): Returns;
|
|
102
|
+
foldRArgument(argument: RArgument<Info>): Returns;
|
|
103
|
+
foldRBinaryOp(binaryOp: RBinaryOp<Info>): Returns;
|
|
104
|
+
foldRExpressionList(exprList: RExpressionList<Info>): Returns;
|
|
105
|
+
foldRForLoop(loop: RForLoop<Info>): Returns;
|
|
106
|
+
foldRFunctionCall(call: RFunctionCall<Info>): Returns;
|
|
107
|
+
foldRFunctionDefinition(definition: RFunctionDefinition<Info>): Returns;
|
|
108
|
+
foldRIfThenElse(ite: RIfThenElse<Info>): Returns;
|
|
109
|
+
foldRParameter(parameter: RParameter<Info>): Returns;
|
|
110
|
+
foldRPipe(pipe: RPipe<Info>): Returns;
|
|
111
|
+
foldRRepeatLoop(loop: RRepeatLoop<Info>): Returns;
|
|
112
|
+
foldRUnaryOp(unaryOp: RUnaryOp<Info>): Returns;
|
|
113
|
+
foldRWhileLoop(loop: RWhileLoop<Info>): Returns;
|
|
114
|
+
foldRBreak(_node: RBreak<Info>): Returns;
|
|
115
|
+
foldRComment(_node: RComment<Info>): Returns;
|
|
116
|
+
foldRLineDirective(_node: RLineDirective<Info>): Returns;
|
|
117
|
+
foldRLogical(_node: RLogical<Info>): Returns;
|
|
118
|
+
foldRNext(_node: RNext<Info>): Returns;
|
|
119
|
+
foldRNumber(_node: RNumber<Info>): Returns;
|
|
120
|
+
foldRString(_node: RString<Info>): Returns;
|
|
121
|
+
foldRSymbol(_node: RSymbol<Info>): Returns;
|
|
122
|
+
protected readonly folds: FittingNormalizedAstFold<Returns, Info>;
|
|
123
|
+
}
|
|
124
|
+
export {};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DefaultNormalizedAstFold = void 0;
|
|
4
|
+
const r_function_call_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
5
|
+
const type_1 = require("../r-bridge/lang-4.x/ast/model/type");
|
|
6
|
+
/**
|
|
7
|
+
* Default implementation of a fold over the normalized AST (using the classic fold traversal).
|
|
8
|
+
* To modify the behavior, please extend this class and overwrite the methods of interest.
|
|
9
|
+
* You can control the value passing (`Returns` generic)
|
|
10
|
+
* by providing sensible Monoid behavior overwriting the {@link DefaultNormalizedAstFold#concat|concat} method
|
|
11
|
+
* and supplying the empty value in the constructor.
|
|
12
|
+
*
|
|
13
|
+
* @note By providing `entry` and `exit` you can use this as an extension to the simpler {@link visitAst} function but without
|
|
14
|
+
* the early termination within the visitors (for this, you can overwrite the respective `fold*` methods).
|
|
15
|
+
*
|
|
16
|
+
* @example First you want to create your own fold:
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* let marker = false;
|
|
20
|
+
* class MyNumberFold<Info> extends DefaultNormalizedAstFold<void, Info> {
|
|
21
|
+
* override foldRNumber(node: RNumber<Info>) {
|
|
22
|
+
* super.foldRNumber(node);
|
|
23
|
+
* marker = true;
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
* This one does explicitly not use the return functionality (and hence acts more as a conventional visitor).
|
|
28
|
+
* Now let us suppose we have a normalized AST as an {@link RNode} in the variable `ast`
|
|
29
|
+
* and want to check if the AST contains a number:
|
|
30
|
+
*
|
|
31
|
+
* ```ts
|
|
32
|
+
* const result = new MyNumberFold().fold(ast);
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* Please take a look at the corresponding tests or the wiki pages for more information on how to use this fold.
|
|
36
|
+
*/
|
|
37
|
+
class DefaultNormalizedAstFold {
|
|
38
|
+
enter;
|
|
39
|
+
exit;
|
|
40
|
+
empty;
|
|
41
|
+
/**
|
|
42
|
+
* Empty must provide a sensible default whenever you want to have `Returns` as non-`void`
|
|
43
|
+
* (e.g., whenever you want your visitors to be able to return a value).
|
|
44
|
+
*/
|
|
45
|
+
constructor(empty, enter, exit) {
|
|
46
|
+
this.empty = empty;
|
|
47
|
+
this.enter = enter;
|
|
48
|
+
this.exit = exit;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Monoid::concat
|
|
52
|
+
*
|
|
53
|
+
*
|
|
54
|
+
* @see {@link https://en.wikipedia.org/wiki/Monoid}
|
|
55
|
+
* @see {@link DefaultNormalizedAstFold#concatAll|concatAll}
|
|
56
|
+
*/
|
|
57
|
+
concat(_a, _b) {
|
|
58
|
+
return this.empty;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* overwrite this method, if you have a faster way to concat multiple nodes
|
|
62
|
+
*
|
|
63
|
+
* @see {@link DefaultNormalizedAstFold#concatAll|concatAll}
|
|
64
|
+
*/
|
|
65
|
+
concatAll(nodes) {
|
|
66
|
+
return nodes.reduce((acc, n) => this.concat(acc, n), this.empty);
|
|
67
|
+
}
|
|
68
|
+
fold(nodes) {
|
|
69
|
+
if (Array.isArray(nodes)) {
|
|
70
|
+
const n = nodes;
|
|
71
|
+
return this.concatAll(n.filter(n => n && n !== r_function_call_1.EmptyArgument).map(node => this.foldSingle(node)));
|
|
72
|
+
}
|
|
73
|
+
else if (nodes) {
|
|
74
|
+
return this.foldSingle(nodes);
|
|
75
|
+
}
|
|
76
|
+
return this.empty;
|
|
77
|
+
}
|
|
78
|
+
foldSingle(node) {
|
|
79
|
+
this.enter?.(node);
|
|
80
|
+
const type = node.type;
|
|
81
|
+
// @ts-expect-error -- ts may be unable to infer that the type is correct
|
|
82
|
+
const result = this.folds[type]?.(node);
|
|
83
|
+
this.exit?.(node);
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
foldRAccess(access) {
|
|
87
|
+
let accessed = this.foldSingle(access.accessed);
|
|
88
|
+
if (access.operator === '[' || access.operator === '[[') {
|
|
89
|
+
accessed = this.concat(accessed, this.fold(access.access));
|
|
90
|
+
}
|
|
91
|
+
return accessed;
|
|
92
|
+
}
|
|
93
|
+
foldRArgument(argument) {
|
|
94
|
+
return this.concat(this.fold(argument.name), this.fold(argument.value));
|
|
95
|
+
}
|
|
96
|
+
foldRBinaryOp(binaryOp) {
|
|
97
|
+
return this.concat(this.foldSingle(binaryOp.lhs), this.foldSingle(binaryOp.rhs));
|
|
98
|
+
}
|
|
99
|
+
foldRExpressionList(exprList) {
|
|
100
|
+
return this.concat(this.fold(exprList.grouping), this.fold(exprList.children));
|
|
101
|
+
}
|
|
102
|
+
foldRForLoop(loop) {
|
|
103
|
+
return this.concatAll([this.foldSingle(loop.variable), this.foldSingle(loop.vector), this.foldSingle(loop.body)]);
|
|
104
|
+
}
|
|
105
|
+
foldRFunctionCall(call) {
|
|
106
|
+
return this.concat(this.foldSingle(call.named ? call.functionName : call.calledFunction), this.fold(call.arguments));
|
|
107
|
+
}
|
|
108
|
+
foldRFunctionDefinition(definition) {
|
|
109
|
+
return this.concat(this.fold(definition.parameters), this.foldSingle(definition.body));
|
|
110
|
+
}
|
|
111
|
+
foldRIfThenElse(ite) {
|
|
112
|
+
return this.concatAll([this.foldSingle(ite.condition), this.foldSingle(ite.then), this.fold(ite.otherwise)]);
|
|
113
|
+
}
|
|
114
|
+
foldRParameter(parameter) {
|
|
115
|
+
return this.concat(this.foldSingle(parameter.name), this.fold(parameter.defaultValue));
|
|
116
|
+
}
|
|
117
|
+
foldRPipe(pipe) {
|
|
118
|
+
return this.concat(this.foldSingle(pipe.lhs), this.foldSingle(pipe.rhs));
|
|
119
|
+
}
|
|
120
|
+
foldRRepeatLoop(loop) {
|
|
121
|
+
return this.foldSingle(loop.body);
|
|
122
|
+
}
|
|
123
|
+
foldRUnaryOp(unaryOp) {
|
|
124
|
+
return this.foldSingle(unaryOp.operand);
|
|
125
|
+
}
|
|
126
|
+
foldRWhileLoop(loop) {
|
|
127
|
+
return this.concat(this.foldSingle(loop.condition), this.foldSingle(loop.body));
|
|
128
|
+
}
|
|
129
|
+
foldRBreak(_node) {
|
|
130
|
+
return this.empty;
|
|
131
|
+
}
|
|
132
|
+
foldRComment(_node) {
|
|
133
|
+
return this.empty;
|
|
134
|
+
}
|
|
135
|
+
foldRLineDirective(_node) {
|
|
136
|
+
return this.empty;
|
|
137
|
+
}
|
|
138
|
+
foldRLogical(_node) {
|
|
139
|
+
return this.empty;
|
|
140
|
+
}
|
|
141
|
+
foldRNext(_node) {
|
|
142
|
+
return this.empty;
|
|
143
|
+
}
|
|
144
|
+
foldRNumber(_node) {
|
|
145
|
+
return this.empty;
|
|
146
|
+
}
|
|
147
|
+
foldRString(_node) {
|
|
148
|
+
return this.empty;
|
|
149
|
+
}
|
|
150
|
+
foldRSymbol(_node) {
|
|
151
|
+
return this.empty;
|
|
152
|
+
}
|
|
153
|
+
folds = {
|
|
154
|
+
[type_1.RType.Access]: n => this.foldRAccess(n),
|
|
155
|
+
[type_1.RType.Argument]: n => this.foldRArgument(n),
|
|
156
|
+
[type_1.RType.BinaryOp]: n => this.foldRBinaryOp(n),
|
|
157
|
+
[type_1.RType.Break]: n => this.foldRBreak(n),
|
|
158
|
+
[type_1.RType.Comment]: n => this.foldRComment(n),
|
|
159
|
+
[type_1.RType.ExpressionList]: n => this.foldRExpressionList(n),
|
|
160
|
+
[type_1.RType.ForLoop]: n => this.foldRForLoop(n),
|
|
161
|
+
[type_1.RType.FunctionCall]: n => this.foldRFunctionCall(n),
|
|
162
|
+
[type_1.RType.FunctionDefinition]: n => this.foldRFunctionDefinition(n),
|
|
163
|
+
[type_1.RType.IfThenElse]: n => this.foldRIfThenElse(n),
|
|
164
|
+
[type_1.RType.LineDirective]: n => this.foldRLineDirective(n),
|
|
165
|
+
[type_1.RType.Logical]: n => this.foldRLogical(n),
|
|
166
|
+
[type_1.RType.Next]: n => this.foldRNext(n),
|
|
167
|
+
[type_1.RType.Number]: n => this.foldRNumber(n),
|
|
168
|
+
[type_1.RType.Parameter]: n => this.foldRParameter(n),
|
|
169
|
+
[type_1.RType.Pipe]: n => this.foldRPipe(n),
|
|
170
|
+
[type_1.RType.RepeatLoop]: n => this.foldRRepeatLoop(n),
|
|
171
|
+
[type_1.RType.String]: n => this.foldRString(n),
|
|
172
|
+
[type_1.RType.Symbol]: n => this.foldRSymbol(n),
|
|
173
|
+
[type_1.RType.UnaryOp]: n => this.foldRUnaryOp(n),
|
|
174
|
+
[type_1.RType.WhileLoop]: n => this.foldRWhileLoop(n),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
exports.DefaultNormalizedAstFold = DefaultNormalizedAstFold;
|
|
178
|
+
//# sourceMappingURL=normalized-ast-fold.js.map
|
|
@@ -42,6 +42,7 @@ const shell_1 = require("../../../r-bridge/shell");
|
|
|
42
42
|
const retriever_1 = require("../../../r-bridge/retriever");
|
|
43
43
|
const visitor_1 = require("../../../r-bridge/lang-4.x/ast/model/processing/visitor");
|
|
44
44
|
const type_1 = require("../../../r-bridge/lang-4.x/ast/model/type");
|
|
45
|
+
const arrays_1 = require("../../../util/arrays");
|
|
45
46
|
const tempfile = (() => {
|
|
46
47
|
let _tempfile = undefined;
|
|
47
48
|
return () => {
|
|
@@ -244,15 +245,15 @@ async function summarizeSlicerStats(stats, report = () => {
|
|
|
244
245
|
}
|
|
245
246
|
function summarizeSummarizedMeasurement(data) {
|
|
246
247
|
data = data.filter(assert_1.isNotUndefined);
|
|
247
|
-
const min = data.map(d => d.min).filter(assert_1.isNotUndefined)
|
|
248
|
-
const max = data.map(d => d.max).filter(assert_1.isNotUndefined)
|
|
248
|
+
const min = Math.min(...data.map(d => d.min).filter(assert_1.isNotUndefined));
|
|
249
|
+
const max = Math.max(...data.map(d => d.max).filter(assert_1.isNotUndefined));
|
|
249
250
|
// calculate median of medians (don't just average the median!)
|
|
250
251
|
const medians = data.map(d => d.median).filter(assert_1.isNotUndefined).sort((a, b) => a - b);
|
|
251
252
|
const median = medians[Math.floor(medians.length / 2)];
|
|
252
|
-
const mean = data.map(d => d.mean).filter(assert_1.isNotUndefined)
|
|
253
|
+
const mean = (0, arrays_1.arraySum)(data.map(d => d.mean).filter(assert_1.isNotUndefined)) / data.length;
|
|
253
254
|
// Method 1 of https://www.statology.org/averaging-standard-deviations/
|
|
254
|
-
const std = Math.sqrt(data.map(d => d.std ** 2).filter(assert_1.isNotUndefined)
|
|
255
|
-
const total = data.map(d => d.total).filter(assert_1.isNotUndefined)
|
|
255
|
+
const std = Math.sqrt((0, arrays_1.arraySum)(data.map(d => d.std ** 2).filter(assert_1.isNotUndefined)) / data.length);
|
|
256
|
+
const total = (0, arrays_1.arraySum)(data.map(d => d.total).filter(assert_1.isNotUndefined));
|
|
256
257
|
return { min, max, median, mean, std, total };
|
|
257
258
|
}
|
|
258
259
|
function summarizeSummarizedReductions(reductions) {
|
|
@@ -11,13 +11,16 @@ async function dataflow(shell, remainingLine) {
|
|
|
11
11
|
request: (0, retriever_1.requestFromInput)(remainingLine.trim())
|
|
12
12
|
}).allRemainingSteps();
|
|
13
13
|
}
|
|
14
|
+
function handleString(code) {
|
|
15
|
+
return code.startsWith('"') ? JSON.parse(code) : code;
|
|
16
|
+
}
|
|
14
17
|
exports.dataflowCommand = {
|
|
15
18
|
description: `Get mermaid code for the dataflow graph of R code, start with '${retriever_1.fileProtocol}' to indicate a file`,
|
|
16
19
|
usageExample: ':dataflow',
|
|
17
20
|
aliases: ['d', 'df'],
|
|
18
21
|
script: false,
|
|
19
22
|
fn: async (output, shell, remainingLine) => {
|
|
20
|
-
const result = await dataflow(shell, remainingLine);
|
|
23
|
+
const result = await dataflow(shell, handleString(remainingLine));
|
|
21
24
|
output.stdout((0, dfg_1.graphToMermaid)({ graph: result.dataflow.graph, includeEnvironments: false }).string);
|
|
22
25
|
}
|
|
23
26
|
};
|
|
@@ -27,7 +30,7 @@ exports.dataflowStarCommand = {
|
|
|
27
30
|
aliases: ['d*', 'df*'],
|
|
28
31
|
script: false,
|
|
29
32
|
fn: async (output, shell, remainingLine) => {
|
|
30
|
-
const result = await dataflow(shell, remainingLine);
|
|
33
|
+
const result = await dataflow(shell, handleString(remainingLine));
|
|
31
34
|
output.stdout((0, dfg_1.graphToMermaidUrl)(result.dataflow.graph, false));
|
|
32
35
|
}
|
|
33
36
|
};
|
|
@@ -11,13 +11,16 @@ async function normalize(shell, remainingLine) {
|
|
|
11
11
|
request: (0, retriever_1.requestFromInput)(remainingLine.trim())
|
|
12
12
|
}).allRemainingSteps();
|
|
13
13
|
}
|
|
14
|
+
function handleString(code) {
|
|
15
|
+
return code.startsWith('"') ? JSON.parse(code) : code;
|
|
16
|
+
}
|
|
14
17
|
exports.normalizeCommand = {
|
|
15
18
|
description: `Get mermaid code for the normalized AST of R code, start with '${retriever_1.fileProtocol}' to indicate a file`,
|
|
16
19
|
usageExample: ':normalize',
|
|
17
20
|
aliases: ['n'],
|
|
18
21
|
script: false,
|
|
19
22
|
fn: async (output, shell, remainingLine) => {
|
|
20
|
-
const result = await normalize(shell, remainingLine);
|
|
23
|
+
const result = await normalize(shell, handleString(remainingLine));
|
|
21
24
|
output.stdout((0, ast_1.normalizedAstToMermaid)(result.normalize.ast));
|
|
22
25
|
}
|
|
23
26
|
};
|
|
@@ -27,7 +30,7 @@ exports.normalizeStarCommand = {
|
|
|
27
30
|
aliases: ['n*'],
|
|
28
31
|
script: false,
|
|
29
32
|
fn: async (output, shell, remainingLine) => {
|
|
30
|
-
const result = await normalize(shell, remainingLine);
|
|
33
|
+
const result = await normalize(shell, handleString(remainingLine));
|
|
31
34
|
output.stdout((0, ast_1.normalizedAstToMermaidUrl)(result.normalize.ast));
|
|
32
35
|
}
|
|
33
36
|
};
|
|
@@ -19,7 +19,7 @@ async function getDataflow(shell, remainingLine) {
|
|
|
19
19
|
function printHelp(output) {
|
|
20
20
|
output.stderr(`Format: ${(0, ansi_1.italic)(':query "<query>" <code>', output.formatter)}`);
|
|
21
21
|
output.stdout('The query is an array of query objects to represent multiple queries. Each query object may have the following properties:');
|
|
22
|
-
output.stdout((0, schema_1.describeSchema)(query_1.AnyQuerySchema, output.formatter));
|
|
22
|
+
output.stdout((0, schema_1.describeSchema)((0, query_1.AnyQuerySchema)(), output.formatter));
|
|
23
23
|
output.stdout(`\n\nThe example ${(0, ansi_1.italic)(':query "[{\\"type\\": \\"call-context\\", \\"callName\\": \\"mean\\" }]" mean(1:10)', output.formatter)} would return the call context of the mean function.`);
|
|
24
24
|
output.stdout('As a convenience, we interpret any (non-help) string not starting with \'[\' as a regex for the simple call-context query.');
|
|
25
25
|
output.stdout(`Hence, ${(0, ansi_1.italic)(':query "mean" mean(1:10)', output.formatter)} is equivalent to the above example.`);
|
|
@@ -38,7 +38,7 @@ async function processQueryArgs(line, shell, output) {
|
|
|
38
38
|
let parsedQuery = [];
|
|
39
39
|
if (query.startsWith('[')) {
|
|
40
40
|
parsedQuery = JSON.parse(query);
|
|
41
|
-
const validationResult = query_1.QueriesSchema.validate(parsedQuery);
|
|
41
|
+
const validationResult = (0, query_1.QueriesSchema)().validate(parsedQuery);
|
|
42
42
|
if (validationResult.error) {
|
|
43
43
|
output.stderr(`Invalid query: ${validationResult.error.message}`);
|
|
44
44
|
printHelp(output);
|
|
@@ -12,7 +12,7 @@ exports.requestQueryMessage = {
|
|
|
12
12
|
type: joi_1.default.string().valid('request-query').required().description('The type of the message.'),
|
|
13
13
|
id: joi_1.default.string().optional().description('If you give the id, the response will be sent to the client with the same id.'),
|
|
14
14
|
filetoken: joi_1.default.string().required().description('The filetoken of the file/data retrieved from the analysis request.'),
|
|
15
|
-
query: query_1.QueriesSchema.required().description('The query to run on the file analysis information.')
|
|
15
|
+
query: (0, query_1.QueriesSchema)().required().description('The query to run on the file analysis information.')
|
|
16
16
|
}).description('Request a query to be run on the file analysis information.')
|
|
17
17
|
};
|
|
18
18
|
exports.responseQueryMessage = {
|
package/cli/slicer-app.js
CHANGED
|
@@ -29,7 +29,7 @@ async function getSlice() {
|
|
|
29
29
|
(0, assert_1.guard)(options.input !== undefined, 'input must be given');
|
|
30
30
|
(0, assert_1.guard)(options.criterion !== undefined, 'a slicing criterion must be given');
|
|
31
31
|
await slicer.init(options['input-is-text']
|
|
32
|
-
? { request: 'text', content: options.input }
|
|
32
|
+
? { request: 'text', content: options.input.replaceAll('\\n', '\n') }
|
|
33
33
|
: { request: 'file', content: options.input }, options['no-magic-comments'] ? auto_select_defaults_1.doNotAutoSelect : (0, magic_comments_1.makeMagicCommentHandler)(auto_select_defaults_1.doNotAutoSelect));
|
|
34
34
|
let mappedSlices = [];
|
|
35
35
|
let reconstruct = undefined;
|
|
@@ -22,6 +22,16 @@ export interface Pipeline<T extends IPipelineStep = IPipelineStep> {
|
|
|
22
22
|
* @see Pipeline for details
|
|
23
23
|
*/
|
|
24
24
|
export type PipelineStepNames<P extends Pipeline> = PipelineStep<P>['name'];
|
|
25
|
+
/**
|
|
26
|
+
* Returns the steps included in the given pipeline.
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* type Pipeline = typeof DEFAULT_DATAFLOW_PIPELINE
|
|
30
|
+
* // Pipeline is now Pipeline<step1 | step2 | ...>
|
|
31
|
+
* type Steps = PipelineStep<typeof DEFAULT_DATAFLOW_PIPELINE>
|
|
32
|
+
* // Steps is now just step1 | step2 | ...
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
25
35
|
export type PipelineStep<P extends Pipeline> = P extends Pipeline<infer U> ? U : never;
|
|
26
36
|
/**
|
|
27
37
|
* Meta-information attached to every step result
|
|
@@ -35,10 +45,51 @@ export interface PipelinePerStepMetaInformation {
|
|
|
35
45
|
readonly timing: number;
|
|
36
46
|
};
|
|
37
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Returns the step with the given name from the given pipeline.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* type Foo = PipelineStepWithName<typeof DEFAULT_DATAFLOW_PIPELINE, 'parse'>
|
|
54
|
+
* // Foo is now only the "parse" step from the DEFAULT_DATAFLOW_PIPELINE
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
38
57
|
export type PipelineStepWithName<P extends Pipeline, Name extends PipelineStepName> = P extends Pipeline<infer U> ? U extends IPipelineStep<Name> ? U : never : never;
|
|
58
|
+
/**
|
|
59
|
+
* Returns the processor function of the step with the given name from the given pipeline.
|
|
60
|
+
* @see {@link PipelineStepWithName}
|
|
61
|
+
*/
|
|
39
62
|
export type PipelineStepProcessorWithName<P extends Pipeline, Name extends PipelineStepName> = PipelineStepWithName<P, Name>['processor'];
|
|
63
|
+
/**
|
|
64
|
+
* Returns the printer function of the step with the given name from the given pipeline.
|
|
65
|
+
* @see {@link PipelineStepWithName}
|
|
66
|
+
*/
|
|
40
67
|
export type PipelineStepPrintersWithName<P extends Pipeline, Name extends PipelineStepName> = PipelineStepWithName<P, Name>['printer'];
|
|
68
|
+
/**
|
|
69
|
+
* Returns the output type of the step with the given name from the given pipeline.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* type Foo = PipelineStepOutputWithName<typeof DEFAULT_DATAFLOW_PIPELINE, 'parse'>
|
|
74
|
+
* // Foo contains the ParseStepOutput & PipelinePerStepMetaInformation type (ie the parse output and meta information)
|
|
75
|
+
* @see {@link PipelineStepWithName}
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
41
78
|
export type PipelineStepOutputWithName<P extends Pipeline, Name extends PipelineStepName> = Awaited<ReturnType<PipelineStepProcessorWithName<P, Name>>> & PipelinePerStepMetaInformation;
|
|
79
|
+
/**
|
|
80
|
+
* Returns a union type that represents the required inputs to be passed to the given pipeline.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* type Foo = PipelineInput<typeof DEFAULT_DATAFLOW_PIPELINE>
|
|
85
|
+
* // Foo contains ParseRequiredInput & NormalizeRequiredInput
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* In short, this can be useful whenever you want to describe _all_ inputs a complete
|
|
89
|
+
* pipeline needs to run through (i.e., the union of all inputs required by the individual steps).
|
|
90
|
+
*
|
|
91
|
+
* @see {@link PipelineOutput}
|
|
92
|
+
*/
|
|
42
93
|
export type PipelineInput<P extends Pipeline> = UnionToIntersection<PipelineStep<P>['requiredInput']>;
|
|
43
94
|
/**
|
|
44
95
|
* Only gets the union of 'requiredInput' of those PipelineSteps which have a 'execute' field of type 'OncePerRequest'.
|
|
@@ -47,6 +98,18 @@ export type PipelineInput<P extends Pipeline> = UnionToIntersection<PipelineStep
|
|
|
47
98
|
export type PipelinePerRequestInput<P extends Pipeline> = {
|
|
48
99
|
[K in PipelineStepNames<P>]: PipelineStepWithName<P, K>['executed'] extends PipelineStepStage.OncePerFile ? never : PipelineStepWithName<P, K>['requiredInput'];
|
|
49
100
|
}[PipelineStepNames<P>];
|
|
101
|
+
/**
|
|
102
|
+
* Returns an object type that represents the types of the outputs that will result from running the given pipeline, each as the step's name mapped to its PipelineStepOutputWithName.
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* type Foo = PipelineOutput<typeof DEFAULT_DATAFLOW_PIPELINE>
|
|
106
|
+
* // Foo contains {
|
|
107
|
+
* // parse: ParseStepOutput & PipelinePerStepMetaInformation,
|
|
108
|
+
* // normalize: NormalizeStepOutput & PipelinePerStepMetaInformation,
|
|
109
|
+
* // ...
|
|
110
|
+
* // }
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
50
113
|
export type PipelineOutput<P extends Pipeline> = {
|
|
51
114
|
[K in PipelineStepNames<P>]: PipelineStepOutputWithName<P, K>;
|
|
52
115
|
};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DefaultBuiltinConfig = void 0;
|
|
4
|
+
const identify_link_to_last_call_relation_1 = require("../../queries/catalog/call-context-query/identify-link-to-last-call-relation");
|
|
5
|
+
const type_1 = require("../../r-bridge/lang-4.x/ast/model/type");
|
|
6
|
+
const cascade_action_1 = require("../../queries/catalog/call-context-query/cascade-action");
|
|
4
7
|
/**
|
|
5
8
|
* Contains the built-in definitions recognized by flowR
|
|
6
9
|
*/
|
|
@@ -40,10 +43,45 @@ exports.DefaultBuiltinConfig = [
|
|
|
40
43
|
{ type: 'function', names: ['print', 'message', 'warning'], processor: 'builtin:default', config: { returnsNthArgument: 0, forceArgs: 'all', hasUnknownSideEffects: { type: 'link-to-last-call', callName: /^sink$/ } }, assumePrimitive: false },
|
|
41
44
|
// graphics base
|
|
42
45
|
{ type: 'function', names: ['plot', 'plot.new', 'curve', 'map', 'image', 'boxplot', 'dotchart', 'sunflowerplot', 'barplot', 'matplot', 'hist', 'stem', 'density', 'smoothScatter', 'contour', 'persp'],
|
|
43
|
-
processor: 'builtin:default',
|
|
46
|
+
processor: 'builtin:default',
|
|
47
|
+
config: {
|
|
48
|
+
forceArgs: 'all',
|
|
49
|
+
hasUnknownSideEffects: {
|
|
50
|
+
type: 'link-to-last-call',
|
|
51
|
+
ignoreIf: (source, graph) => {
|
|
52
|
+
/* map with add = true appends to an existing plot */
|
|
53
|
+
return (source.name === 'map' && (0, identify_link_to_last_call_relation_1.getValueOfArgument)(graph, source, {
|
|
54
|
+
index: 11,
|
|
55
|
+
name: 'add'
|
|
56
|
+
}, [type_1.RType.Logical])?.content === true);
|
|
57
|
+
},
|
|
58
|
+
callName: /^(pdf|jpeg|png|windows|postscript|xfig|bitmap|pictex|cairo_pdf|svg|bmp|tiff|X11|quartz)$/
|
|
59
|
+
}
|
|
60
|
+
}, assumePrimitive: true },
|
|
44
61
|
// graphics addons
|
|
45
|
-
{ type: 'function', names: ['points', 'abline', 'mtext', 'lines', 'text', 'legend', 'title', 'axis', 'polygon', 'polypath', 'pie', 'rect', 'segments', 'arrows', 'symbols', 'tiplabels'],
|
|
46
|
-
processor: 'builtin:default', config: {
|
|
62
|
+
{ type: 'function', names: ['points', 'abline', 'map', 'mtext', 'lines', 'text', 'legend', 'title', 'axis', 'polygon', 'polypath', 'pie', 'rect', 'segments', 'arrows', 'symbols', 'tiplabels'],
|
|
63
|
+
processor: 'builtin:default', config: {
|
|
64
|
+
forceArgs: 'all',
|
|
65
|
+
hasUnknownSideEffects: {
|
|
66
|
+
type: 'link-to-last-call',
|
|
67
|
+
callName: /^(dev\.new|dev\.copy|plot\.new|xspline|sunflowerplot|dotchart|plot|map|image|curve|boxplot|barplot|matplot|hist|stem|density|smoothScatter|contour|persp)$/,
|
|
68
|
+
ignoreIf: (source, graph) => {
|
|
69
|
+
const sourceVertex = graph.getVertex(source);
|
|
70
|
+
/* map with add = true appends to an existing plot */
|
|
71
|
+
return (sourceVertex?.name === 'map' && (0, identify_link_to_last_call_relation_1.getValueOfArgument)(graph, sourceVertex, {
|
|
72
|
+
index: 11,
|
|
73
|
+
name: 'add'
|
|
74
|
+
}, [type_1.RType.Logical])?.content !== true);
|
|
75
|
+
},
|
|
76
|
+
cascadeIf: (target, _, graph) => {
|
|
77
|
+
/* map with add = true appends to an existing plot */
|
|
78
|
+
return target.name === 'map' ? ((0, identify_link_to_last_call_relation_1.getValueOfArgument)(graph, target, {
|
|
79
|
+
index: 11,
|
|
80
|
+
name: 'add'
|
|
81
|
+
}, [type_1.RType.Logical])?.content === true ? cascade_action_1.CascadeAction.Continue : cascade_action_1.CascadeAction.Stop) : cascade_action_1.CascadeAction.Stop;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}, assumePrimitive: true },
|
|
47
85
|
{ type: 'function', names: ['('], processor: 'builtin:default', config: { returnsNthArgument: 0 }, assumePrimitive: true },
|
|
48
86
|
{ type: 'function', names: ['load', 'load_all', 'setwd', 'set.seed'], processor: 'builtin:default', config: { hasUnknownSideEffects: true, forceArgs: [true] }, assumePrimitive: false },
|
|
49
87
|
{ type: 'function', names: ['eval', 'body', 'formals', 'environment'], processor: 'builtin:default', config: { hasUnknownSideEffects: true, forceArgs: [true] }, assumePrimitive: false },
|
|
@@ -60,8 +98,9 @@ exports.DefaultBuiltinConfig = [
|
|
|
60
98
|
{ type: 'function', names: ['get'], processor: 'builtin:get', config: {}, assumePrimitive: false },
|
|
61
99
|
{ type: 'function', names: ['library', 'require'], processor: 'builtin:library', config: {}, assumePrimitive: false },
|
|
62
100
|
{ type: 'function', names: ['<-', '='], processor: 'builtin:assignment', config: { canBeReplacement: true }, assumePrimitive: true },
|
|
63
|
-
{ type: 'function', names: [':='
|
|
64
|
-
{ type: 'function', names: ['
|
|
101
|
+
{ type: 'function', names: [':='], processor: 'builtin:assignment', config: {}, assumePrimitive: true },
|
|
102
|
+
{ type: 'function', names: ['assign'], processor: 'builtin:assignment', config: { targetVariable: true }, assumePrimitive: true },
|
|
103
|
+
{ type: 'function', names: ['delayedAssign'], processor: 'builtin:assignment', config: { quoteSource: true, targetVariable: true }, assumePrimitive: true },
|
|
65
104
|
{ type: 'function', names: ['<<-'], processor: 'builtin:assignment', config: { superAssignment: true, canBeReplacement: true }, assumePrimitive: true },
|
|
66
105
|
{ type: 'function', names: ['->'], processor: 'builtin:assignment', config: { swapSourceAndTarget: true, canBeReplacement: true }, assumePrimitive: true },
|
|
67
106
|
{ type: 'function', names: ['->>'], processor: 'builtin:assignment', config: { superAssignment: true, swapSourceAndTarget: true, canBeReplacement: true }, assumePrimitive: true },
|
|
@@ -83,7 +122,7 @@ exports.DefaultBuiltinConfig = [
|
|
|
83
122
|
/* downloader and installer functions (R, devtools, BiocManager) */
|
|
84
123
|
'library.dynam', 'install.packages', 'install', 'install_github', 'install_gitlab', 'install_bitbucket', 'install_url', 'install_git', 'install_svn', 'install_local', 'install_version', 'update_packages',
|
|
85
124
|
/* weird env attachments */
|
|
86
|
-
'attach', '
|
|
125
|
+
'attach', 'unname', 'data'
|
|
87
126
|
],
|
|
88
127
|
processor: 'builtin:default',
|
|
89
128
|
config: { hasUnknownSideEffects: true },
|