@eagleoutice/flowr 2.2.16 → 2.4.0
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 +48 -20
- package/abstract-interpretation/data-frame/absint-info.d.ts +109 -0
- package/abstract-interpretation/data-frame/absint-info.js +31 -0
- package/abstract-interpretation/data-frame/absint-visitor.d.ts +58 -0
- package/abstract-interpretation/data-frame/absint-visitor.js +171 -0
- package/abstract-interpretation/data-frame/domain.d.ts +107 -0
- package/abstract-interpretation/data-frame/domain.js +315 -0
- package/abstract-interpretation/data-frame/mappers/access-mapper.d.ts +17 -0
- package/abstract-interpretation/data-frame/mappers/access-mapper.js +166 -0
- package/abstract-interpretation/data-frame/mappers/arguments.d.ts +117 -0
- package/abstract-interpretation/data-frame/mappers/arguments.js +188 -0
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.d.ts +20 -0
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.js +34 -0
- package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +261 -0
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +1219 -0
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.d.ts +12 -0
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +206 -0
- package/abstract-interpretation/data-frame/resolve-args.d.ts +42 -0
- package/abstract-interpretation/data-frame/resolve-args.js +118 -0
- package/abstract-interpretation/data-frame/semantics.d.ts +213 -0
- package/abstract-interpretation/data-frame/semantics.js +363 -0
- package/abstract-interpretation/data-frame/shape-inference.d.ts +38 -0
- package/abstract-interpretation/data-frame/shape-inference.js +111 -0
- package/benchmark/slicer.d.ts +15 -1
- package/benchmark/slicer.js +137 -0
- package/benchmark/stats/print.js +123 -45
- package/benchmark/stats/size-of.d.ts +7 -0
- package/benchmark/stats/size-of.js +1 -0
- package/benchmark/stats/stats.d.ts +30 -1
- package/benchmark/stats/stats.js +4 -2
- package/benchmark/summarizer/data.d.ts +33 -2
- package/benchmark/summarizer/first-phase/input.js +5 -1
- package/benchmark/summarizer/first-phase/process.js +47 -1
- package/benchmark/summarizer/second-phase/graph.js +1 -1
- package/benchmark/summarizer/second-phase/process.js +102 -4
- package/cli/benchmark-app.d.ts +2 -0
- package/cli/benchmark-app.js +2 -0
- package/cli/benchmark-helper-app.d.ts +2 -0
- package/cli/benchmark-helper-app.js +10 -3
- package/cli/common/options.js +4 -0
- package/cli/repl/commands/repl-query.js +1 -1
- package/cli/repl/server/connection.js +14 -5
- package/config.d.ts +31 -0
- package/config.js +21 -1
- package/control-flow/basic-cfg-guided-visitor.d.ts +1 -2
- package/control-flow/basic-cfg-guided-visitor.js +0 -6
- package/control-flow/cfg-simplification.d.ts +6 -0
- package/control-flow/cfg-simplification.js +18 -9
- package/control-flow/control-flow-graph.d.ts +3 -8
- package/control-flow/control-flow-graph.js +5 -6
- 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 +52 -63
- package/control-flow/semantic-cfg-guided-visitor.d.ts +1 -1
- package/control-flow/semantic-cfg-guided-visitor.js +1 -1
- package/core/steps/all/static-slicing/00-slice.d.ts +7 -1
- package/core/steps/all/static-slicing/00-slice.js +9 -3
- package/core/steps/pipeline/default-pipelines.d.ts +74 -74
- package/dataflow/environments/built-in.d.ts +7 -5
- package/dataflow/environments/built-in.js +16 -13
- package/dataflow/eval/resolve/alias-tracking.js +2 -2
- package/dataflow/eval/resolve/resolve.d.ts +53 -9
- package/dataflow/eval/resolve/resolve.js +132 -38
- package/dataflow/graph/dataflowgraph-builder.js +2 -2
- package/dataflow/graph/graph.js +1 -1
- package/dataflow/graph/invert-dfg.d.ts +2 -0
- package/dataflow/graph/invert-dfg.js +17 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +1 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +4 -0
- package/documentation/doc-util/doc-query.js +11 -1
- package/documentation/doc-util/doc-search.js +2 -2
- package/documentation/print-cfg-wiki.js +3 -4
- package/documentation/print-core-wiki.js +2 -2
- package/documentation/print-dataflow-graph-wiki.js +7 -0
- package/documentation/print-faq-wiki.js +4 -0
- package/documentation/print-interface-wiki.js +11 -0
- package/documentation/print-linter-wiki.js +36 -4
- package/documentation/print-linting-and-testing-wiki.js +13 -1
- package/documentation/print-onboarding-wiki.js +4 -0
- package/documentation/print-query-wiki.js +29 -3
- package/linter/linter-executor.js +1 -2
- package/linter/linter-format.d.ts +26 -4
- package/linter/linter-format.js +25 -6
- package/linter/linter-rules.d.ts +63 -12
- package/linter/linter-rules.js +5 -1
- package/linter/rules/absolute-path.d.ts +4 -7
- package/linter/rules/absolute-path.js +9 -6
- package/linter/rules/dataframe-access-validation.d.ts +55 -0
- package/linter/rules/dataframe-access-validation.js +118 -0
- package/linter/rules/dead-code.d.ts +43 -0
- package/linter/rules/dead-code.js +50 -0
- package/linter/rules/deprecated-functions.d.ts +3 -2
- package/linter/rules/deprecated-functions.js +3 -1
- package/linter/rules/file-path-validity.d.ts +4 -4
- package/linter/rules/file-path-validity.js +8 -6
- package/linter/rules/naming-convention.d.ts +5 -4
- package/linter/rules/naming-convention.js +8 -2
- package/linter/rules/seeded-randomness.d.ts +4 -3
- package/linter/rules/seeded-randomness.js +3 -1
- package/linter/rules/unused-definition.d.ts +2 -0
- package/linter/rules/unused-definition.js +3 -1
- package/package.json +2 -2
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +6 -1
- package/queries/catalog/dependencies-query/function-info/read-functions.js +1 -0
- package/queries/catalog/dependencies-query/function-info/write-functions.js +1 -0
- package/queries/catalog/df-shape-query/df-shape-query-executor.d.ts +3 -0
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +46 -0
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +72 -0
- package/queries/catalog/df-shape-query/df-shape-query-format.js +31 -0
- package/queries/catalog/linter-query/linter-query-format.js +1 -1
- package/queries/catalog/location-map-query/location-map-query-executor.js +7 -5
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +3 -0
- package/queries/catalog/location-map-query/location-map-query-format.js +1 -0
- package/queries/catalog/search-query/search-query-executor.js +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +2 -1
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +3 -0
- package/queries/catalog/static-slice-query/static-slice-query-format.js +3 -1
- package/queries/query-print.d.ts +1 -1
- package/queries/query-print.js +0 -1
- package/queries/query.d.ts +77 -6
- package/queries/query.js +26 -11
- package/search/flowr-search-builder.d.ts +6 -6
- package/search/flowr-search-executor.d.ts +2 -2
- package/search/flowr-search-executor.js +1 -1
- package/search/flowr-search.d.ts +13 -8
- package/search/flowr-search.js +21 -0
- package/search/search-executor/search-enrichers.d.ts +87 -20
- package/search/search-executor/search-enrichers.js +44 -5
- package/search/search-executor/search-generators.d.ts +4 -4
- package/search/search-executor/search-generators.js +12 -7
- package/search/search-executor/search-mappers.js +3 -2
- package/search/search-executor/search-transformer.d.ts +3 -3
- package/search/search-executor/search-transformer.js +2 -2
- package/slicing/static/static-slicer.d.ts +4 -2
- package/slicing/static/static-slicer.js +10 -4
- package/util/collections/arrays.d.ts +2 -0
- package/util/collections/arrays.js +9 -0
- package/util/files.d.ts +8 -2
- package/util/files.js +22 -4
- package/util/mermaid/dfg.js +4 -2
- package/util/r-value.d.ts +23 -0
- package/util/r-value.js +113 -0
- package/util/range.d.ts +1 -0
- package/util/range.js +5 -1
- package/util/version.js +1 -1
- package/util/cfg/cfg.d.ts +0 -0
- package/util/cfg/cfg.js +0 -2
|
@@ -41,30 +41,31 @@ function builtInId(name) {
|
|
|
41
41
|
function isBuiltIn(name) {
|
|
42
42
|
return String(name).startsWith('built-in:');
|
|
43
43
|
}
|
|
44
|
-
function defaultBuiltInProcessor(name, args, rootId, data,
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
function defaultBuiltInProcessor(name, args, rootId, data, { returnsNthArgument, useAsProcessor, forceArgs, readAllArguments, cfg, hasUnknownSideEffects, treatAsFnCall }) {
|
|
45
|
+
const activeProcessor = useAsProcessor ?? 'builtin:default';
|
|
46
|
+
const { information: res, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs, origin: activeProcessor });
|
|
47
|
+
if (returnsNthArgument !== undefined) {
|
|
48
|
+
const arg = returnsNthArgument === 'last' ? processedArguments[args.length - 1] : processedArguments[returnsNthArgument];
|
|
48
49
|
if (arg !== undefined) {
|
|
49
50
|
res.graph.addEdge(rootId, arg.entryPoint, edge_1.EdgeType.Returns);
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
|
-
if (
|
|
53
|
+
if (readAllArguments) {
|
|
53
54
|
for (const arg of processedArguments) {
|
|
54
55
|
if (arg) {
|
|
55
56
|
res.graph.addEdge(rootId, arg.entryPoint, edge_1.EdgeType.Reads);
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
|
-
if (
|
|
60
|
-
if (typeof
|
|
61
|
-
(0, unknown_side_effect_1.handleUnknownSideEffect)(res.graph, res.environment, rootId,
|
|
60
|
+
if (hasUnknownSideEffects) {
|
|
61
|
+
if (typeof hasUnknownSideEffects !== 'boolean') {
|
|
62
|
+
(0, unknown_side_effect_1.handleUnknownSideEffect)(res.graph, res.environment, rootId, hasUnknownSideEffects);
|
|
62
63
|
}
|
|
63
64
|
else {
|
|
64
65
|
(0, unknown_side_effect_1.handleUnknownSideEffect)(res.graph, res.environment, rootId);
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
|
-
const fnCallNames =
|
|
68
|
+
const fnCallNames = treatAsFnCall?.[name.content];
|
|
68
69
|
if (fnCallNames) {
|
|
69
70
|
for (const arg of args) {
|
|
70
71
|
if (arg !== r_function_call_1.EmptyArgument && arg.value && fnCallNames.includes(arg.name?.content)) {
|
|
@@ -90,13 +91,13 @@ function defaultBuiltInProcessor(name, args, rootId, data, config) {
|
|
|
90
91
|
environment: data.environment,
|
|
91
92
|
onlyBuiltin: false,
|
|
92
93
|
cds: data.controlDependencies,
|
|
93
|
-
origin: [
|
|
94
|
+
origin: [activeProcessor]
|
|
94
95
|
});
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
|
-
if (
|
|
99
|
-
res.exitPoints
|
|
99
|
+
if (cfg !== undefined) {
|
|
100
|
+
res.exitPoints.push({ type: cfg, nodeId: rootId, controlDependencies: data.controlDependencies });
|
|
100
101
|
}
|
|
101
102
|
return res;
|
|
102
103
|
}
|
|
@@ -144,7 +145,9 @@ exports.BuiltInProcessorMapper = {
|
|
|
144
145
|
};
|
|
145
146
|
exports.BuiltInEvalHandlerMapper = {
|
|
146
147
|
'built-in:c': resolve_1.resolveAsVector,
|
|
147
|
-
'
|
|
148
|
+
'built-in::': resolve_1.resolveAsSeq,
|
|
149
|
+
'built-in:+': resolve_1.resolveAsPlus,
|
|
150
|
+
'built-in:-': resolve_1.resolveAsMinus
|
|
148
151
|
};
|
|
149
152
|
exports.BuiltInMemory = new Map();
|
|
150
153
|
exports.EmptyBuiltInMemory = new Map();
|
|
@@ -139,6 +139,8 @@ function resolveIdToValue(id, { environment, graph, idMap, full = true, resolve
|
|
|
139
139
|
return r_value_1.Top;
|
|
140
140
|
}
|
|
141
141
|
case type_1.RType.FunctionCall:
|
|
142
|
+
case type_1.RType.BinaryOp:
|
|
143
|
+
case type_1.RType.UnaryOp:
|
|
142
144
|
return (0, set_constants_1.setFrom)((0, resolve_1.resolveNode)(resolve, node, environment, graph, idMap));
|
|
143
145
|
case type_1.RType.String:
|
|
144
146
|
case type_1.RType.Number:
|
|
@@ -261,8 +263,6 @@ function isNestedInLoop(node, ast) {
|
|
|
261
263
|
function trackAliasesInGraph(id, graph, idMap) {
|
|
262
264
|
idMap ??= graph.idMap;
|
|
263
265
|
(0, assert_1.guard)(idMap !== undefined, 'The ID map is required to get the lineage of a node');
|
|
264
|
-
const start = graph.getVertex(id);
|
|
265
|
-
(0, assert_1.guard)(start !== undefined, 'Unable to find start for alias tracking');
|
|
266
266
|
const queue = new visiting_queue_1.VisitingQueue(25);
|
|
267
267
|
const clean = (0, environment_1.initializeCleanEnvironments)();
|
|
268
268
|
const cleanFingerprint = (0, fingerprint_1.envFingerprint)(clean);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { AstIdMap, RNodeWithParent } from '../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
2
2
|
import type { REnvironmentInformation } from '../../environments/environment';
|
|
3
3
|
import type { DataflowGraph } from '../../graph/graph';
|
|
4
|
-
import type { Value } from '../values/r-value';
|
|
4
|
+
import type { Lift, Value, ValueNumber, ValueVector } from '../values/r-value';
|
|
5
|
+
import { Top } from '../values/r-value';
|
|
5
6
|
import type { VariableResolve } from '../../../config';
|
|
6
7
|
/**
|
|
7
8
|
* Helper function used by {@link resolveIdToValue}, please use that instead, if
|
|
@@ -22,16 +23,59 @@ export declare function resolveNode(resolve: VariableResolve, a: RNodeWithParent
|
|
|
22
23
|
* Helper function used by {@link resolveIdToValue}, please use that instead, if
|
|
23
24
|
* you want to resolve the value of an identifier / node
|
|
24
25
|
*
|
|
25
|
-
* This function
|
|
26
|
-
*
|
|
27
|
-
* order to construct the value of the vector to resolve by calling {@link resolveIdToValue}
|
|
28
|
-
* or {@link resolveNode}
|
|
26
|
+
* This function resolves a vector function call `c` to a {@link ValueVector}
|
|
27
|
+
* by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
|
|
29
28
|
*
|
|
30
|
-
* @param a - Node of the vector to resolve
|
|
31
|
-
* @param env - Environment to use
|
|
32
29
|
* @param resolve - Variable resolve mode
|
|
30
|
+
* @param node - Node of the vector function to resolve
|
|
31
|
+
* @param env - Environment to use
|
|
33
32
|
* @param graph - Dataflow graph
|
|
34
|
-
* @param map -
|
|
33
|
+
* @param map - Id map of the dataflow graph
|
|
35
34
|
* @returns ValueVector or Top
|
|
36
35
|
*/
|
|
37
|
-
export declare function resolveAsVector(resolve: VariableResolve,
|
|
36
|
+
export declare function resolveAsVector(resolve: VariableResolve, node: RNodeWithParent, environment?: REnvironmentInformation, graph?: DataflowGraph, idMap?: AstIdMap): ValueVector<Lift<Value[]>> | typeof Top;
|
|
37
|
+
/**
|
|
38
|
+
* Helper function used by {@link resolveIdToValue}, please use that instead, if
|
|
39
|
+
* you want to resolve the value of an identifier / node
|
|
40
|
+
*
|
|
41
|
+
* This function resolves a binary sequence operator `:` to a {@link ValueVector} of {@link ValueNumber}s
|
|
42
|
+
* by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
|
|
43
|
+
*
|
|
44
|
+
* @param resolve - Variable resolve mode
|
|
45
|
+
* @param operator - Node of the sequence operator to resolve
|
|
46
|
+
* @param env - Environment to use
|
|
47
|
+
* @param graph - Dataflow graph
|
|
48
|
+
* @param map - Id map of the dataflow graph
|
|
49
|
+
* @returns ValueVector of ValueNumbers or Top
|
|
50
|
+
*/
|
|
51
|
+
export declare function resolveAsSeq(resolve: VariableResolve, operator: RNodeWithParent, environment?: REnvironmentInformation, graph?: DataflowGraph, idMap?: AstIdMap): ValueVector<Lift<ValueNumber[]>> | typeof Top;
|
|
52
|
+
/**
|
|
53
|
+
* Helper function used by {@link resolveIdToValue}, please use that instead, if
|
|
54
|
+
* you want to resolve the value of an identifier / node
|
|
55
|
+
*
|
|
56
|
+
* This function resolves a unary plus operator `+` to a {@link ValueNumber} or {@link ValueVector} of ValueNumbers
|
|
57
|
+
* by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
|
|
58
|
+
*
|
|
59
|
+
* @param resolve - Variable resolve mode
|
|
60
|
+
* @param operator - Node of the plus operator to resolve
|
|
61
|
+
* @param env - Environment to use
|
|
62
|
+
* @param graph - Dataflow graph
|
|
63
|
+
* @param map - Id map of the dataflow graph
|
|
64
|
+
* @returns ValueNumber, ValueVector of ValueNumbers, or Top
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveAsPlus(resolve: VariableResolve, operator: RNodeWithParent, environment?: REnvironmentInformation, graph?: DataflowGraph, idMap?: AstIdMap): ValueNumber | ValueVector<Lift<ValueNumber[]>> | typeof Top;
|
|
67
|
+
/**
|
|
68
|
+
* Helper function used by {@link resolveIdToValue}, please use that instead, if
|
|
69
|
+
* you want to resolve the value of an identifier / node
|
|
70
|
+
*
|
|
71
|
+
* This function resolves a unary minus operator `-` to a {@link ValueNumber} or {@link ValueVector} of ValueNumbers
|
|
72
|
+
* by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
|
|
73
|
+
*
|
|
74
|
+
* @param resolve - Variable resolve mode
|
|
75
|
+
* @param operator - Node of the minus operator to resolve
|
|
76
|
+
* @param env - Environment to use
|
|
77
|
+
* @param graph - Dataflow graph
|
|
78
|
+
* @param map - Id map of the dataflow graph
|
|
79
|
+
* @returns ValueNumber, ValueVector of ValueNumbers, or Top
|
|
80
|
+
*/
|
|
81
|
+
export declare function resolveAsMinus(resolve: VariableResolve, operator: RNodeWithParent, environment?: REnvironmentInformation, graph?: DataflowGraph, idMap?: AstIdMap): ValueNumber | ValueVector<Lift<ValueNumber[]>> | typeof Top;
|
|
@@ -2,17 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.resolveNode = resolveNode;
|
|
4
4
|
exports.resolveAsVector = resolveAsVector;
|
|
5
|
+
exports.resolveAsSeq = resolveAsSeq;
|
|
6
|
+
exports.resolveAsPlus = resolveAsPlus;
|
|
7
|
+
exports.resolveAsMinus = resolveAsMinus;
|
|
5
8
|
const r_function_call_1 = require("../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
6
9
|
const type_1 = require("../../../r-bridge/lang-4.x/ast/model/type");
|
|
7
|
-
const
|
|
10
|
+
const r_value_1 = require("../../../util/r-value");
|
|
8
11
|
const built_in_1 = require("../../environments/built-in");
|
|
9
12
|
const dfg_get_origin_1 = require("../../origin/dfg-get-origin");
|
|
10
13
|
const interval_constants_1 = require("../values/intervals/interval-constants");
|
|
11
14
|
const logical_constants_1 = require("../values/logical/logical-constants");
|
|
12
|
-
const
|
|
15
|
+
const r_value_2 = require("../values/r-value");
|
|
13
16
|
const string_constants_1 = require("../values/string/string-constants");
|
|
14
17
|
const vector_constants_1 = require("../values/vectors/vector-constants");
|
|
15
18
|
const alias_tracking_1 = require("./alias-tracking");
|
|
19
|
+
const scalar_consatnts_1 = require("../values/scalar/scalar-consatnts");
|
|
16
20
|
/**
|
|
17
21
|
* Helper function used by {@link resolveIdToValue}, please use that instead, if
|
|
18
22
|
* you want to resolve the value of an identifier / node
|
|
@@ -37,59 +41,149 @@ function resolveNode(resolve, a, env, graph, map) {
|
|
|
37
41
|
else if (a.type === type_1.RType.Logical) {
|
|
38
42
|
return a.content.valueOf() ? logical_constants_1.ValueLogicalTrue : logical_constants_1.ValueLogicalFalse;
|
|
39
43
|
}
|
|
40
|
-
else if (a.type === type_1.RType.FunctionCall
|
|
44
|
+
else if ((a.type === type_1.RType.FunctionCall || a.type === type_1.RType.BinaryOp || a.type === type_1.RType.UnaryOp) && graph) {
|
|
41
45
|
const origin = (0, dfg_get_origin_1.getOriginInDfg)(graph, a.info.id)?.[0];
|
|
42
46
|
if (origin === undefined || origin.type !== 3 /* OriginType.BuiltInFunctionOrigin */) {
|
|
43
|
-
return
|
|
47
|
+
return r_value_2.Top;
|
|
44
48
|
}
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
let builtInName;
|
|
50
|
+
if ((0, built_in_1.isBuiltIn)(origin.proc)) {
|
|
51
|
+
builtInName = origin.proc;
|
|
52
|
+
}
|
|
53
|
+
else if (a.type === type_1.RType.FunctionCall && a.named) {
|
|
54
|
+
builtInName = (0, built_in_1.builtInId)(a.functionName.content);
|
|
55
|
+
}
|
|
56
|
+
else if (a.type === type_1.RType.BinaryOp || a.type === type_1.RType.UnaryOp) {
|
|
57
|
+
builtInName = (0, built_in_1.builtInId)(a.operator);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
return r_value_2.Top;
|
|
61
|
+
}
|
|
62
|
+
if (Object.prototype.hasOwnProperty.call(built_in_1.BuiltInEvalHandlerMapper, builtInName)) {
|
|
63
|
+
const handler = built_in_1.BuiltInEvalHandlerMapper[builtInName];
|
|
47
64
|
return handler(resolve, a, env, graph, map);
|
|
48
65
|
}
|
|
49
66
|
}
|
|
50
|
-
return
|
|
67
|
+
return r_value_2.Top;
|
|
51
68
|
}
|
|
52
69
|
/**
|
|
53
70
|
* Helper function used by {@link resolveIdToValue}, please use that instead, if
|
|
54
71
|
* you want to resolve the value of an identifier / node
|
|
55
72
|
*
|
|
56
|
-
* This function
|
|
57
|
-
*
|
|
58
|
-
* order to construct the value of the vector to resolve by calling {@link resolveIdToValue}
|
|
59
|
-
* or {@link resolveNode}
|
|
73
|
+
* This function resolves a vector function call `c` to a {@link ValueVector}
|
|
74
|
+
* by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
|
|
60
75
|
*
|
|
61
|
-
* @param a - Node of the vector to resolve
|
|
62
|
-
* @param env - Environment to use
|
|
63
76
|
* @param resolve - Variable resolve mode
|
|
77
|
+
* @param node - Node of the vector function to resolve
|
|
78
|
+
* @param env - Environment to use
|
|
64
79
|
* @param graph - Dataflow graph
|
|
65
|
-
* @param map -
|
|
80
|
+
* @param map - Id map of the dataflow graph
|
|
66
81
|
* @returns ValueVector or Top
|
|
67
82
|
*/
|
|
68
|
-
function resolveAsVector(resolve,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
for (const arg of a.arguments) {
|
|
72
|
-
if (arg === r_function_call_1.EmptyArgument) {
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
if (arg.value === undefined) {
|
|
76
|
-
return r_value_1.Top;
|
|
77
|
-
}
|
|
78
|
-
if (arg.value.type === type_1.RType.Symbol) {
|
|
79
|
-
const value = (0, alias_tracking_1.resolveIdToValue)(arg.info.id, { environment: env, idMap: map, graph: graph, full: true, resolve });
|
|
80
|
-
if ((0, r_value_1.isTop)(value)) {
|
|
81
|
-
return r_value_1.Top;
|
|
82
|
-
}
|
|
83
|
-
values.push(value);
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
const val = resolveNode(resolve, arg.value, env, graph, map);
|
|
87
|
-
if ((0, r_value_1.isTop)(val)) {
|
|
88
|
-
return r_value_1.Top;
|
|
89
|
-
}
|
|
90
|
-
values.push(val);
|
|
91
|
-
}
|
|
83
|
+
function resolveAsVector(resolve, node, environment, graph, idMap) {
|
|
84
|
+
if (node.type !== type_1.RType.FunctionCall) {
|
|
85
|
+
return r_value_2.Top;
|
|
92
86
|
}
|
|
87
|
+
const resolveInfo = { environment, graph, idMap, full: true, resolve };
|
|
88
|
+
const values = node.arguments.map(arg => arg !== r_function_call_1.EmptyArgument ? (0, alias_tracking_1.resolveIdToValue)(arg.value, resolveInfo) : r_value_2.Top);
|
|
93
89
|
return (0, vector_constants_1.vectorFrom)((0, vector_constants_1.flattenVectorElements)(values));
|
|
94
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Helper function used by {@link resolveIdToValue}, please use that instead, if
|
|
93
|
+
* you want to resolve the value of an identifier / node
|
|
94
|
+
*
|
|
95
|
+
* This function resolves a binary sequence operator `:` to a {@link ValueVector} of {@link ValueNumber}s
|
|
96
|
+
* by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
|
|
97
|
+
*
|
|
98
|
+
* @param resolve - Variable resolve mode
|
|
99
|
+
* @param operator - Node of the sequence operator to resolve
|
|
100
|
+
* @param env - Environment to use
|
|
101
|
+
* @param graph - Dataflow graph
|
|
102
|
+
* @param map - Id map of the dataflow graph
|
|
103
|
+
* @returns ValueVector of ValueNumbers or Top
|
|
104
|
+
*/
|
|
105
|
+
function resolveAsSeq(resolve, operator, environment, graph, idMap) {
|
|
106
|
+
if (operator.type !== type_1.RType.BinaryOp) {
|
|
107
|
+
return r_value_2.Top;
|
|
108
|
+
}
|
|
109
|
+
const resolveInfo = { environment, graph, idMap, full: true, resolve };
|
|
110
|
+
const leftArg = (0, alias_tracking_1.resolveIdToValue)(operator.lhs, resolveInfo);
|
|
111
|
+
const rightArg = (0, alias_tracking_1.resolveIdToValue)(operator.rhs, resolveInfo);
|
|
112
|
+
const leftValue = (0, r_value_1.unliftRValue)(leftArg);
|
|
113
|
+
const rightValue = (0, r_value_1.unliftRValue)(rightArg);
|
|
114
|
+
if ((0, r_value_1.isRNumberValue)(leftValue) && (0, r_value_1.isRNumberValue)(rightValue)) {
|
|
115
|
+
return (0, vector_constants_1.vectorFrom)(createNumberSequence(leftValue, rightValue).map(scalar_consatnts_1.liftScalar));
|
|
116
|
+
}
|
|
117
|
+
return r_value_2.Top;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Helper function used by {@link resolveIdToValue}, please use that instead, if
|
|
121
|
+
* you want to resolve the value of an identifier / node
|
|
122
|
+
*
|
|
123
|
+
* This function resolves a unary plus operator `+` to a {@link ValueNumber} or {@link ValueVector} of ValueNumbers
|
|
124
|
+
* by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
|
|
125
|
+
*
|
|
126
|
+
* @param resolve - Variable resolve mode
|
|
127
|
+
* @param operator - Node of the plus operator to resolve
|
|
128
|
+
* @param env - Environment to use
|
|
129
|
+
* @param graph - Dataflow graph
|
|
130
|
+
* @param map - Id map of the dataflow graph
|
|
131
|
+
* @returns ValueNumber, ValueVector of ValueNumbers, or Top
|
|
132
|
+
*/
|
|
133
|
+
function resolveAsPlus(resolve, operator, environment, graph, idMap) {
|
|
134
|
+
if (operator.type !== type_1.RType.UnaryOp) {
|
|
135
|
+
return r_value_2.Top;
|
|
136
|
+
}
|
|
137
|
+
const resolveInfo = { environment, graph, idMap, full: true, resolve };
|
|
138
|
+
const arg = (0, alias_tracking_1.resolveIdToValue)(operator.operand, resolveInfo);
|
|
139
|
+
const argValue = (0, r_value_1.unliftRValue)(arg);
|
|
140
|
+
if ((0, r_value_1.isRNumberValue)(argValue)) {
|
|
141
|
+
return (0, scalar_consatnts_1.liftScalar)(argValue);
|
|
142
|
+
}
|
|
143
|
+
else if (Array.isArray(argValue) && argValue.every(r_value_1.isRNumberValue)) {
|
|
144
|
+
return (0, vector_constants_1.vectorFrom)(argValue.map(scalar_consatnts_1.liftScalar));
|
|
145
|
+
}
|
|
146
|
+
return r_value_2.Top;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Helper function used by {@link resolveIdToValue}, please use that instead, if
|
|
150
|
+
* you want to resolve the value of an identifier / node
|
|
151
|
+
*
|
|
152
|
+
* This function resolves a unary minus operator `-` to a {@link ValueNumber} or {@link ValueVector} of ValueNumbers
|
|
153
|
+
* by recursively resolving the values of the arguments by calling {@link resolveIdToValue}
|
|
154
|
+
*
|
|
155
|
+
* @param resolve - Variable resolve mode
|
|
156
|
+
* @param operator - Node of the minus operator to resolve
|
|
157
|
+
* @param env - Environment to use
|
|
158
|
+
* @param graph - Dataflow graph
|
|
159
|
+
* @param map - Id map of the dataflow graph
|
|
160
|
+
* @returns ValueNumber, ValueVector of ValueNumbers, or Top
|
|
161
|
+
*/
|
|
162
|
+
function resolveAsMinus(resolve, operator, environment, graph, idMap) {
|
|
163
|
+
if (operator.type !== type_1.RType.UnaryOp) {
|
|
164
|
+
return r_value_2.Top;
|
|
165
|
+
}
|
|
166
|
+
const resolveInfo = { environment, graph, idMap, full: true, resolve };
|
|
167
|
+
const arg = (0, alias_tracking_1.resolveIdToValue)(operator.operand, resolveInfo);
|
|
168
|
+
const argValue = (0, r_value_1.unliftRValue)(arg);
|
|
169
|
+
if ((0, r_value_1.isRNumberValue)(argValue)) {
|
|
170
|
+
return (0, scalar_consatnts_1.liftScalar)({ ...argValue, num: -argValue.num });
|
|
171
|
+
}
|
|
172
|
+
else if (Array.isArray(argValue) && argValue.every(r_value_1.isRNumberValue)) {
|
|
173
|
+
return (0, vector_constants_1.vectorFrom)(argValue.map(element => (0, scalar_consatnts_1.liftScalar)({ ...element, num: -element.num })));
|
|
174
|
+
}
|
|
175
|
+
return r_value_2.Top;
|
|
176
|
+
}
|
|
177
|
+
function createNumberSequence(start, end) {
|
|
178
|
+
const sequence = [];
|
|
179
|
+
const min = Math.min(start.num, end.num);
|
|
180
|
+
const max = Math.max(start.num, end.num);
|
|
181
|
+
for (let i = min; i <= max; i++) {
|
|
182
|
+
sequence.push({ ...start, num: i });
|
|
183
|
+
}
|
|
184
|
+
if (start > end) {
|
|
185
|
+
sequence.reverse();
|
|
186
|
+
}
|
|
187
|
+
return sequence;
|
|
188
|
+
}
|
|
95
189
|
//# sourceMappingURL=resolve.js.map
|
|
@@ -180,7 +180,7 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
|
|
|
180
180
|
fromId = from.nodeId;
|
|
181
181
|
}
|
|
182
182
|
else {
|
|
183
|
-
const result = (0, flowr_search_executor_1.runSearch)(from.query, data);
|
|
183
|
+
const result = (0, flowr_search_executor_1.runSearch)(from.query, data).getElements();
|
|
184
184
|
(0, assert_1.guard)(result.length === 1, `from query result should yield exactly one node, but yielded ${result.length}`);
|
|
185
185
|
fromId = result[0].node.info.id;
|
|
186
186
|
}
|
|
@@ -189,7 +189,7 @@ class DataflowGraphBuilder extends graph_1.DataflowGraph {
|
|
|
189
189
|
toIds = to.target;
|
|
190
190
|
}
|
|
191
191
|
else {
|
|
192
|
-
const result = (0, flowr_search_executor_1.runSearch)(to.query, data);
|
|
192
|
+
const result = (0, flowr_search_executor_1.runSearch)(to.query, data).getElements();
|
|
193
193
|
toIds = result.map(r => r.node.info.id);
|
|
194
194
|
}
|
|
195
195
|
return this.edgeHelper(fromId, toIds, type);
|
package/dataflow/graph/graph.js
CHANGED
|
@@ -376,7 +376,7 @@ function mergeNodeInfos(current, next) {
|
|
|
376
376
|
}
|
|
377
377
|
else if (current.tag === vertex_1.VertexType.FunctionDefinition) {
|
|
378
378
|
(0, assert_1.guard)(current.scope === next.scope, 'nodes to be joined for the same id must have the same scope');
|
|
379
|
-
|
|
379
|
+
current.exitPoints = (0, arrays_1.uniqueArrayMerge)(current.exitPoints, next.exitPoints);
|
|
380
380
|
}
|
|
381
381
|
return current;
|
|
382
382
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.invertDfg = invertDfg;
|
|
4
|
+
const graph_1 = require("./graph");
|
|
5
|
+
function invertDfg(graph) {
|
|
6
|
+
const invertedGraph = new graph_1.DataflowGraph(graph.idMap);
|
|
7
|
+
for (const [, v] of graph.vertices(true)) {
|
|
8
|
+
invertedGraph.addVertex(v);
|
|
9
|
+
}
|
|
10
|
+
for (const [from, targets] of graph.edges()) {
|
|
11
|
+
for (const [to, { types }] of targets) {
|
|
12
|
+
invertedGraph.addEdge(to, from, types);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return invertedGraph;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=invert-dfg.js.map
|
|
@@ -8,6 +8,7 @@ import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/
|
|
|
8
8
|
import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
9
9
|
import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
10
10
|
import type { NoInfo } from '../../../../../../r-bridge/lang-4.x/ast/model/model';
|
|
11
|
+
export declare function getSourceProvider(): RParseRequestProvider;
|
|
11
12
|
export declare function setSourceProvider(provider: RParseRequestProvider): void;
|
|
12
13
|
export declare function inferWdFromScript(option: InferWorkingDirectory, referenceChain: readonly RParseRequest[]): string[];
|
|
13
14
|
/**
|
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getSourceProvider = getSourceProvider;
|
|
6
7
|
exports.setSourceProvider = setSourceProvider;
|
|
7
8
|
exports.inferWdFromScript = inferWdFromScript;
|
|
8
9
|
exports.findSource = findSource;
|
|
@@ -30,6 +31,9 @@ const r_value_1 = require("../../../../../eval/values/r-value");
|
|
|
30
31
|
const unknown_side_effect_1 = require("../../../../../graph/unknown-side-effect");
|
|
31
32
|
const alias_tracking_1 = require("../../../../../eval/resolve/alias-tracking");
|
|
32
33
|
let sourceProvider = (0, retriever_1.requestProviderFromFile)();
|
|
34
|
+
function getSourceProvider() {
|
|
35
|
+
return sourceProvider;
|
|
36
|
+
}
|
|
33
37
|
function setSourceProvider(provider) {
|
|
34
38
|
sourceProvider = provider;
|
|
35
39
|
}
|
|
@@ -17,6 +17,7 @@ const doc_dfg_1 = require("./doc-dfg");
|
|
|
17
17
|
const doc_code_1 = require("./doc-code");
|
|
18
18
|
const time_1 = require("../../util/text/time");
|
|
19
19
|
const query_print_1 = require("../../queries/query-print");
|
|
20
|
+
const doc_cli_option_1 = require("./doc-cli-option");
|
|
20
21
|
const config_1 = require("../../config");
|
|
21
22
|
async function showQuery(shell, code, queries, { showCode, collapseResult, collapseQuery, addOutput = () => '' } = {}) {
|
|
22
23
|
const now = performance.now();
|
|
@@ -24,7 +25,7 @@ async function showQuery(shell, code, queries, { showCode, collapseResult, colla
|
|
|
24
25
|
parser: shell,
|
|
25
26
|
request: (0, retriever_1.requestFromInput)(code)
|
|
26
27
|
}, config_1.defaultConfigOptions).allRemainingSteps();
|
|
27
|
-
const results = (0, query_1.executeQueries)({ dataflow: analysis.dataflow, ast: analysis.normalize, config: config_1.defaultConfigOptions }, queries);
|
|
28
|
+
const results = await Promise.resolve((0, query_1.executeQueries)({ dataflow: analysis.dataflow, ast: analysis.normalize, config: config_1.defaultConfigOptions }, queries));
|
|
28
29
|
const duration = performance.now() - now;
|
|
29
30
|
const metaInfo = `
|
|
30
31
|
The analysis required _${(0, time_1.printAsMs)(duration)}_ (including parsing and normalization and the query) within the generation environment.
|
|
@@ -34,6 +35,15 @@ The analysis required _${(0, time_1.printAsMs)(duration)}_ (including parsing an
|
|
|
34
35
|
|
|
35
36
|
${(0, doc_code_1.codeBlock)('json', collapseQuery ? str.split('\n').join(' ').replace(/([{[])\s{2,}/g, '$1 ').replace(/\s{2,}([\]}])/g, ' $1') : str)}
|
|
36
37
|
|
|
38
|
+
${(function () {
|
|
39
|
+
if (queries.length === 1 && Object.keys(queries[0]).length === 1) {
|
|
40
|
+
return `(This query can be shortened to \`@${queries[0].type}\` when used within the REPL command ${(0, doc_cli_option_1.getReplCommand)('query')}).`;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return '';
|
|
44
|
+
}
|
|
45
|
+
})()}
|
|
46
|
+
|
|
37
47
|
${collapseResult ? ' <details> <summary style="color:gray">Show Results</summary>' : ''}
|
|
38
48
|
|
|
39
49
|
_Results (prettified and summarized):_
|
|
@@ -53,13 +53,13 @@ ${(0, doc_code_1.codeBlock)('json', JSON.stringify(search, null, 2))}
|
|
|
53
53
|
${collapseResult ? ' <details> <summary style="color:gray">Show Results</summary>' : ''}
|
|
54
54
|
|
|
55
55
|
The query returns the following vetices (all references to \`x\` in the code):
|
|
56
|
-
${result.map(({ node }) => `<b>${node.info.id} ('${(0, node_id_1.recoverContent)(node.info.id, analysis.dataflow.graph)}')</b> at L${(0, dfg_1.formatRange)(node.location)}`).join(', ')}
|
|
56
|
+
${result.getElements().map(({ node }) => `<b>${node.info.id} ('${(0, node_id_1.recoverContent)(node.info.id, analysis.dataflow.graph)}')</b> at L${(0, dfg_1.formatRange)(node.location)}`).join(', ')}
|
|
57
57
|
|
|
58
58
|
${metaInfo}
|
|
59
59
|
|
|
60
60
|
The returned results are highlighted thick and blue within the dataflow graph:
|
|
61
61
|
|
|
62
|
-
${await (0, doc_dfg_1.printDfGraphForCode)(shell, code, { showCode: false, switchCodeAndGraph: false, mark: new Set(result.map(({ node }) => node.info.id)) })}
|
|
62
|
+
${await (0, doc_dfg_1.printDfGraphForCode)(shell, code, { showCode: false, switchCodeAndGraph: false, mark: new Set(result.getElements().map(({ node }) => node.info.id)) })}
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
${collapseResult ? '</details>' : ''}
|
|
@@ -224,8 +224,7 @@ ${Object.entries(control_flow_graph_1.CfgVertexType).map(([key, value]) => `- \`
|
|
|
224
224
|
We use the ${(0, doc_types_1.shortLink)('CfgBasicBlockVertex', types.info)} to represent [basic blocks](#cfg-basic-blocks) and separate
|
|
225
225
|
expressions (${(0, doc_types_1.shortLink)('CfgExpressionVertex', types.info)}) and statements (${(0, doc_types_1.shortLink)('CfgStatementVertex', types.info)})
|
|
226
226
|
as control flow units with and without side effects (if you want to, you can see view statements as effectful expressions).
|
|
227
|
-
The markers (${(0, doc_types_1.shortLink)('
|
|
228
|
-
indicate specific segments of larger expressions/statements (e.g., an \`if\` which has a condition and its branches).
|
|
227
|
+
The markers (${(0, doc_types_1.shortLink)('CfgEndMarkerVertex', types.info)}) indicate the end of larger expressions/statements.
|
|
229
228
|
|
|
230
229
|
To signal these links, the expressions and statements contain information about the attached markers:
|
|
231
230
|
|
|
@@ -235,7 +234,7 @@ Similarly, the markers contain a link to their root:
|
|
|
235
234
|
|
|
236
235
|
${(0, doc_types_1.printHierarchy)({ info: types.info, root: 'CfgWithRoot', program: types.program, openTop: true })}
|
|
237
236
|
|
|
238
|
-
In mermaid visualizations, we use rectangles for statements, rounded rectangles for expressions
|
|
237
|
+
In mermaid visualizations, we use rectangles for statements, rounded rectangles for expressions and circles for exit markers.
|
|
239
238
|
Blocks are visualized as boxes around the contained vertices.
|
|
240
239
|
|
|
241
240
|
${(0, doc_structure_1.block)({
|
|
@@ -554,7 +553,7 @@ Hence, you may rely on the corresponding exit point(s) to identify all exits of
|
|
|
554
553
|
|
|
555
554
|
${(0, doc_structure_1.block)({
|
|
556
555
|
type: 'WARNING',
|
|
557
|
-
content: 'Using basic blocks, this works just the same. However please keep in mind that the corresponding exit markers do not (and for control statements usually will not) be part of the same basic block.'
|
|
556
|
+
content: 'Using basic blocks, this works just the same. However, please keep in mind that the corresponding exit markers do not (and for control statements usually will not) be part of the same basic block.'
|
|
558
557
|
})}
|
|
559
558
|
|
|
560
559
|
`;
|
|
@@ -28,7 +28,6 @@ const built_in_access_1 = require("../dataflow/internal/process/functions/call/b
|
|
|
28
28
|
const built_in_for_loop_1 = require("../dataflow/internal/process/functions/call/built-in/built-in-for-loop");
|
|
29
29
|
const built_in_repeat_loop_1 = require("../dataflow/internal/process/functions/call/built-in/built-in-repeat-loop");
|
|
30
30
|
const linker_1 = require("../dataflow/internal/linker");
|
|
31
|
-
const static_slicer_1 = require("../slicing/static/static-slicer");
|
|
32
31
|
const info_1 = require("../dataflow/info");
|
|
33
32
|
const processor_1 = require("../dataflow/processor");
|
|
34
33
|
const default_pipelines_1 = require("../core/steps/pipeline/default-pipelines");
|
|
@@ -42,6 +41,7 @@ const normalize_for_1 = require("../r-bridge/lang-4.x/ast/parser/main/internal/l
|
|
|
42
41
|
const doc_issue_1 = require("./doc-util/doc-issue");
|
|
43
42
|
const pipeline_executor_1 = require("../core/pipeline-executor");
|
|
44
43
|
const pipeline_1 = require("../core/steps/pipeline/pipeline");
|
|
44
|
+
const static_slicer_1 = require("../slicing/static/static-slicer");
|
|
45
45
|
const config_1 = require("../config");
|
|
46
46
|
async function getText(shell) {
|
|
47
47
|
const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
|
|
@@ -373,7 +373,7 @@ Of course, all of these endeavors work not just with the ${(0, doc_types_1.short
|
|
|
373
373
|
The slicing is available as an extra step as you can see by inspecting he ${(0, doc_types_1.shortLink)('DEFAULT_SLICING_PIPELINE', info)}.
|
|
374
374
|
Besides ${(0, doc_types_1.shortLink)('STATIC_SLICE', info)} it contains a ${(0, doc_types_1.shortLink)('NAIVE_RECONSTRUCT', info)} to print the slice as (executable) R code.
|
|
375
375
|
|
|
376
|
-
Your main point of interesting here is the ${(0, doc_types_1.shortLink)(static_slicer_1.
|
|
376
|
+
Your main point of interesting here is the ${(0, doc_types_1.shortLink)(static_slicer_1.staticSlice.name, info)} function which relies on a modified
|
|
377
377
|
breadth-first search to collect all nodes which are part of the slice.
|
|
378
378
|
For more information on how the slicing works, please refer to the [tool demonstration (Section 3.2)](https://doi.org/10.1145/3691620.3695359),
|
|
379
379
|
or the [original master's thesis (Chapter 4)](https://doi.org/10.18725/OPARU-50107).
|
|
@@ -835,6 +835,13 @@ The following sections present details on the different types of vertices and ed
|
|
|
835
835
|
${(0, doc_general_1.prefixLines)((0, doc_code_1.codeBlock)('ts', 'const node = graph.idMap.get(id);'), '> ')}
|
|
836
836
|
> In case you just need the name (\`lexeme\`) of the respective vertex, ${(0, doc_types_1.shortLink)(node_id_1.recoverName.name, vertexType.info)} can help you out:
|
|
837
837
|
${(0, doc_general_1.prefixLines)((0, doc_code_1.codeBlock)('ts', `const name = ${node_id_1.recoverName.name}(id, graph.idMap);`), '> ')}
|
|
838
|
+
>
|
|
839
|
+
> Please note that not every node in the normalized AST is represented in the dataflow graph.
|
|
840
|
+
> For example, if the node is unreachable in a way that can be detected during the analysis and flowR
|
|
841
|
+
> is configured to ignore dead code. Likewise, empty argument wrappers do not have a corresponding
|
|
842
|
+
> dataflow graph vertex (as they are not relevant for the dataflow graph). It depends on the scenario what to do in such a case.
|
|
843
|
+
> For argument wrappers you can access the dataflow information for their value. For dead code, however, flowR currently contains
|
|
844
|
+
> some core heuristics that remove it which cannot be reversed easily. So please open [an issue](${doc_issue_1.NewIssueUrl}) if you encounter such a case and require the node to be present in the dataflow graph.
|
|
838
845
|
|
|
839
846
|
${(0, doc_structure_1.section)('Vertices', 2, 'vertices')}
|
|
840
847
|
|
|
@@ -39,6 +39,10 @@ With \`npm\` you have to pass arguments in a specific way. The \`--\` operator i
|
|
|
39
39
|
${(0, doc_code_1.codeBlock)('shell', 'npm run flowR -- --help')}
|
|
40
40
|
`)}
|
|
41
41
|
|
|
42
|
+
${qAndA('How to do logging in flowR?', `
|
|
43
|
+
Check out the [Logging Section in the Linting and Testing wiki page](${doc_files_1.FlowrWikiBaseRef}/Linting-and-Testing#logging) for more information on how to do logging in *flowR*.
|
|
44
|
+
`)}
|
|
45
|
+
|
|
42
46
|
## 🇷 R FAQ
|
|
43
47
|
|
|
44
48
|
### 📦 R Packages
|
|
@@ -182,6 +182,7 @@ The following summarizes the configuration options:
|
|
|
182
182
|
- \`solver\`: allows to configure how _flowR_ resolves variables and their values (currently we support: ${Object.values(config_1.VariableResolve).map(v => `\`${v}\``).join(', ')}), as well as if pointer analysis should be active.
|
|
183
183
|
- \`engines\`: allows to configure the engines used by _flowR_ to interact with R code. See the [Engines wiki page](${doc_files_1.FlowrWikiBaseRef}/Engines) for more information.
|
|
184
184
|
- \`defaultEngine\`: allows to specify the default engine to use for interacting with R code. If not set, an arbitrary engine from the specified list will be used.
|
|
185
|
+
- \`abstractInterpretation\`: allows to configure how _flowR_ performs abstract interpretation, although we currently only support data frame shape inference through abstract interpretation.
|
|
185
186
|
|
|
186
187
|
So you can configure _flowR_ by adding a file like the following:
|
|
187
188
|
|
|
@@ -214,6 +215,16 @@ ${(0, doc_code_1.codeBlock)('json', JSON.stringify({
|
|
|
214
215
|
slicer: {
|
|
215
216
|
threshold: 50
|
|
216
217
|
}
|
|
218
|
+
},
|
|
219
|
+
abstractInterpretation: {
|
|
220
|
+
dataFrame: {
|
|
221
|
+
maxColNames: 20,
|
|
222
|
+
wideningThreshold: 4,
|
|
223
|
+
readLoadedData: {
|
|
224
|
+
readExternalFiles: true,
|
|
225
|
+
maxReadLines: 1_000_000
|
|
226
|
+
}
|
|
227
|
+
}
|
|
217
228
|
}
|
|
218
229
|
}, null, 2))}
|
|
219
230
|
|