@eagleoutice/flowr 2.2.13 → 2.2.15
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 +4 -4
- package/cli/repl/commands/repl-cfg.d.ts +2 -2
- package/cli/repl/commands/repl-cfg.js +4 -4
- package/cli/repl/commands/repl-commands.js +3 -3
- package/cli/repl/commands/repl-execute.js +2 -1
- package/cli/repl/server/connection.js +1 -1
- package/cli/script-core/statistics-helper-core.js +1 -1
- package/config.js +1 -1
- package/control-flow/basic-cfg-guided-visitor.d.ts +3 -3
- package/control-flow/cfg-dead-code.d.ts +4 -0
- package/control-flow/cfg-dead-code.js +81 -0
- package/control-flow/cfg-simplification.d.ts +17 -6
- package/control-flow/cfg-simplification.js +23 -19
- package/control-flow/control-flow-graph.d.ts +2 -1
- package/control-flow/control-flow-graph.js +1 -0
- package/control-flow/dfg-cfg-guided-visitor.d.ts +4 -4
- package/control-flow/dfg-cfg-guided-visitor.js +1 -1
- package/control-flow/extract-cfg.d.ts +2 -2
- package/control-flow/extract-cfg.js +70 -67
- package/control-flow/semantic-cfg-guided-visitor.d.ts +17 -8
- package/control-flow/semantic-cfg-guided-visitor.js +50 -17
- package/control-flow/simple-visitor.d.ts +4 -0
- package/control-flow/simple-visitor.js +14 -0
- package/control-flow/syntax-cfg-guided-visitor.d.ts +2 -2
- package/dataflow/environments/built-in-config.d.ts +1 -0
- package/dataflow/environments/built-in.d.ts +10 -1
- package/dataflow/environments/built-in.js +9 -3
- package/dataflow/environments/default-builtin-config.js +1 -1
- package/dataflow/environments/resolve-by-name.d.ts +0 -36
- package/dataflow/environments/resolve-by-name.js +0 -240
- package/dataflow/eval/resolve/alias-tracking.d.ts +87 -0
- package/dataflow/eval/resolve/alias-tracking.js +349 -0
- package/dataflow/eval/resolve/resolve.d.ts +34 -0
- package/dataflow/eval/resolve/resolve.js +93 -0
- package/dataflow/eval/values/general.d.ts +27 -0
- package/dataflow/eval/values/general.js +73 -0
- package/dataflow/eval/values/intervals/interval-constants.d.ts +4 -0
- package/dataflow/eval/values/intervals/interval-constants.js +27 -0
- package/dataflow/eval/values/logical/logical-constants.d.ts +7 -0
- package/dataflow/eval/values/logical/logical-constants.js +31 -0
- package/dataflow/eval/values/r-value.d.ts +58 -0
- package/dataflow/eval/values/r-value.js +90 -0
- package/dataflow/eval/values/scalar/scalar-consatnts.d.ts +15 -0
- package/dataflow/eval/values/scalar/scalar-consatnts.js +35 -0
- package/dataflow/eval/values/sets/set-constants.d.ts +7 -0
- package/dataflow/eval/values/sets/set-constants.js +34 -0
- package/dataflow/eval/values/string/string-constants.d.ts +8 -0
- package/dataflow/eval/values/string/string-constants.js +40 -0
- package/dataflow/eval/values/vectors/vector-constants.d.ts +14 -0
- package/dataflow/eval/values/vectors/vector-constants.js +35 -0
- package/dataflow/graph/unknown-replacement.d.ts +11 -0
- package/dataflow/graph/unknown-replacement.js +12 -0
- package/dataflow/graph/unknown-side-effect.d.ts +7 -0
- package/dataflow/graph/unknown-side-effect.js +13 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +8 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +4 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +12 -9
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +5 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +9 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +12 -15
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +23 -0
- package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
- package/documentation/doc-util/doc-cfg.d.ts +1 -1
- package/documentation/doc-util/doc-cfg.js +3 -3
- package/documentation/doc-util/doc-query.d.ts +6 -3
- package/documentation/doc-util/doc-query.js +3 -1
- package/documentation/print-cfg-wiki.js +31 -31
- package/documentation/print-dataflow-graph-wiki.js +4 -3
- package/documentation/print-engines-wiki.js +1 -1
- package/documentation/print-linter-wiki.d.ts +1 -0
- package/documentation/print-linter-wiki.js +76 -0
- package/documentation/print-query-wiki.js +80 -0
- package/linter/linter-executor.d.ts +9 -0
- package/linter/linter-executor.js +26 -0
- package/linter/linter-format.d.ts +65 -0
- package/linter/linter-format.js +9 -0
- package/linter/linter-rules.d.ts +42 -0
- package/linter/linter-rules.js +14 -0
- package/linter/rules/1-deprecated-functions.d.ts +34 -0
- package/linter/rules/1-deprecated-functions.js +54 -0
- package/linter/rules/2-file-path-validity.d.ts +48 -0
- package/linter/rules/2-file-path-validity.js +93 -0
- package/package.json +2 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +1 -1
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +2 -2
- package/queries/catalog/call-context-query/call-context-query-format.js +5 -1
- package/queries/catalog/cluster-query/cluster-query-format.d.ts +2 -0
- package/queries/catalog/cluster-query/cluster-query-format.js +5 -1
- package/queries/catalog/config-query/config-query-format.d.ts +1 -0
- package/queries/catalog/config-query/config-query-format.js +2 -1
- package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +3 -0
- package/queries/catalog/control-flow-query/control-flow-query-executor.js +20 -0
- package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +81 -0
- package/queries/catalog/control-flow-query/control-flow-query-format.js +34 -0
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -0
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +2 -1
- package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +2 -0
- package/queries/catalog/dataflow-query/dataflow-query-format.js +9 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +33 -32
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -0
- package/queries/catalog/dependencies-query/dependencies-query-format.js +10 -1
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -0
- package/queries/catalog/happens-before-query/happens-before-query-format.js +2 -1
- package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -0
- package/queries/catalog/id-map-query/id-map-query-format.js +2 -1
- package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -0
- package/queries/catalog/lineage-query/lineage-query-format.js +5 -1
- package/queries/catalog/linter-query/linter-query-executor.d.ts +3 -0
- package/queries/catalog/linter-query/linter-query-executor.js +28 -0
- package/queries/catalog/linter-query/linter-query-format.d.ts +80 -0
- package/queries/catalog/linter-query/linter-query-format.js +44 -0
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +1 -0
- package/queries/catalog/location-map-query/location-map-query-format.js +2 -1
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -0
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +2 -1
- package/queries/catalog/origin-query/origin-query-format.d.ts +2 -0
- package/queries/catalog/origin-query/origin-query-format.js +5 -1
- package/queries/catalog/project-query/project-query-executor.js +1 -1
- package/queries/catalog/project-query/project-query-format.d.ts +1 -0
- package/queries/catalog/project-query/project-query-format.js +2 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +3 -3
- package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +3 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-format.js +4 -23
- package/queries/catalog/search-query/search-query-format.d.ts +1 -0
- package/queries/catalog/search-query/search-query-format.js +5 -1
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +2 -0
- package/queries/catalog/static-slice-query/static-slice-query-format.js +9 -1
- package/queries/query.d.ts +143 -1
- package/queries/query.js +4 -0
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +11 -4
- package/r-bridge/retriever.js +1 -1
- package/search/flowr-search-builder.d.ts +31 -2
- package/search/flowr-search-builder.js +30 -0
- package/search/flowr-search.d.ts +7 -1
- package/search/search-executor/search-enrichers.d.ts +73 -0
- package/search/search-executor/search-enrichers.js +101 -0
- package/search/search-executor/search-generators.d.ts +6 -1
- package/search/search-executor/search-generators.js +21 -1
- package/search/search-executor/search-mappers.d.ts +19 -0
- package/search/search-executor/search-mappers.js +21 -0
- package/search/search-executor/search-transformer.d.ts +12 -0
- package/search/search-executor/search-transformer.js +11 -1
- package/slicing/criterion/parse.d.ts +8 -0
- package/slicing/criterion/parse.js +20 -0
- package/util/version.js +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ResolvedCallSuffix = void 0;
|
|
4
|
-
exports.
|
|
4
|
+
exports.extractCfg = extractCfg;
|
|
5
5
|
exports.extractSimpleCfg = extractSimpleCfg;
|
|
6
6
|
exports.cfg2quads = cfg2quads;
|
|
7
7
|
const quads_1 = require("../util/quads");
|
|
@@ -62,20 +62,18 @@ function dataflowCfgFolds(dataflowGraph) {
|
|
|
62
62
|
*
|
|
63
63
|
* @see {@link extractSimpleCfg} - for a simplified version of this function
|
|
64
64
|
*/
|
|
65
|
-
function
|
|
66
|
-
return (0, cfg_simplification_1.simplifyControlFlowInformation)((0, fold_1.foldAst)(ast.ast, graph ? dataflowCfgFolds(graph) : cfgFolds), simplifications);
|
|
65
|
+
function extractCfg(ast, graph, simplifications) {
|
|
66
|
+
return (0, cfg_simplification_1.simplifyControlFlowInformation)((0, fold_1.foldAst)(ast.ast, graph ? dataflowCfgFolds(graph) : cfgFolds), { ast, dfg: graph }, simplifications);
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
|
-
* Simplified version of {@link
|
|
69
|
+
* Simplified version of {@link extractCfg} that is much quicker, but much simpler!
|
|
70
70
|
*/
|
|
71
71
|
function extractSimpleCfg(ast) {
|
|
72
72
|
return (0, fold_1.foldAst)(ast.ast, cfgFolds);
|
|
73
73
|
}
|
|
74
74
|
function cfgLeaf(type) {
|
|
75
|
-
return (
|
|
76
|
-
|
|
77
|
-
graph.addVertex({ id: leaf.info.id, type });
|
|
78
|
-
return { graph, breaks: [], nexts: [], returns: [], exitPoints: [leaf.info.id], entryPoints: [leaf.info.id] };
|
|
75
|
+
return ({ info: { id } }) => {
|
|
76
|
+
return { graph: new control_flow_graph_1.ControlFlowGraph().addVertex({ id, type }), breaks: [], nexts: [], returns: [], exitPoints: [id], entryPoints: [id] };
|
|
79
77
|
};
|
|
80
78
|
}
|
|
81
79
|
function cfgBreak(leaf) {
|
|
@@ -91,40 +89,41 @@ function identifyMayStatementType(node) {
|
|
|
91
89
|
return node.info.role === "expr-list-child" /* RoleInParent.ExpressionListChild */ ? control_flow_graph_1.CfgVertexType.Statement : control_flow_graph_1.CfgVertexType.Expression;
|
|
92
90
|
}
|
|
93
91
|
function cfgIfThenElse(ifNode, condition, then, otherwise) {
|
|
92
|
+
const ifId = ifNode.info.id;
|
|
94
93
|
const graph = new control_flow_graph_1.ControlFlowGraph();
|
|
95
|
-
graph.addVertex({ id:
|
|
96
|
-
graph.addVertex({ id:
|
|
97
|
-
graph.addVertex({ id:
|
|
94
|
+
graph.addVertex({ id: ifId, type: identifyMayStatementType(ifNode), mid: [ifId + '-condition'], end: [ifId + '-exit'] });
|
|
95
|
+
graph.addVertex({ id: ifId + '-condition', kind: 'condition', type: control_flow_graph_1.CfgVertexType.MidMarker, root: ifId });
|
|
96
|
+
graph.addVertex({ id: ifId + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: ifId });
|
|
98
97
|
graph.mergeWith(condition.graph);
|
|
99
98
|
graph.mergeWith(then.graph);
|
|
100
99
|
if (otherwise) {
|
|
101
100
|
graph.mergeWith(otherwise.graph);
|
|
102
101
|
}
|
|
103
102
|
for (const exitPoint of condition.exitPoints) {
|
|
104
|
-
graph.addEdge(
|
|
103
|
+
graph.addEdge(ifId + '-condition', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
|
|
105
104
|
}
|
|
106
105
|
for (const entryPoint of then.entryPoints) {
|
|
107
|
-
graph.addEdge(entryPoint,
|
|
106
|
+
graph.addEdge(entryPoint, ifId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: ifId });
|
|
108
107
|
}
|
|
109
108
|
for (const entryPoint of otherwise?.entryPoints ?? []) {
|
|
110
|
-
graph.addEdge(entryPoint,
|
|
109
|
+
graph.addEdge(entryPoint, ifId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: ifId });
|
|
111
110
|
}
|
|
112
111
|
for (const entryPoint of condition.entryPoints) {
|
|
113
|
-
graph.addEdge(entryPoint,
|
|
112
|
+
graph.addEdge(entryPoint, ifId, { label: 0 /* CfgEdgeType.Fd */ });
|
|
114
113
|
}
|
|
115
114
|
for (const exit of [...then.exitPoints, ...otherwise?.exitPoints ?? []]) {
|
|
116
|
-
graph.addEdge(
|
|
115
|
+
graph.addEdge(ifId + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
|
|
117
116
|
}
|
|
118
117
|
if (!otherwise) {
|
|
119
|
-
graph.addEdge(
|
|
118
|
+
graph.addEdge(ifId + '-exit', ifId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: ifId });
|
|
120
119
|
}
|
|
121
120
|
return {
|
|
122
121
|
graph,
|
|
123
122
|
breaks: [...then.breaks, ...otherwise?.breaks ?? []],
|
|
124
123
|
nexts: [...then.nexts, ...otherwise?.nexts ?? []],
|
|
125
124
|
returns: [...then.returns, ...otherwise?.returns ?? []],
|
|
126
|
-
exitPoints: [
|
|
127
|
-
entryPoints: [
|
|
125
|
+
exitPoints: [ifId + '-exit'],
|
|
126
|
+
entryPoints: [ifId]
|
|
128
127
|
};
|
|
129
128
|
}
|
|
130
129
|
function cfgRepeat(repeat, body) {
|
|
@@ -144,110 +143,114 @@ function cfgRepeat(repeat, body) {
|
|
|
144
143
|
return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: [repeat.info.id + '-exit'], entryPoints: [repeat.info.id] };
|
|
145
144
|
}
|
|
146
145
|
function cfgWhile(whileLoop, condition, body) {
|
|
146
|
+
const whileId = whileLoop.info.id;
|
|
147
147
|
const graph = condition.graph;
|
|
148
|
-
graph.addVertex({ id:
|
|
149
|
-
graph.addVertex({ id:
|
|
150
|
-
graph.addVertex({ id:
|
|
148
|
+
graph.addVertex({ id: whileId, type: identifyMayStatementType(whileLoop), mid: [whileId + '-condition'], end: [whileId + '-exit'] });
|
|
149
|
+
graph.addVertex({ id: whileId + '-condition', kind: 'condition', type: control_flow_graph_1.CfgVertexType.MidMarker, root: whileId });
|
|
150
|
+
graph.addVertex({ id: whileId + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: whileId });
|
|
151
151
|
graph.mergeWith(body.graph);
|
|
152
152
|
for (const entry of condition.entryPoints) {
|
|
153
|
-
graph.addEdge(entry,
|
|
153
|
+
graph.addEdge(entry, whileId, { label: 0 /* CfgEdgeType.Fd */ });
|
|
154
154
|
}
|
|
155
155
|
for (const exit of condition.exitPoints) {
|
|
156
|
-
graph.addEdge(
|
|
156
|
+
graph.addEdge(whileId + '-condition', exit, { label: 0 /* CfgEdgeType.Fd */ });
|
|
157
157
|
}
|
|
158
158
|
for (const entry of body.entryPoints) {
|
|
159
|
-
graph.addEdge(entry,
|
|
159
|
+
graph.addEdge(entry, whileId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: whileId });
|
|
160
160
|
}
|
|
161
161
|
for (const next of [...body.nexts, ...body.exitPoints]) {
|
|
162
|
-
graph.addEdge(
|
|
162
|
+
graph.addEdge(whileId, next, { label: 0 /* CfgEdgeType.Fd */ });
|
|
163
163
|
}
|
|
164
164
|
for (const breakPoint of body.breaks) {
|
|
165
|
-
graph.addEdge(
|
|
165
|
+
graph.addEdge(whileId + '-exit', breakPoint, { label: 0 /* CfgEdgeType.Fd */ });
|
|
166
166
|
}
|
|
167
167
|
// while can break on the condition as well
|
|
168
|
-
graph.addEdge(
|
|
169
|
-
return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: [
|
|
168
|
+
graph.addEdge(whileId + '-exit', whileId + '-condition', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: whileId });
|
|
169
|
+
return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: [whileId + '-exit'], entryPoints: [whileId] };
|
|
170
170
|
}
|
|
171
171
|
function cfgFor(forLoop, variable, vector, body) {
|
|
172
|
+
const forLoopId = forLoop.info.id;
|
|
172
173
|
const graph = variable.graph;
|
|
173
|
-
graph.addVertex({ id:
|
|
174
|
+
graph.addVertex({ id: forLoopId, type: identifyMayStatementType(forLoop), end: [forLoopId + '-exit'], mid: [forLoopId + '-head'] });
|
|
174
175
|
graph.mergeWith(vector.graph);
|
|
175
176
|
graph.mergeWith(body.graph);
|
|
176
177
|
for (const entry of vector.entryPoints) {
|
|
177
|
-
graph.addEdge(entry,
|
|
178
|
+
graph.addEdge(entry, forLoopId, { label: 0 /* CfgEdgeType.Fd */ });
|
|
178
179
|
}
|
|
179
180
|
for (const exit of vector.exitPoints) {
|
|
180
181
|
for (const entry of variable.entryPoints) {
|
|
181
182
|
graph.addEdge(entry, exit, { label: 0 /* CfgEdgeType.Fd */ });
|
|
182
183
|
}
|
|
183
184
|
}
|
|
184
|
-
graph.addVertex({ id:
|
|
185
|
+
graph.addVertex({ id: forLoopId + '-head', type: control_flow_graph_1.CfgVertexType.MidMarker, root: forLoopId, kind: 'head' });
|
|
185
186
|
for (const exit of variable.exitPoints) {
|
|
186
|
-
graph.addEdge(
|
|
187
|
+
graph.addEdge(forLoopId + '-head', exit, { label: 0 /* CfgEdgeType.Fd */ });
|
|
187
188
|
}
|
|
188
189
|
for (const entry of body.entryPoints) {
|
|
189
|
-
graph.addEdge(entry,
|
|
190
|
+
graph.addEdge(entry, forLoopId + '-head', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RTrue, caused: forLoopId });
|
|
190
191
|
}
|
|
191
192
|
for (const next of [...body.nexts, ...body.exitPoints]) {
|
|
192
|
-
graph.addEdge(
|
|
193
|
+
graph.addEdge(forLoopId, next, { label: 0 /* CfgEdgeType.Fd */ });
|
|
193
194
|
}
|
|
194
195
|
for (const breakPoint of body.breaks) {
|
|
195
|
-
graph.addEdge(
|
|
196
|
+
graph.addEdge(forLoopId + '-exit', breakPoint, { label: 0 /* CfgEdgeType.Fd */ });
|
|
196
197
|
}
|
|
197
198
|
const isNotEndless = body.exitPoints.length > 0 || body.breaks.length > 0;
|
|
198
199
|
if (isNotEndless) {
|
|
199
200
|
graph.addVertex({
|
|
200
|
-
id:
|
|
201
|
+
id: forLoopId + '-exit',
|
|
201
202
|
type: control_flow_graph_1.CfgVertexType.EndMarker,
|
|
202
|
-
root:
|
|
203
|
+
root: forLoopId
|
|
203
204
|
});
|
|
204
|
-
graph.addEdge(
|
|
205
|
+
graph.addEdge(forLoopId + '-exit', forLoopId + '-head', { label: 1 /* CfgEdgeType.Cd */, when: convert_values_1.RFalse, caused: forLoopId });
|
|
205
206
|
}
|
|
206
|
-
return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: isNotEndless ? [
|
|
207
|
+
return { graph, breaks: [], nexts: [], returns: body.returns, exitPoints: isNotEndless ? [forLoopId + '-exit'] : [], entryPoints: [forLoopId] };
|
|
207
208
|
}
|
|
208
209
|
function cfgFunctionDefinition(fn, params, body) {
|
|
210
|
+
const fnId = fn.info.id;
|
|
209
211
|
const graph = new control_flow_graph_1.ControlFlowGraph();
|
|
210
|
-
const children = [
|
|
211
|
-
graph.addVertex({ id:
|
|
212
|
-
graph.addVertex({ id:
|
|
213
|
-
graph.addVertex({ id:
|
|
212
|
+
const children = [fnId + '-params', fnId + '-exit'];
|
|
213
|
+
graph.addVertex({ id: fnId + '-params', kind: 'parameters', type: control_flow_graph_1.CfgVertexType.MidMarker, root: fnId }, false);
|
|
214
|
+
graph.addVertex({ id: fnId + '-exit', type: control_flow_graph_1.CfgVertexType.EndMarker, root: fnId }, false);
|
|
215
|
+
graph.addVertex({ id: fnId, children, type: identifyMayStatementType(fn), mid: [fnId + '-params'], end: [fnId + '-exit'] });
|
|
214
216
|
graph.mergeWith(body.graph, true);
|
|
215
217
|
children.push(...body.graph.rootIds());
|
|
216
218
|
for (const param of params) {
|
|
217
219
|
graph.mergeWith(param.graph, true);
|
|
218
220
|
children.push(...param.graph.rootIds());
|
|
219
221
|
for (const entry of param.entryPoints) {
|
|
220
|
-
graph.addEdge(entry,
|
|
222
|
+
graph.addEdge(entry, fnId, { label: 0 /* CfgEdgeType.Fd */ });
|
|
221
223
|
}
|
|
222
224
|
for (const exit of param.exitPoints) {
|
|
223
|
-
graph.addEdge(
|
|
225
|
+
graph.addEdge(fnId + '-params', exit, { label: 0 /* CfgEdgeType.Fd */ });
|
|
224
226
|
}
|
|
225
227
|
}
|
|
226
228
|
if (params.length === 0) {
|
|
227
|
-
graph.addEdge(
|
|
229
|
+
graph.addEdge(fnId + '-params', fnId, { label: 0 /* CfgEdgeType.Fd */ });
|
|
228
230
|
}
|
|
229
231
|
for (const entry of body.entryPoints) {
|
|
230
|
-
graph.addEdge(entry,
|
|
232
|
+
graph.addEdge(entry, fnId + '-params', { label: 0 /* CfgEdgeType.Fd */ });
|
|
231
233
|
}
|
|
232
|
-
// breaks and nexts should be illegal but safe is safe
|
|
233
|
-
for (const next of
|
|
234
|
-
graph.addEdge(
|
|
234
|
+
// breaks and nexts should be illegal but safe is safe, I guess
|
|
235
|
+
for (const next of body.returns.concat(body.breaks, body.nexts, body.exitPoints)) {
|
|
236
|
+
graph.addEdge(fnId + '-exit', next, { label: 0 /* CfgEdgeType.Fd */ });
|
|
235
237
|
}
|
|
236
|
-
return { graph: graph, breaks: [], nexts: [], returns: [], exitPoints: [
|
|
238
|
+
return { graph: graph, breaks: [], nexts: [], returns: [], exitPoints: [fnId], entryPoints: [fnId] };
|
|
237
239
|
}
|
|
238
240
|
function cfgFunctionCall(call, name, args, exit = 'exit') {
|
|
241
|
+
const callId = call.info.id;
|
|
239
242
|
const graph = name.graph;
|
|
240
|
-
const info = { graph, breaks: [...name.breaks], nexts: [...name.nexts], returns: [...name.returns], exitPoints: [
|
|
241
|
-
graph.addVertex({ id:
|
|
243
|
+
const info = { graph, breaks: [...name.breaks], nexts: [...name.nexts], returns: [...name.returns], exitPoints: [callId + '-' + exit], entryPoints: [callId] };
|
|
244
|
+
graph.addVertex({ id: callId, type: identifyMayStatementType(call), mid: [callId + '-name'], end: [callId + '-' + exit] });
|
|
242
245
|
for (const entryPoint of name.entryPoints) {
|
|
243
|
-
graph.addEdge(entryPoint,
|
|
246
|
+
graph.addEdge(entryPoint, callId, { label: 0 /* CfgEdgeType.Fd */ });
|
|
244
247
|
}
|
|
245
|
-
graph.addVertex({ id:
|
|
248
|
+
graph.addVertex({ id: callId + '-name', kind: 'name', type: control_flow_graph_1.CfgVertexType.MidMarker, root: callId });
|
|
246
249
|
for (const exitPoint of name.exitPoints) {
|
|
247
|
-
graph.addEdge(
|
|
250
|
+
graph.addEdge(callId + '-name', exitPoint, { label: 0 /* CfgEdgeType.Fd */ });
|
|
248
251
|
}
|
|
249
|
-
graph.addVertex({ id:
|
|
250
|
-
let lastArgExits = [
|
|
252
|
+
graph.addVertex({ id: callId + '-' + exit, type: control_flow_graph_1.CfgVertexType.EndMarker, root: callId });
|
|
253
|
+
let lastArgExits = [callId + '-name'];
|
|
251
254
|
for (const arg of args) {
|
|
252
255
|
if (arg === r_function_call_1.EmptyArgument) {
|
|
253
256
|
continue;
|
|
@@ -264,7 +267,7 @@ function cfgFunctionCall(call, name, args, exit = 'exit') {
|
|
|
264
267
|
lastArgExits = arg.exitPoints;
|
|
265
268
|
}
|
|
266
269
|
for (const exit of lastArgExits) {
|
|
267
|
-
graph.addEdge(
|
|
270
|
+
graph.addEdge(callId + '-exit', exit, { label: 0 /* CfgEdgeType.Fd */ });
|
|
268
271
|
}
|
|
269
272
|
// should not contain any breaks, nexts, or returns, (except for the body if something like 'break()')
|
|
270
273
|
return info;
|
|
@@ -272,11 +275,11 @@ function cfgFunctionCall(call, name, args, exit = 'exit') {
|
|
|
272
275
|
exports.ResolvedCallSuffix = '-resolved-call-exit';
|
|
273
276
|
function cfgFunctionCallWithDataflow(graph) {
|
|
274
277
|
return (call, name, args) => {
|
|
275
|
-
const
|
|
278
|
+
const baseCfg = cfgFunctionCall(call, name, args);
|
|
276
279
|
/* try to resolve the call and link the target definitions */
|
|
277
280
|
const targets = (0, linker_1.getAllFunctionCallTargets)(call.info.id, graph);
|
|
278
281
|
const exits = [];
|
|
279
|
-
const callVertex =
|
|
282
|
+
const callVertex = baseCfg.graph.getVertex(call.info.id);
|
|
280
283
|
(0, assert_1.guard)(callVertex !== undefined, 'cfgFunctionCallWithDataflow: call vertex not found');
|
|
281
284
|
for (const target of targets) {
|
|
282
285
|
// we have to filter out non func-call targets as the call targets contains names and call ids
|
|
@@ -287,21 +290,21 @@ function cfgFunctionCallWithDataflow(graph) {
|
|
|
287
290
|
}
|
|
288
291
|
}
|
|
289
292
|
if (exits.length > 0) {
|
|
290
|
-
|
|
293
|
+
baseCfg.graph.addVertex({
|
|
291
294
|
id: call.info.id + exports.ResolvedCallSuffix,
|
|
292
295
|
type: control_flow_graph_1.CfgVertexType.EndMarker,
|
|
293
296
|
root: call.info.id
|
|
294
297
|
});
|
|
295
|
-
for (const exit of [...
|
|
296
|
-
|
|
298
|
+
for (const exit of [...baseCfg.exitPoints, ...exits]) {
|
|
299
|
+
baseCfg.graph.addEdge(call.info.id + exports.ResolvedCallSuffix, exit, { label: 0 /* CfgEdgeType.Fd */ });
|
|
297
300
|
}
|
|
298
301
|
return {
|
|
299
|
-
...
|
|
302
|
+
...baseCfg,
|
|
300
303
|
exitPoints: [call.info.id + exports.ResolvedCallSuffix]
|
|
301
304
|
};
|
|
302
305
|
}
|
|
303
306
|
else {
|
|
304
|
-
return
|
|
307
|
+
return baseCfg;
|
|
305
308
|
}
|
|
306
309
|
};
|
|
307
310
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { CfgExpressionVertex, CfgStatementVertex, ControlFlowInformation } from './control-flow-graph';
|
|
2
|
-
import type { DataflowInformation } from '../dataflow/info';
|
|
3
2
|
import type { DataflowCfgGuidedVisitorConfiguration } from './dfg-cfg-guided-visitor';
|
|
4
3
|
import { DataflowAwareCfgGuidedVisitor } from './dfg-cfg-guided-visitor';
|
|
5
4
|
import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
@@ -10,12 +9,12 @@ import type { DataflowGraphVertexFunctionCall, DataflowGraphVertexFunctionDefini
|
|
|
10
9
|
import type { RString } from '../r-bridge/lang-4.x/ast/model/nodes/r-string';
|
|
11
10
|
import type { RNumber } from '../r-bridge/lang-4.x/ast/model/nodes/r-number';
|
|
12
11
|
import type { RLogical } from '../r-bridge/lang-4.x/ast/model/nodes/r-logical';
|
|
13
|
-
import type { FunctionArgument } from '../dataflow/graph/graph';
|
|
12
|
+
import type { DataflowGraph, FunctionArgument } from '../dataflow/graph/graph';
|
|
14
13
|
import type { NoInfo, RNode } from '../r-bridge/lang-4.x/ast/model/model';
|
|
15
14
|
import type { RSymbol } from '../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
16
15
|
import type { BuiltInProcessorMapper } from '../dataflow/environments/built-in';
|
|
17
16
|
import type { RExpressionList } from '../r-bridge/lang-4.x/ast/model/nodes/r-expression-list';
|
|
18
|
-
export interface SemanticCfgGuidedVisitorConfiguration<OtherInfo = NoInfo,
|
|
17
|
+
export interface SemanticCfgGuidedVisitorConfiguration<OtherInfo = NoInfo, ControlFlow extends ControlFlowInformation = ControlFlowInformation, Ast extends NormalizedAst<OtherInfo> = NormalizedAst<OtherInfo>, Dfg extends DataflowGraph = DataflowGraph> extends DataflowCfgGuidedVisitorConfiguration<ControlFlow, Dfg>, SyntaxCfgGuidedVisitorConfiguration<OtherInfo, ControlFlow, Ast> {
|
|
19
18
|
}
|
|
20
19
|
/**
|
|
21
20
|
* This visitor extends on the {@link DataflowAwareCfgGuidedVisitor} by dispatching visitors for separate function calls as well,
|
|
@@ -40,7 +39,7 @@ export interface SemanticCfgGuidedVisitorConfiguration<OtherInfo = NoInfo, Cfg e
|
|
|
40
39
|
*
|
|
41
40
|
* Use {@link BasicCfgGuidedVisitor#start} to start the traversal.
|
|
42
41
|
*/
|
|
43
|
-
export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo,
|
|
42
|
+
export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, ControlFlow extends ControlFlowInformation = ControlFlowInformation, Ast extends NormalizedAst<OtherInfo> = NormalizedAst<OtherInfo>, Dfg extends DataflowGraph = DataflowGraph, Config extends SemanticCfgGuidedVisitorConfiguration<OtherInfo, ControlFlow, Ast, Dfg> = SemanticCfgGuidedVisitorConfiguration<OtherInfo, ControlFlow, Ast, Dfg>> extends DataflowAwareCfgGuidedVisitor<ControlFlow, Dfg, Config> {
|
|
44
43
|
/**
|
|
45
44
|
* A helper function to get the normalized AST node for the given id or fail if it does not exist.
|
|
46
45
|
*/
|
|
@@ -117,6 +116,11 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
|
|
|
117
116
|
* @protected
|
|
118
117
|
*/
|
|
119
118
|
protected onDispatchFunctionCallOrigin(call: DataflowGraphVertexFunctionCall, origin: keyof typeof BuiltInProcessorMapper | string): void;
|
|
119
|
+
/**
|
|
120
|
+
* This event is called for the root program node, i.e., the program that is being analyzed.
|
|
121
|
+
*
|
|
122
|
+
* @protected
|
|
123
|
+
*/
|
|
120
124
|
protected onProgram(_data: RExpressionList<OtherInfo>): void;
|
|
121
125
|
/**
|
|
122
126
|
* A helper function to request the {@link getOriginInDfg|origins} of the given node.
|
|
@@ -180,6 +184,7 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
|
|
|
180
184
|
*/
|
|
181
185
|
protected onFunctionDefinition(_data: {
|
|
182
186
|
vertex: DataflowGraphVertexFunctionDefinition;
|
|
187
|
+
parameters?: readonly NodeId[];
|
|
183
188
|
}): void;
|
|
184
189
|
/**
|
|
185
190
|
* This event triggers for every anonymous call within the program.
|
|
@@ -211,7 +216,7 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
|
|
|
211
216
|
*
|
|
212
217
|
* This explicitly will not trigger for scenarios in which the function has no name (i.e., if it is anonymous).
|
|
213
218
|
* For such cases, you may rely on the {@link SemanticCfgGuidedVisitor#onUnnamedCall|`onUnnamedCall`} event.
|
|
214
|
-
* The main reason for this separation is part of flowR's handling of these functions, as
|
|
219
|
+
* The main reason for this separation is part of flowR's handling of these functions, as anonymous calls cannot be resolved using the active environment.
|
|
215
220
|
*
|
|
216
221
|
* @protected
|
|
217
222
|
*/
|
|
@@ -282,9 +287,9 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
|
|
|
282
287
|
*/
|
|
283
288
|
protected onIfThenElseCall(_data: {
|
|
284
289
|
call: DataflowGraphVertexFunctionCall;
|
|
285
|
-
condition:
|
|
286
|
-
then:
|
|
287
|
-
else:
|
|
290
|
+
condition: NodeId | undefined;
|
|
291
|
+
then: NodeId | undefined;
|
|
292
|
+
else: NodeId | undefined;
|
|
288
293
|
}): void;
|
|
289
294
|
/**
|
|
290
295
|
* This event triggers for every call to the `get` function, which is used to access variables in the global environment.
|
|
@@ -346,6 +351,8 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
|
|
|
346
351
|
*/
|
|
347
352
|
protected onSpecialBinaryOpCall(_data: {
|
|
348
353
|
call: DataflowGraphVertexFunctionCall;
|
|
354
|
+
lhs?: FunctionArgument;
|
|
355
|
+
rhs?: FunctionArgument;
|
|
349
356
|
}): void;
|
|
350
357
|
/**
|
|
351
358
|
* This event triggers for every call to R's pipe operator, i.e., for every call to `|>`.
|
|
@@ -354,6 +361,8 @@ export declare class SemanticCfgGuidedVisitor<OtherInfo = NoInfo, Cfg extends Co
|
|
|
354
361
|
*/
|
|
355
362
|
protected onPipeCall(_data: {
|
|
356
363
|
call: DataflowGraphVertexFunctionCall;
|
|
364
|
+
lhs?: FunctionArgument;
|
|
365
|
+
rhs?: FunctionArgument;
|
|
357
366
|
}): void;
|
|
358
367
|
/**
|
|
359
368
|
* This event triggers for every call to the `quote` function, which is used to quote expressions.
|
|
@@ -6,6 +6,7 @@ const dfg_get_origin_1 = require("../dataflow/origin/dfg-get-origin");
|
|
|
6
6
|
const type_1 = require("../r-bridge/lang-4.x/ast/model/type");
|
|
7
7
|
const edge_1 = require("../dataflow/graph/edge");
|
|
8
8
|
const assert_1 = require("../util/assert");
|
|
9
|
+
const r_function_call_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
9
10
|
/**
|
|
10
11
|
* This visitor extends on the {@link DataflowAwareCfgGuidedVisitor} by dispatching visitors for separate function calls as well,
|
|
11
12
|
* providing more information!
|
|
@@ -90,7 +91,13 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
|
|
|
90
91
|
*/
|
|
91
92
|
visitFunctionDefinition(vertex) {
|
|
92
93
|
super.visitFunctionDefinition(vertex);
|
|
93
|
-
this.
|
|
94
|
+
const ast = this.getNormalizedAst(vertex.id);
|
|
95
|
+
if (ast?.type === type_1.RType.FunctionDefinition) {
|
|
96
|
+
this.onFunctionDefinition({ vertex, parameters: ast.parameters.map(p => p.info.id) });
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
this.onFunctionDefinition({ vertex });
|
|
100
|
+
}
|
|
94
101
|
}
|
|
95
102
|
/**
|
|
96
103
|
* See {@link DataflowAwareCfgGuidedVisitor#visitFunctionCall} for the base implementation.
|
|
@@ -161,8 +168,26 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
|
|
|
161
168
|
return this.onSourceCall({ call });
|
|
162
169
|
case 'builtin:access':
|
|
163
170
|
return this.onAccessCall({ call });
|
|
164
|
-
case 'builtin:if-then-else':
|
|
165
|
-
|
|
171
|
+
case 'builtin:if-then-else': {
|
|
172
|
+
// recover dead arguments from ast
|
|
173
|
+
const ast = this.getNormalizedAst(call.id);
|
|
174
|
+
if (!ast || ast.type !== type_1.RType.IfThenElse) {
|
|
175
|
+
return this.onIfThenElseCall({
|
|
176
|
+
call,
|
|
177
|
+
condition: call.args[0] === r_function_call_1.EmptyArgument ? undefined : call.args[0].nodeId,
|
|
178
|
+
then: call.args[1] === r_function_call_1.EmptyArgument ? undefined : call.args[1].nodeId,
|
|
179
|
+
else: call.args[2] === r_function_call_1.EmptyArgument ? undefined : call.args[2].nodeId
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
return this.onIfThenElseCall({
|
|
184
|
+
call,
|
|
185
|
+
condition: ast.condition.info.id,
|
|
186
|
+
then: ast.then.info.id,
|
|
187
|
+
else: ast.otherwise?.info.id
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
166
191
|
case 'builtin:get':
|
|
167
192
|
return this.onGetCall({ call });
|
|
168
193
|
case 'builtin:rm':
|
|
@@ -173,11 +198,11 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
|
|
|
173
198
|
return this.onVectorCall({ call });
|
|
174
199
|
case 'table:assign':
|
|
175
200
|
case 'builtin:assignment': {
|
|
176
|
-
const outgoing = this.config.
|
|
201
|
+
const outgoing = this.config.dfg.outgoingEdges(call.id);
|
|
177
202
|
if (outgoing) {
|
|
178
203
|
const target = [...outgoing.entries()].filter(([, e]) => (0, edge_1.edgeIncludesType)(e.types, edge_1.EdgeType.Returns));
|
|
179
204
|
if (target.length === 1) {
|
|
180
|
-
const targetOut = this.config.
|
|
205
|
+
const targetOut = this.config.dfg.outgoingEdges(target[0][0]);
|
|
181
206
|
if (targetOut) {
|
|
182
207
|
const source = [...targetOut.entries()].filter(([t, e]) => (0, edge_1.edgeIncludesType)(e.types, edge_1.EdgeType.DefinedBy) && t !== call.id);
|
|
183
208
|
if (source.length === 1) {
|
|
@@ -189,9 +214,15 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
|
|
|
189
214
|
return this.onAssignmentCall({ call, target: undefined, source: undefined });
|
|
190
215
|
}
|
|
191
216
|
case 'builtin:special-bin-op':
|
|
192
|
-
|
|
217
|
+
if (call.args.length !== 2) {
|
|
218
|
+
return this.onSpecialBinaryOpCall({ call });
|
|
219
|
+
}
|
|
220
|
+
return this.onSpecialBinaryOpCall({ call, lhs: call.args[0], rhs: call.args[1] });
|
|
193
221
|
case 'builtin:pipe':
|
|
194
|
-
|
|
222
|
+
if (call.args.length !== 2) {
|
|
223
|
+
return this.onPipeCall({ call });
|
|
224
|
+
}
|
|
225
|
+
return this.onPipeCall({ call, lhs: call.args[0], rhs: call.args[1] });
|
|
195
226
|
case 'builtin:quote':
|
|
196
227
|
return this.onQuoteCall({ call });
|
|
197
228
|
case 'builtin:for-loop':
|
|
@@ -201,11 +232,11 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
|
|
|
201
232
|
case 'builtin:while-loop':
|
|
202
233
|
return this.onWhileLoopCall({ call, condition: call.args[0], body: call.args[1] });
|
|
203
234
|
case 'builtin:replacement': {
|
|
204
|
-
const outgoing = this.config.
|
|
235
|
+
const outgoing = this.config.dfg.outgoingEdges(call.id);
|
|
205
236
|
if (outgoing) {
|
|
206
237
|
const target = [...outgoing.entries()].filter(([, e]) => (0, edge_1.edgeIncludesType)(e.types, edge_1.EdgeType.Returns));
|
|
207
238
|
if (target.length === 1) {
|
|
208
|
-
const targetOut = this.config.
|
|
239
|
+
const targetOut = this.config.dfg.outgoingEdges(target[0][0]);
|
|
209
240
|
if (targetOut) {
|
|
210
241
|
const source = [...targetOut.entries()].filter(([t, e]) => (0, edge_1.edgeIncludesType)(e.types, edge_1.EdgeType.DefinedBy) && t !== call.id);
|
|
211
242
|
if (source.length === 1) {
|
|
@@ -223,13 +254,17 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
|
|
|
223
254
|
return this.onDefaultFunctionCall({ call });
|
|
224
255
|
}
|
|
225
256
|
}
|
|
226
|
-
|
|
227
|
-
|
|
257
|
+
/**
|
|
258
|
+
* This event is called for the root program node, i.e., the program that is being analyzed.
|
|
259
|
+
*
|
|
260
|
+
* @protected
|
|
261
|
+
*/
|
|
262
|
+
onProgram(_data) { }
|
|
228
263
|
/**
|
|
229
264
|
* A helper function to request the {@link getOriginInDfg|origins} of the given node.
|
|
230
265
|
*/
|
|
231
266
|
getOrigins(id) {
|
|
232
|
-
return (0, dfg_get_origin_1.getOriginInDfg)(this.config.
|
|
267
|
+
return (0, dfg_get_origin_1.getOriginInDfg)(this.config.dfg, id);
|
|
233
268
|
}
|
|
234
269
|
/** Called for every occurrence of a `NULL` in the program. */
|
|
235
270
|
onNullConstant(_data) { }
|
|
@@ -300,7 +335,7 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
|
|
|
300
335
|
*
|
|
301
336
|
* This explicitly will not trigger for scenarios in which the function has no name (i.e., if it is anonymous).
|
|
302
337
|
* For such cases, you may rely on the {@link SemanticCfgGuidedVisitor#onUnnamedCall|`onUnnamedCall`} event.
|
|
303
|
-
* The main reason for this separation is part of flowR's handling of these functions, as
|
|
338
|
+
* The main reason for this separation is part of flowR's handling of these functions, as anonymous calls cannot be resolved using the active environment.
|
|
304
339
|
*
|
|
305
340
|
* @protected
|
|
306
341
|
*/
|
|
@@ -351,15 +386,13 @@ class SemanticCfgGuidedVisitor extends dfg_cfg_guided_visitor_1.DataflowAwareCfg
|
|
|
351
386
|
*
|
|
352
387
|
* @protected
|
|
353
388
|
*/
|
|
354
|
-
onAccessCall(_data) {
|
|
355
|
-
}
|
|
389
|
+
onAccessCall(_data) { }
|
|
356
390
|
/**
|
|
357
391
|
* This event triggers for every call to the `if` function, which is used to implement the `if-then-else` control flow.
|
|
358
392
|
*
|
|
359
393
|
* @protected
|
|
360
394
|
*/
|
|
361
|
-
onIfThenElseCall(_data) {
|
|
362
|
-
}
|
|
395
|
+
onIfThenElseCall(_data) { }
|
|
363
396
|
/**
|
|
364
397
|
* This event triggers for every call to the `get` function, which is used to access variables in the global environment.
|
|
365
398
|
*
|
|
@@ -23,3 +23,7 @@ export declare function visitCfgInReverseOrder(graph: ControlFlowGraph, startNod
|
|
|
23
23
|
* @see {@link visitCfgInReverseOrder} for a traversal in reversed order
|
|
24
24
|
*/
|
|
25
25
|
export declare function visitCfgInOrder(graph: ControlFlowGraph, startNodes: readonly NodeId[], visitor: (node: NodeId) => boolean | void): void;
|
|
26
|
+
/**
|
|
27
|
+
* Check if a node can reach another node in the control flow graph.
|
|
28
|
+
*/
|
|
29
|
+
export declare function canReach(graph: ControlFlowGraph, from: NodeId[], to: NodeId): boolean;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.visitCfgInReverseOrder = visitCfgInReverseOrder;
|
|
4
4
|
exports.visitCfgInOrder = visitCfgInOrder;
|
|
5
|
+
exports.canReach = canReach;
|
|
5
6
|
const control_flow_graph_1 = require("./control-flow-graph");
|
|
6
7
|
/**
|
|
7
8
|
* Visit all nodes reachable from the start node in the control flow graph, traversing the dependencies but ignoring cycles.
|
|
@@ -77,4 +78,17 @@ visitor) {
|
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Check if a node can reach another node in the control flow graph.
|
|
83
|
+
*/
|
|
84
|
+
function canReach(graph, from, to) {
|
|
85
|
+
let reached = false;
|
|
86
|
+
visitCfgInOrder(graph, from, node => {
|
|
87
|
+
if (node === to) {
|
|
88
|
+
reached = true;
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
return reached;
|
|
93
|
+
}
|
|
80
94
|
//# sourceMappingURL=simple-visitor.js.map
|
|
@@ -25,7 +25,7 @@ import type { RNext } from '../r-bridge/lang-4.x/ast/model/nodes/r-next';
|
|
|
25
25
|
import type { RNumber } from '../r-bridge/lang-4.x/ast/model/nodes/r-number';
|
|
26
26
|
import type { RSymbol } from '../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
27
27
|
import type { NoInfo, RNode } from '../r-bridge/lang-4.x/ast/model/model';
|
|
28
|
-
export interface SyntaxCfgGuidedVisitorConfiguration<OtherInfo = NoInfo,
|
|
28
|
+
export interface SyntaxCfgGuidedVisitorConfiguration<OtherInfo = NoInfo, ControlFlow extends ControlFlowInformation = ControlFlowInformation, Ast extends NormalizedAst<OtherInfo> = NormalizedAst<OtherInfo>> extends BasicCfgGuidedVisitorConfiguration<ControlFlow> {
|
|
29
29
|
readonly normalizedAst: Ast;
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
@@ -33,7 +33,7 @@ export interface SyntaxCfgGuidedVisitorConfiguration<OtherInfo = NoInfo, Cfg ext
|
|
|
33
33
|
*
|
|
34
34
|
* Use {@link BasicCfgGuidedVisitor#start} to start the traversal.
|
|
35
35
|
*/
|
|
36
|
-
export declare class SyntaxAwareCfgGuidedVisitor<OtherInfo = NoInfo,
|
|
36
|
+
export declare class SyntaxAwareCfgGuidedVisitor<OtherInfo = NoInfo, ControlFlow extends ControlFlowInformation = ControlFlowInformation, Ast extends NormalizedAst<OtherInfo> = NormalizedAst<OtherInfo>, Config extends SyntaxCfgGuidedVisitorConfiguration<OtherInfo, ControlFlow, Ast> = SyntaxCfgGuidedVisitorConfiguration<OtherInfo, ControlFlow, Ast>> extends BasicCfgGuidedVisitor<ControlFlow, Config> {
|
|
37
37
|
/**
|
|
38
38
|
* Get the normalized AST node for the given id or fail if it does not exist.
|
|
39
39
|
*/
|
|
@@ -27,6 +27,7 @@ export interface BuiltInFunctionDefinition<BuiltInProcessor extends BuiltInMappi
|
|
|
27
27
|
readonly type: 'function';
|
|
28
28
|
readonly processor: BuiltInProcessor;
|
|
29
29
|
readonly config?: ConfigOfBuiltInMappingName<BuiltInProcessor>;
|
|
30
|
+
readonly evalHandler?: string;
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
32
33
|
* Define a built-in replacement (like `[` or `$`) and the processor to use.
|
|
@@ -15,7 +15,7 @@ import { processQuote } from '../internal/process/functions/call/built-in/built-
|
|
|
15
15
|
import { processFunctionDefinition } from '../internal/process/functions/call/built-in/built-in-function-definition';
|
|
16
16
|
import { processExpressionList } from '../internal/process/functions/call/built-in/built-in-expression-list';
|
|
17
17
|
import { processGet } from '../internal/process/functions/call/built-in/built-in-get';
|
|
18
|
-
import type { ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
18
|
+
import type { AstIdMap, ParentInformation, RNodeWithParent } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
19
19
|
import type { RFunctionArgument } from '../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
20
20
|
import type { RSymbol } from '../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
21
21
|
import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
@@ -28,6 +28,10 @@ import { processList } from '../internal/process/functions/call/built-in/built-i
|
|
|
28
28
|
import { processVector } from '../internal/process/functions/call/built-in/built-in-vector';
|
|
29
29
|
import { processRm } from '../internal/process/functions/call/built-in/built-in-rm';
|
|
30
30
|
import { processEvalCall } from '../internal/process/functions/call/built-in/built-in-eval';
|
|
31
|
+
import type { REnvironmentInformation } from './environment';
|
|
32
|
+
import type { Value } from '../eval/values/r-value';
|
|
33
|
+
import { resolveAsVector } from '../eval/resolve/resolve';
|
|
34
|
+
import type { DataflowGraph } from '../graph/graph';
|
|
31
35
|
export type BuiltIn = `built-in:${string}`;
|
|
32
36
|
export declare function builtInId(name: string): BuiltIn;
|
|
33
37
|
export declare function isBuiltIn(name: NodeId | string): name is BuiltIn;
|
|
@@ -52,6 +56,7 @@ export interface DefaultBuiltInProcessorConfiguration extends ForceArguments {
|
|
|
52
56
|
/** record mapping the actual function name called to the arguments that should be treated as function calls */
|
|
53
57
|
readonly treatAsFnCall?: Record<string, readonly string[]>;
|
|
54
58
|
}
|
|
59
|
+
export type BuiltInEvalHandler = (a: RNodeWithParent, env: REnvironmentInformation, graph?: DataflowGraph, map?: AstIdMap) => Value;
|
|
55
60
|
declare function defaultBuiltInProcessor<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>, config: DefaultBuiltInProcessorConfiguration): DataflowInformation;
|
|
56
61
|
export declare function registerBuiltInFunctions<Config extends object, Proc extends BuiltInIdentifierProcessorWithConfig<Config>>(both: boolean, names: readonly Identifier[], processor: Proc, config: Config): void;
|
|
57
62
|
export declare const BuiltInProcessorMapper: {
|
|
@@ -77,6 +82,10 @@ export declare const BuiltInProcessorMapper: {
|
|
|
77
82
|
readonly 'builtin:list': typeof processList;
|
|
78
83
|
readonly 'builtin:vector': typeof processVector;
|
|
79
84
|
};
|
|
85
|
+
export declare const BuiltInEvalHandlerMapper: {
|
|
86
|
+
readonly 'built-in:c': typeof resolveAsVector;
|
|
87
|
+
readonly 'builtin:vector': typeof resolveAsVector;
|
|
88
|
+
};
|
|
80
89
|
export type BuiltInMappingName = keyof typeof BuiltInProcessorMapper;
|
|
81
90
|
export type ConfigOfBuiltInMappingName<N extends BuiltInMappingName> = Parameters<typeof BuiltInProcessorMapper[N]>[4];
|
|
82
91
|
export declare const BuiltInMemory: Map<Identifier, IdentifierDefinition[]>;
|