@eagleoutice/flowr 2.2.12 → 2.2.13
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 +82 -20
- package/benchmark/slicer.js +2 -2
- package/benchmark/summarizer/first-phase/input.js +1 -1
- package/benchmark/summarizer/first-phase/process.js +3 -3
- package/benchmark/summarizer/second-phase/process.js +1 -1
- package/benchmark/summarizer/summarizer.js +1 -1
- package/cli/common/options.js +4 -4
- package/cli/common/script.js +1 -1
- package/cli/flowr.js +1 -1
- package/cli/repl/commands/repl-cfg.d.ts +2 -0
- package/cli/repl/commands/repl-cfg.js +38 -24
- package/cli/repl/commands/repl-commands.js +4 -2
- package/cli/repl/commands/repl-dataflow.js +3 -3
- package/cli/repl/commands/repl-execute.js +1 -1
- package/cli/repl/commands/repl-main.d.ts +1 -1
- package/cli/repl/commands/repl-main.js +1 -1
- package/cli/repl/commands/repl-normalize.js +1 -1
- package/cli/repl/commands/repl-query.js +2 -2
- package/cli/repl/core.js +1 -1
- package/cli/repl/prompt.js +1 -1
- package/cli/repl/server/connection.js +4 -4
- package/cli/repl/server/messages/message-analysis.d.ts +1 -1
- package/cli/script-core/statistics-core.js +1 -1
- package/cli/script-core/statistics-helper-core.js +4 -4
- package/config.d.ts +47 -24
- package/config.js +3 -3
- package/control-flow/basic-cfg-guided-visitor.d.ts +39 -0
- package/control-flow/basic-cfg-guided-visitor.js +114 -0
- package/control-flow/cfg-properties.d.ts +26 -0
- package/control-flow/cfg-properties.js +100 -0
- package/control-flow/cfg-simplification.d.ts +18 -0
- package/control-flow/cfg-simplification.js +55 -0
- package/control-flow/cfg-to-basic-blocks.d.ts +5 -0
- package/control-flow/cfg-to-basic-blocks.js +81 -0
- package/control-flow/control-flow-graph.d.ts +247 -0
- package/control-flow/control-flow-graph.js +290 -0
- package/control-flow/dfg-cfg-guided-visitor.d.ts +32 -0
- package/control-flow/dfg-cfg-guided-visitor.js +71 -0
- package/control-flow/diff-cfg.d.ts +11 -0
- package/control-flow/diff-cfg.js +161 -0
- package/control-flow/extract-cfg.d.ts +30 -0
- package/control-flow/extract-cfg.js +475 -0
- package/control-flow/happens-before.d.ts +7 -0
- package/{util/cfg → control-flow}/happens-before.js +3 -3
- package/control-flow/semantic-cfg-guided-visitor.d.ts +452 -0
- package/control-flow/semantic-cfg-guided-visitor.js +492 -0
- package/control-flow/simple-visitor.d.ts +25 -0
- package/control-flow/simple-visitor.js +80 -0
- package/control-flow/syntax-cfg-guided-visitor.d.ts +128 -0
- package/control-flow/syntax-cfg-guided-visitor.js +166 -0
- package/core/print/print.d.ts +1 -1
- package/core/print/slice-diff-ansi.js +1 -1
- package/core/steps/pipeline/create-pipeline.js +1 -1
- package/dataflow/environments/built-in-config.js +9 -6
- package/dataflow/environments/built-in.d.ts +8 -4
- package/dataflow/environments/built-in.js +47 -5
- package/dataflow/environments/default-builtin-config.d.ts +2 -0
- package/dataflow/environments/default-builtin-config.js +81 -14
- package/dataflow/environments/resolve-by-name.js +15 -4
- package/dataflow/extractor.js +2 -2
- package/dataflow/graph/dataflowgraph-builder.d.ts +3 -1
- package/dataflow/graph/dataflowgraph-builder.js +4 -2
- package/dataflow/graph/diff-dataflow-graph.d.ts +16 -0
- package/dataflow/graph/{diff.js → diff-dataflow-graph.js} +30 -56
- package/dataflow/graph/graph.d.ts +11 -3
- package/dataflow/graph/graph.js +27 -12
- package/dataflow/graph/vertex.d.ts +17 -2
- package/dataflow/internal/linker.d.ts +3 -2
- package/dataflow/internal/linker.js +33 -24
- package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +1 -1
- package/dataflow/internal/process/functions/call/argument/unpack-argument.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +12 -9
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +84 -16
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +23 -16
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +9 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +3 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +15 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-get.js +4 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +4 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-library.js +4 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-list.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +9 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +3 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +1 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +19 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +19 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.js +4 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +3 -3
- package/dataflow/internal/process/functions/call/common.d.ts +4 -1
- package/dataflow/internal/process/functions/call/common.js +5 -3
- package/dataflow/internal/process/functions/call/known-call-handling.d.ts +3 -2
- package/dataflow/internal/process/functions/call/known-call-handling.js +2 -1
- package/dataflow/internal/process/functions/call/named-call-handling.js +1 -1
- package/dataflow/internal/process/functions/call/unnamed-call-handling.d.ts +1 -0
- package/dataflow/internal/process/functions/call/unnamed-call-handling.js +6 -4
- package/dataflow/internal/process/process-named-call.d.ts +1 -1
- package/dataflow/internal/process/process-named-call.js +5 -5
- package/dataflow/origin/dfg-get-origin.d.ts +82 -0
- package/dataflow/origin/dfg-get-origin.js +116 -0
- package/documentation/doc-util/doc-cfg.d.ts +13 -6
- package/documentation/doc-util/doc-cfg.js +19 -14
- package/documentation/doc-util/doc-cli-option.js +4 -2
- package/documentation/doc-util/doc-dfg.js +3 -3
- package/documentation/doc-util/doc-escape.d.ts +7 -0
- package/documentation/doc-util/doc-escape.js +19 -0
- package/documentation/doc-util/doc-files.d.ts +1 -0
- package/documentation/doc-util/doc-files.js +2 -1
- package/documentation/doc-util/doc-normalized-ast.js +3 -3
- package/documentation/doc-util/doc-query.js +2 -2
- package/documentation/doc-util/doc-repl.js +1 -1
- package/documentation/doc-util/doc-search.js +1 -1
- package/documentation/doc-util/doc-server-message.js +2 -2
- package/documentation/doc-util/doc-structure.d.ts +1 -0
- package/documentation/doc-util/doc-structure.js +5 -0
- package/documentation/doc-util/doc-types.d.ts +7 -1
- package/documentation/doc-util/doc-types.js +13 -2
- package/documentation/print-capabilities-markdown.js +27 -1
- package/documentation/print-cfg-wiki.js +505 -17
- package/documentation/print-dataflow-graph-wiki.js +180 -25
- package/documentation/print-engines-wiki.js +1 -1
- package/documentation/print-faq-wiki.d.ts +1 -0
- package/documentation/print-faq-wiki.js +75 -0
- package/documentation/print-interface-wiki.js +1 -1
- package/documentation/print-linting-and-testing-wiki.js +52 -36
- package/documentation/print-normalized-ast-wiki.js +1 -1
- package/documentation/print-onboarding-wiki.d.ts +1 -0
- package/documentation/print-onboarding-wiki.js +42 -0
- package/documentation/print-query-wiki.js +21 -1
- package/documentation/print-readme.js +10 -3
- package/package.json +9 -6
- package/queries/catalog/call-context-query/call-context-query-executor.js +5 -5
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +1 -1
- package/queries/catalog/call-context-query/call-context-query-format.js +2 -2
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +2 -2
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +24 -21
- package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
- package/queries/catalog/cluster-query/cluster-query-format.js +1 -1
- package/queries/catalog/config-query/config-query-format.d.ts +1 -1
- package/queries/catalog/config-query/config-query-format.js +2 -2
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +2 -2
- package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
- package/queries/catalog/dataflow-query/dataflow-query-format.js +2 -2
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -2
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-format.js +2 -2
- package/queries/catalog/happens-before-query/happens-before-query-executor.d.ts +1 -1
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +4 -4
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
- package/queries/catalog/happens-before-query/happens-before-query-format.js +2 -2
- package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
- package/queries/catalog/id-map-query/id-map-query-format.js +2 -2
- package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -1
- package/queries/catalog/lineage-query/lineage-query-format.js +2 -2
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +1 -1
- package/queries/catalog/location-map-query/location-map-query-format.js +2 -2
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +2 -2
- package/queries/catalog/origin-query/origin-query-executor.d.ts +5 -0
- package/queries/catalog/origin-query/origin-query-executor.js +33 -0
- package/queries/catalog/origin-query/origin-query-format.d.ts +71 -0
- package/queries/catalog/origin-query/origin-query-format.js +27 -0
- package/queries/catalog/project-query/project-query-format.d.ts +1 -1
- package/queries/catalog/project-query/project-query-format.js +2 -2
- package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-format.js +2 -2
- package/queries/catalog/search-query/search-query-format.d.ts +1 -1
- package/queries/catalog/search-query/search-query-format.js +2 -2
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-format.js +2 -2
- package/queries/query-print.d.ts +1 -1
- package/queries/query-print.js +4 -4
- package/queries/query.d.ts +61 -2
- package/queries/query.js +3 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +3 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +5 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +3 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +5 -0
- package/r-bridge/lang-4.x/ast/model/processing/decorate.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/decorate.js +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/fold.js +3 -1
- package/r-bridge/lang-4.x/ast/model/processing/stateful-fold.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/expression/normalize-expression.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-argument.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-call.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-definition.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/normalize-access.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/operators/normalize-binary.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/structure/normalize-root.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/main/internal/values/normalize-symbol.js +1 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +2 -2
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +26 -8
- package/r-bridge/retriever.js +1 -1
- package/search/search-executor/search-generators.d.ts +1 -1
- package/search/search-executor/search-transformer.d.ts +1 -1
- package/slicing/criterion/collect-all.js +1 -1
- package/slicing/static/slice-call.js +13 -3
- package/statistics/features/supported/assignments/post-process.js +1 -1
- package/statistics/features/supported/defined-functions/post-process.js +2 -2
- package/statistics/features/supported/used-functions/post-process.js +1 -1
- package/statistics/features/supported/used-packages/post-process.js +2 -2
- package/statistics/features/supported/values/post-process.js +2 -2
- package/statistics/output/print-stats.js +2 -2
- package/statistics/summarizer/post-process/clusterer.d.ts +1 -1
- package/statistics/summarizer/post-process/clusterer.js +1 -1
- package/statistics/summarizer/post-process/histogram.js +3 -3
- package/statistics/summarizer/post-process/post-process-output.js +3 -3
- package/statistics/summarizer/second-phase/process.js +2 -2
- package/statistics/summarizer/summarizer.js +2 -2
- package/util/assert.js +36 -1
- package/util/cfg/cfg.d.ts +0 -80
- package/util/cfg/cfg.js +0 -549
- package/util/{arrays.d.ts → collections/arrays.d.ts} +1 -1
- package/util/{arrays.js → collections/arrays.js} +3 -3
- package/util/collections/set.js +17 -0
- package/util/diff-graph.d.ts +47 -0
- package/util/diff-graph.js +61 -0
- package/util/diff.d.ts +6 -6
- package/util/diff.js +1 -1
- package/util/mermaid/cfg.d.ts +9 -2
- package/util/mermaid/cfg.js +64 -12
- package/util/mermaid/dfg.d.ts +2 -1
- package/util/mermaid/dfg.js +26 -10
- package/util/mermaid/mermaid.d.ts +2 -0
- package/util/mermaid/mermaid.js +6 -0
- package/util/quads.js +1 -1
- package/util/schema.d.ts +1 -1
- package/util/schema.js +1 -1
- package/util/summarizer.js +1 -1
- package/util/{text.js → text/text.js} +1 -1
- package/util/{time.js → text/time.js} +1 -1
- package/util/version.js +1 -1
- package/dataflow/graph/diff.d.ts +0 -36
- package/util/cfg/happens-before.d.ts +0 -7
- package/util/cfg/visitor.d.ts +0 -9
- package/util/cfg/visitor.js +0 -30
- package/util/set.js +0 -31
- /package/util/{bimap.d.ts → collections/bimap.d.ts} +0 -0
- /package/util/{bimap.js → collections/bimap.js} +0 -0
- /package/util/{defaultmap.d.ts → collections/defaultmap.d.ts} +0 -0
- /package/util/{defaultmap.js → collections/defaultmap.js} +0 -0
- /package/util/{set.d.ts → collections/set.d.ts} +0 -0
- /package/util/{ansi.d.ts → text/ansi.d.ts} +0 -0
- /package/util/{ansi.js → text/ansi.js} +0 -0
- /package/util/{args.d.ts → text/args.d.ts} +0 -0
- /package/util/{args.js → text/args.js} +0 -0
- /package/util/{strings.d.ts → text/strings.d.ts} +0 -0
- /package/util/{strings.js → text/strings.js} +0 -0
- /package/util/{text.d.ts → text/text.d.ts} +0 -0
- /package/util/{time.d.ts → text/time.d.ts} +0 -0
|
@@ -42,6 +42,9 @@ function linkReadNameToWriteIfPossible(read, environments, listEnvironments, rem
|
|
|
42
42
|
for (const target of probableTarget) {
|
|
43
43
|
// we can stick with maybe even if readId.attribute is always
|
|
44
44
|
nextGraph.addEdge(read, target, edge_1.EdgeType.Reads);
|
|
45
|
+
if ((read.type === identifier_1.ReferenceType.Function || read.type === identifier_1.ReferenceType.BuiltInFunction) && ((0, built_in_1.isBuiltIn)(target.definedAt))) {
|
|
46
|
+
nextGraph.addEdge(read, target, edge_1.EdgeType.Calls);
|
|
47
|
+
}
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
50
|
function processNextExpression(currentElement, environment, listEnvironments, remainingRead, nextGraph) {
|
|
@@ -66,7 +69,7 @@ function updateSideEffectsForCalledFunctions(calledEnvs, inputEnvironment, nextG
|
|
|
66
69
|
while (current !== undefined && current.id !== environment_1.BuiltInEnvironment.id) {
|
|
67
70
|
for (const definitions of current.memory.values()) {
|
|
68
71
|
for (const def of definitions) {
|
|
69
|
-
if (
|
|
72
|
+
if (!(0, built_in_1.isBuiltIn)(def.definedAt)) {
|
|
70
73
|
hasUpdate = true;
|
|
71
74
|
nextGraph.addEdge(def.nodeId, functionCall, edge_1.EdgeType.SideEffectOnCall);
|
|
72
75
|
}
|
|
@@ -90,7 +93,7 @@ function processExpressionList(name, args, rootId, data) {
|
|
|
90
93
|
const listEnvironments = new Set();
|
|
91
94
|
const remainingRead = new Map();
|
|
92
95
|
const nextGraph = new graph_1.DataflowGraph(data.completeAst.idMap);
|
|
93
|
-
|
|
96
|
+
let out = [];
|
|
94
97
|
const exitPoints = [];
|
|
95
98
|
let expressionCounter = 0;
|
|
96
99
|
const processedExpressions = [];
|
|
@@ -115,7 +118,7 @@ function processExpressionList(name, args, rootId, data) {
|
|
|
115
118
|
processed.unknownReferences = (0, environment_1.makeAllMaybe)(processed.unknownReferences, nextGraph, processed.environment, false);
|
|
116
119
|
}
|
|
117
120
|
(0, info_1.addNonDefaultExitPoints)(exitPoints, processed.exitPoints);
|
|
118
|
-
out.
|
|
121
|
+
out = out.concat(processed.out);
|
|
119
122
|
(0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `expression ${expressionCounter} of ${expressions.length} has ${processed.unknownReferences.length} unknown nodes`);
|
|
120
123
|
processNextExpression(processed, environment, listEnvironments, remainingRead, nextGraph);
|
|
121
124
|
environment = exitPoints.length > 0 ? (0, overwrite_1.overwriteEnvironment)(environment, processed.environment) : processed.environment;
|
|
@@ -150,8 +153,10 @@ function processExpressionList(name, args, rootId, data) {
|
|
|
150
153
|
rootId,
|
|
151
154
|
name,
|
|
152
155
|
data,
|
|
153
|
-
argumentProcessResult: processedExpressions
|
|
156
|
+
argumentProcessResult: processedExpressions,
|
|
157
|
+
origin: 'builtin:expression-list'
|
|
154
158
|
});
|
|
159
|
+
nextGraph.addEdge(rootId, (0, built_in_1.builtInId)('{'), edge_1.EdgeType.Reads | edge_1.EdgeType.Calls);
|
|
155
160
|
// process all exit points as potential returns:
|
|
156
161
|
for (const exit of exitPoints) {
|
|
157
162
|
if (exit.type === 1 /* ExitPointType.Return */ || exit.type === 0 /* ExitPointType.Default */) {
|
|
@@ -18,7 +18,7 @@ const identifier_1 = require("../../../../../environments/identifier");
|
|
|
18
18
|
function processForLoop(name, args, rootId, data) {
|
|
19
19
|
if (args.length !== 3) {
|
|
20
20
|
logger_1.dataflowLogger.warn(`For-Loop ${name.content} does not have three arguments, skipping`);
|
|
21
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
21
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
22
22
|
}
|
|
23
23
|
const [variableArg, vectorArg, bodyArg] = args.map(e => (0, unpack_argument_1.unpackArgument)(e));
|
|
24
24
|
(0, assert_1.guard)(variableArg !== undefined && vectorArg !== undefined && bodyArg !== undefined, () => `For-Loop ${JSON.stringify(args)} has missing arguments! Bad!`);
|
|
@@ -55,7 +55,8 @@ function processForLoop(name, args, rootId, data) {
|
|
|
55
55
|
rootId,
|
|
56
56
|
name,
|
|
57
57
|
data: { ...data, controlDependencies: originalDependency },
|
|
58
|
-
argumentProcessResult: [variable, vector, body]
|
|
58
|
+
argumentProcessResult: [variable, vector, body],
|
|
59
|
+
origin: 'builtin:for-loop'
|
|
59
60
|
});
|
|
60
61
|
/* mark the last argument as nse */
|
|
61
62
|
nextGraph.addEdge(rootId, body.entryPoint, edge_1.EdgeType.NonStandardEvaluation);
|
|
@@ -12,6 +12,7 @@ const assert_1 = require("../../../../../../util/assert");
|
|
|
12
12
|
const logger_1 = require("../../../../../logger");
|
|
13
13
|
const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
14
14
|
const graph_1 = require("../../../../../graph/graph");
|
|
15
|
+
const identifier_1 = require("../../../../../environments/identifier");
|
|
15
16
|
const overwrite_1 = require("../../../../../environments/overwrite");
|
|
16
17
|
const vertex_1 = require("../../../../../graph/vertex");
|
|
17
18
|
const scoping_1 = require("../../../../../environments/scoping");
|
|
@@ -19,10 +20,11 @@ const environment_1 = require("../../../../../environments/environment");
|
|
|
19
20
|
const resolve_by_name_1 = require("../../../../../environments/resolve-by-name");
|
|
20
21
|
const edge_1 = require("../../../../../graph/edge");
|
|
21
22
|
const log_1 = require("../../../../../../util/log");
|
|
23
|
+
const built_in_1 = require("../../../../../environments/built-in");
|
|
22
24
|
function processFunctionDefinition(name, args, rootId, data) {
|
|
23
25
|
if (args.length < 1) {
|
|
24
26
|
logger_1.dataflowLogger.warn(`Function Definition ${name.content} does not have an argument, skipping`);
|
|
25
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
27
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
26
28
|
}
|
|
27
29
|
/* we remove the last argument, as it is the body */
|
|
28
30
|
const parameters = args.slice(0, -1);
|
|
@@ -140,8 +142,15 @@ function updateNestedFunctionClosures(graph, outEnvironment, fnId) {
|
|
|
140
142
|
continue;
|
|
141
143
|
}
|
|
142
144
|
(0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Found ${resolved.length} references to open ref ${id} in closure of function definition ${fnId}`);
|
|
145
|
+
let allBuiltIn = true;
|
|
143
146
|
for (const ref of resolved) {
|
|
144
147
|
graph.addEdge(ingoing, ref, edge_1.EdgeType.Reads);
|
|
148
|
+
if (!(0, identifier_1.isReferenceType)(ref.type, identifier_1.ReferenceType.BuiltInConstant | identifier_1.ReferenceType.BuiltInFunction)) {
|
|
149
|
+
allBuiltIn = false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (allBuiltIn) {
|
|
153
|
+
remainingIn.push(ingoing);
|
|
145
154
|
}
|
|
146
155
|
}
|
|
147
156
|
(0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Keeping ${remainingIn.length} references to open ref ${id} in closure of function definition ${fnId}`);
|
|
@@ -191,8 +200,10 @@ function updateNestedFunctionCalls(graph, outEnvironment) {
|
|
|
191
200
|
}
|
|
192
201
|
(0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Found ${resolved.length} references to open ref ${id} in closure of function definition ${id}`);
|
|
193
202
|
for (const def of resolved) {
|
|
194
|
-
|
|
195
|
-
|
|
203
|
+
if (!(0, built_in_1.isBuiltIn)(def.nodeId)) {
|
|
204
|
+
graph.addEdge(ingoing, def, edge_1.EdgeType.DefinedByOnCall);
|
|
205
|
+
graph.addEdge(id, def, edge_1.EdgeType.DefinesOnCall);
|
|
206
|
+
}
|
|
196
207
|
}
|
|
197
208
|
}
|
|
198
209
|
(0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Keeping ${remainingIn.length} references to open ref ${id} in closure of function definition ${id}`);
|
|
@@ -209,7 +220,7 @@ function prepareFunctionEnvironment(data) {
|
|
|
209
220
|
}
|
|
210
221
|
/**
|
|
211
222
|
* Within something like `f <- function(a=b, m=3) { b <- 1; a; b <- 5; a + 1 }`
|
|
212
|
-
* `a` will be defined by `b` and `b`will be a promise object bound by the first definition of b it can find.
|
|
223
|
+
* `a` will be defined by `b` and `b` will be a promise object bound by the first definition of b it can find.
|
|
213
224
|
* This means that this function returns `2` due to the first `b <- 1` definition.
|
|
214
225
|
* If the code is `f <- function(a=b, m=3) { if(m > 3) { b <- 1; }; a; b <- 5; a + 1 }`, we need a link to `b <- 1` and `b <- 6`
|
|
215
226
|
* as `b` can be defined by either one of them.
|
|
@@ -11,12 +11,12 @@ const edge_1 = require("../../../../../graph/edge");
|
|
|
11
11
|
function processGet(name, args, rootId, data) {
|
|
12
12
|
if (args.length !== 1) {
|
|
13
13
|
logger_1.dataflowLogger.warn(`symbol access with ${name.content} has not 1 argument, skipping`);
|
|
14
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
14
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
15
15
|
}
|
|
16
16
|
const retrieve = (0, unpack_argument_1.unpackArgument)(args[0]);
|
|
17
17
|
if (retrieve === undefined || retrieve.type !== type_1.RType.String) {
|
|
18
18
|
logger_1.dataflowLogger.warn(`symbol access with ${name.content} has not 1 argument, skipping`);
|
|
19
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
19
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
20
20
|
}
|
|
21
21
|
const treatTargetAsSymbol = {
|
|
22
22
|
type: type_1.RType.Symbol,
|
|
@@ -30,7 +30,8 @@ function processGet(name, args, rootId, data) {
|
|
|
30
30
|
name,
|
|
31
31
|
args: (0, make_argument_1.wrapArgumentsUnnamed)([treatTargetAsSymbol], data.completeAst.idMap),
|
|
32
32
|
rootId,
|
|
33
|
-
data
|
|
33
|
+
data,
|
|
34
|
+
origin: 'builtin:get'
|
|
34
35
|
});
|
|
35
36
|
const firstArg = processedArguments[0];
|
|
36
37
|
if (firstArg) {
|
|
@@ -15,12 +15,12 @@ const environment_1 = require("../../../../../environments/environment");
|
|
|
15
15
|
function processIfThenElse(name, args, rootId, data) {
|
|
16
16
|
if (args.length !== 2 && args.length !== 3) {
|
|
17
17
|
logger_1.dataflowLogger.warn(`If-then-else ${name.content} has something different from 2 or 3 arguments, skipping`);
|
|
18
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
18
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
19
19
|
}
|
|
20
20
|
const [condArg, thenArg, otherwiseArg] = args.map(e => (0, unpack_argument_1.unpackArgument)(e));
|
|
21
21
|
if (condArg === undefined || thenArg === undefined) {
|
|
22
22
|
logger_1.dataflowLogger.warn(`If-then-else ${name.content} has empty condition or then case in ${JSON.stringify(args)}, skipping`);
|
|
23
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
23
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
24
24
|
}
|
|
25
25
|
const cond = (0, processor_1.processDataflowFor)(condArg, data);
|
|
26
26
|
if ((0, info_1.alwaysExits)(cond)) {
|
|
@@ -92,7 +92,8 @@ function processIfThenElse(name, args, rootId, data) {
|
|
|
92
92
|
rootId,
|
|
93
93
|
name,
|
|
94
94
|
data: { ...data, controlDependencies: originalDependency },
|
|
95
|
-
argumentProcessResult: [cond, then, otherwise]
|
|
95
|
+
argumentProcessResult: [cond, then, otherwise],
|
|
96
|
+
origin: 'builtin:if-then-else'
|
|
96
97
|
});
|
|
97
98
|
// as an if always evaluates its condition, we add a 'reads'-edge
|
|
98
99
|
nextGraph.addEdge(name.info.id, cond.entryPoint, edge_1.EdgeType.Reads);
|
|
@@ -10,12 +10,12 @@ function processLibrary(name, args, rootId, data) {
|
|
|
10
10
|
/* we do not really know what loading the library does and what side effects it causes, hence we mark it as an unknown side effect */
|
|
11
11
|
if (args.length !== 1) {
|
|
12
12
|
logger_1.dataflowLogger.warn(`Currently only one-arg library-likes are allows (for ${name.content}), skipping`);
|
|
13
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, hasUnknownSideEffect: true }).information;
|
|
13
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, hasUnknownSideEffect: true, origin: 'default' }).information;
|
|
14
14
|
}
|
|
15
15
|
const nameToLoad = (0, unpack_argument_1.unpackArgument)(args[0]);
|
|
16
16
|
if (nameToLoad === undefined || nameToLoad.type !== type_1.RType.Symbol) {
|
|
17
17
|
logger_1.dataflowLogger.warn('No library name provided, skipping');
|
|
18
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, hasUnknownSideEffect: true }).information;
|
|
18
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, hasUnknownSideEffect: true, origin: 'default' }).information;
|
|
19
19
|
}
|
|
20
20
|
// treat as a function call but convert the first argument to a string
|
|
21
21
|
const newArg = {
|
|
@@ -30,7 +30,8 @@ function processLibrary(name, args, rootId, data) {
|
|
|
30
30
|
};
|
|
31
31
|
return (0, known_call_handling_1.processKnownFunctionCall)({
|
|
32
32
|
name, args: (0, make_argument_1.wrapArgumentsUnnamed)([newArg], data.completeAst.idMap), rootId, data,
|
|
33
|
-
hasUnknownSideEffect: true
|
|
33
|
+
hasUnknownSideEffect: true,
|
|
34
|
+
origin: 'builtin:library'
|
|
34
35
|
}).information;
|
|
35
36
|
}
|
|
36
37
|
//# sourceMappingURL=built-in-library.js.map
|
|
@@ -15,7 +15,7 @@ const containers_1 = require("../../../../../../util/containers");
|
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
function processList(name, args, rootId, data) {
|
|
18
|
-
const fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data });
|
|
18
|
+
const fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'builtin:list' });
|
|
19
19
|
if (!(0, config_1.getConfig)().solver.pointerTracking) {
|
|
20
20
|
return fnCall.information;
|
|
21
21
|
}
|
|
@@ -10,7 +10,7 @@ const vertex_1 = require("../../../../../graph/vertex");
|
|
|
10
10
|
const edge_1 = require("../../../../../graph/edge");
|
|
11
11
|
const identifier_1 = require("../../../../../environments/identifier");
|
|
12
12
|
function processPipe(name, args, rootId, data) {
|
|
13
|
-
const { information, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data });
|
|
13
|
+
const { information, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'builtin:pipe' });
|
|
14
14
|
if (args.length !== 2) {
|
|
15
15
|
logger_1.dataflowLogger.warn(`Pipe ${name.content} has something else than 2 arguments, skipping`);
|
|
16
16
|
return information;
|
|
@@ -4,16 +4,17 @@ exports.processQuote = processQuote;
|
|
|
4
4
|
const known_call_handling_1 = require("../known-call-handling");
|
|
5
5
|
const edge_1 = require("../../../../../graph/edge");
|
|
6
6
|
function processQuote(name, args, rootId, data, config) {
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
const startEnv = data.environment;
|
|
8
|
+
const { information, processedArguments, fnRef } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs, origin: 'builtin:quote' });
|
|
9
|
+
let inRefs = [fnRef];
|
|
10
|
+
let outRefs = [];
|
|
11
|
+
let unknownRefs = [];
|
|
11
12
|
for (let i = 0; i < args.length; i++) {
|
|
12
13
|
const processedArg = processedArguments[i];
|
|
13
14
|
if (processedArg && i !== config?.quoteArgumentsWithIndex) {
|
|
14
|
-
inRefs.
|
|
15
|
-
outRefs.
|
|
16
|
-
unknownRefs.
|
|
15
|
+
inRefs = inRefs.concat(processedArg.in);
|
|
16
|
+
outRefs = outRefs.concat(processedArg.out);
|
|
17
|
+
unknownRefs = unknownRefs.concat(processedArg.unknownReferences);
|
|
17
18
|
}
|
|
18
19
|
else if (processedArg) {
|
|
19
20
|
information.graph.addEdge(rootId, processedArg.entryPoint, edge_1.EdgeType.NonStandardEvaluation);
|
|
@@ -25,6 +26,7 @@ function processQuote(name, args, rootId, data, config) {
|
|
|
25
26
|
}
|
|
26
27
|
return {
|
|
27
28
|
...information,
|
|
29
|
+
environment: startEnv,
|
|
28
30
|
in: inRefs,
|
|
29
31
|
out: outRefs,
|
|
30
32
|
unknownReferences: unknownRefs
|
|
@@ -11,7 +11,7 @@ const logger_1 = require("../../../../../logger");
|
|
|
11
11
|
function processRepeatLoop(name, args, rootId, data) {
|
|
12
12
|
if (args.length !== 1 || args[0] === r_function_call_1.EmptyArgument) {
|
|
13
13
|
logger_1.dataflowLogger.warn(`Repeat-Loop ${name.content} does not have 1 argument, skipping`);
|
|
14
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
14
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
15
15
|
}
|
|
16
16
|
const unpacked = (0, unpack_argument_1.unpackArgument)(args[0]);
|
|
17
17
|
const { information, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({
|
|
@@ -25,7 +25,8 @@ function processRepeatLoop(name, args, rootId, data) {
|
|
|
25
25
|
}
|
|
26
26
|
return d;
|
|
27
27
|
},
|
|
28
|
-
markAsNSE: [0]
|
|
28
|
+
markAsNSE: [0],
|
|
29
|
+
origin: 'builtin:repeat-loop'
|
|
29
30
|
});
|
|
30
31
|
const body = processedArguments[0];
|
|
31
32
|
(0, assert_1.guard)(body !== undefined, () => `Repeat-Loop ${name.content} has no body, impossible!`);
|
|
@@ -4,10 +4,10 @@ exports.processReplacementFunction = processReplacementFunction;
|
|
|
4
4
|
const info_1 = require("../../../../../info");
|
|
5
5
|
const known_call_handling_1 = require("../known-call-handling");
|
|
6
6
|
const log_1 = require("../../../../../../util/log");
|
|
7
|
-
const built_in_assignment_1 = require("./built-in-assignment");
|
|
8
7
|
const common_1 = require("../common");
|
|
9
8
|
const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
10
9
|
const logger_1 = require("../../../../../logger");
|
|
10
|
+
const vertex_1 = require("../../../../../graph/vertex");
|
|
11
11
|
const graph_1 = require("../../../../../graph/graph");
|
|
12
12
|
const edge_1 = require("../../../../../graph/edge");
|
|
13
13
|
const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
|
|
@@ -15,12 +15,14 @@ const containers_1 = require("../../../../../../util/containers");
|
|
|
15
15
|
const config_1 = require("../../../../../../config");
|
|
16
16
|
const unpack_argument_1 = require("../argument/unpack-argument");
|
|
17
17
|
const built_in_access_1 = require("./built-in-access");
|
|
18
|
+
const built_in_1 = require("../../../../../environments/built-in");
|
|
19
|
+
const identifier_1 = require("../../../../../environments/identifier");
|
|
18
20
|
function processReplacementFunction(name,
|
|
19
21
|
/** The last one has to be the value */
|
|
20
22
|
args, rootId, data, config) {
|
|
21
23
|
if (args.length < 2) {
|
|
22
24
|
logger_1.dataflowLogger.warn(`Replacement ${name.content} has less than 2 arguments, skipping`);
|
|
23
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
25
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
24
26
|
}
|
|
25
27
|
/* we only get here if <-, <<-, ... or whatever is part of the replacement is not overwritten */
|
|
26
28
|
(0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Replacement ${name.content} with ${JSON.stringify(args)}, processing`);
|
|
@@ -29,12 +31,16 @@ args, rootId, data, config) {
|
|
|
29
31
|
indices ??= constructAccessedIndices(name.content, args);
|
|
30
32
|
}
|
|
31
33
|
/* we assign the first argument by the last for now and maybe mark as maybe!, we can keep the symbol as we now know we have an assignment */
|
|
32
|
-
|
|
34
|
+
let res = built_in_1.BuiltInProcessorMapper['builtin:assignment'](name, [args[0], args[args.length - 1]], rootId, data, {
|
|
33
35
|
superAssignment: config.assignmentOperator === '<<-',
|
|
34
36
|
makeMaybe: indices !== undefined ? false : config.makeMaybe,
|
|
35
37
|
indicesCollection: indices,
|
|
36
38
|
canBeReplacement: true
|
|
37
39
|
});
|
|
40
|
+
const createdVert = res.graph.getVertex(rootId);
|
|
41
|
+
if (createdVert?.tag === vertex_1.VertexType.FunctionCall) {
|
|
42
|
+
createdVert.origin = ['builtin:replacement'];
|
|
43
|
+
}
|
|
38
44
|
const convertedArgs = config.readIndices ? args.slice(1, -1) : (0, built_in_access_1.symbolArgumentsToStrings)(args.slice(1, -1), 0);
|
|
39
45
|
/* now, we soft-inject other arguments, so that calls like `x[y] <- 3` are linked correctly */
|
|
40
46
|
const { callArgs } = (0, common_1.processAllArguments)({
|
|
@@ -50,7 +56,9 @@ args, rootId, data, config) {
|
|
|
50
56
|
data,
|
|
51
57
|
rootId,
|
|
52
58
|
name,
|
|
53
|
-
argumentProcessResult: args.map(a => a === r_function_call_1.EmptyArgument ? undefined : { entryPoint: (0, unpack_argument_1.unpackArgument)(a)?.info.id })
|
|
59
|
+
argumentProcessResult: args.map(a => a === r_function_call_1.EmptyArgument ? undefined : { entryPoint: (0, unpack_argument_1.unpackArgument)(a)?.info.id }),
|
|
60
|
+
origin: 'builtin:replacement',
|
|
61
|
+
link: config.assignRootId ? { origin: [config.assignRootId] } : undefined
|
|
54
62
|
});
|
|
55
63
|
const firstArg = (0, unpack_argument_1.unpackArgument)(args[0])?.info.id;
|
|
56
64
|
if (firstArg) {
|
|
@@ -63,6 +71,13 @@ args, rootId, data, config) {
|
|
|
63
71
|
res.graph.addEdge(rootId, ref, edge_1.EdgeType.Reads);
|
|
64
72
|
}
|
|
65
73
|
}
|
|
74
|
+
const fa = (0, unpack_argument_1.unpackArgument)(args[0]);
|
|
75
|
+
if (!(0, config_1.getConfig)().solver.pointerTracking && fa) {
|
|
76
|
+
res = {
|
|
77
|
+
...res,
|
|
78
|
+
in: [...res.in, { name: fa.lexeme, type: identifier_1.ReferenceType.Variable, nodeId: fa.info.id, controlDependencies: data.controlDependencies }]
|
|
79
|
+
};
|
|
80
|
+
}
|
|
66
81
|
return res;
|
|
67
82
|
}
|
|
68
83
|
/**
|
|
@@ -9,9 +9,9 @@ const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
|
|
|
9
9
|
function processRm(name, args, rootId, data) {
|
|
10
10
|
if (args.length === 0) {
|
|
11
11
|
logger_1.dataflowLogger.warn('empty rm, skipping');
|
|
12
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
12
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
13
13
|
}
|
|
14
|
-
const res = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
14
|
+
const res = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'builtin:rm' }).information;
|
|
15
15
|
const names = [];
|
|
16
16
|
for (const arg of args) {
|
|
17
17
|
if (arg === r_function_call_1.EmptyArgument) {
|
|
@@ -55,6 +55,14 @@ function platformDirname(p) {
|
|
|
55
55
|
function returnPlatformPath(p) {
|
|
56
56
|
return p.replaceAll(AnyPathSeparator, path_1.default.sep);
|
|
57
57
|
}
|
|
58
|
+
function applyReplacements(path, replacements) {
|
|
59
|
+
const results = [];
|
|
60
|
+
for (const replacement of replacements) {
|
|
61
|
+
const newPath = Object.entries(replacement).reduce((acc, [key, value]) => acc.replace(new RegExp(key, 'g'), value), path);
|
|
62
|
+
results.push(newPath);
|
|
63
|
+
}
|
|
64
|
+
return results;
|
|
65
|
+
}
|
|
58
66
|
/**
|
|
59
67
|
* Tries to find sourced by a source request and returns the first path that exists
|
|
60
68
|
* @param seed - the path originally requested in the `source` call
|
|
@@ -67,7 +75,7 @@ function findSource(seed, data) {
|
|
|
67
75
|
...(config?.searchPath ?? []),
|
|
68
76
|
...(inferWdFromScript(config?.inferWorkingDirectory ?? config_1.InferWorkingDirectory.No, data.referenceChain))
|
|
69
77
|
];
|
|
70
|
-
|
|
78
|
+
let tryPaths = [seed];
|
|
71
79
|
switch (config?.dropPaths ?? config_1.DropPathsOption.No) {
|
|
72
80
|
case config_1.DropPathsOption.Once: {
|
|
73
81
|
const first = platformBasename(seed);
|
|
@@ -77,6 +85,7 @@ function findSource(seed, data) {
|
|
|
77
85
|
case config_1.DropPathsOption.All: {
|
|
78
86
|
const paths = platformDirname(seed).split(AnyPathSeparator);
|
|
79
87
|
const basename = platformBasename(seed);
|
|
88
|
+
tryPaths.push(basename);
|
|
80
89
|
if (paths.length === 1 && paths[0] === '.') {
|
|
81
90
|
break;
|
|
82
91
|
}
|
|
@@ -89,6 +98,10 @@ function findSource(seed, data) {
|
|
|
89
98
|
case config_1.DropPathsOption.No:
|
|
90
99
|
break;
|
|
91
100
|
}
|
|
101
|
+
if (config?.applyReplacements) {
|
|
102
|
+
const r = config.applyReplacements;
|
|
103
|
+
tryPaths = tryPaths.flatMap(t => applyReplacements(t, r));
|
|
104
|
+
}
|
|
92
105
|
const found = [];
|
|
93
106
|
for (const explore of [undefined, ...explorePaths]) {
|
|
94
107
|
for (const tryPath of tryPaths) {
|
|
@@ -99,16 +112,18 @@ function findSource(seed, data) {
|
|
|
99
112
|
}
|
|
100
113
|
}
|
|
101
114
|
}
|
|
102
|
-
log_1.log.
|
|
115
|
+
if (log_1.log.settings.minLevel >= 3 /* LogLevel.Info */) {
|
|
116
|
+
log_1.log.info(`Found sourced file ${JSON.stringify(seed)} at ${JSON.stringify(found)}`);
|
|
117
|
+
}
|
|
103
118
|
return found;
|
|
104
119
|
}
|
|
105
120
|
function processSourceCall(name, args, rootId, data, config) {
|
|
106
121
|
if (args.length !== 1) {
|
|
107
122
|
logger_1.dataflowLogger.warn(`Expected exactly one argument for source currently, but got ${args.length} instead, skipping`);
|
|
108
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
123
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
109
124
|
}
|
|
110
125
|
const information = config.includeFunctionCall ?
|
|
111
|
-
(0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information
|
|
126
|
+
(0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'builtin:source' }).information
|
|
112
127
|
: (0, info_1.initializeCleanDataflowInformation)(rootId, data);
|
|
113
128
|
const sourceFileArgument = args[0];
|
|
114
129
|
if (!config.forceFollow && (0, config_1.getConfig)().ignoreSourceCalls) {
|
|
@@ -6,11 +6,11 @@ const logger_1 = require("../../../../../logger");
|
|
|
6
6
|
const edge_1 = require("../../../../../graph/edge");
|
|
7
7
|
function processSpecialBinOp(name, args, rootId, data, config) {
|
|
8
8
|
if (!config.lazy) {
|
|
9
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
9
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'builtin:special-bin-op' }).information;
|
|
10
10
|
}
|
|
11
11
|
else if (args.length != 2) {
|
|
12
12
|
logger_1.dataflowLogger.warn(`Logical bin-op ${name.content} has something else than 2 arguments, skipping`);
|
|
13
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs }).information;
|
|
13
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs, origin: 'default' }).information;
|
|
14
14
|
}
|
|
15
15
|
const { information, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: config.forceArgs,
|
|
16
16
|
patchData: (d, i) => {
|
|
@@ -18,7 +18,8 @@ function processSpecialBinOp(name, args, rootId, data, config) {
|
|
|
18
18
|
return { ...d, controlDependencies: [...d.controlDependencies ?? [], { id: name.info.id, when: config.evalRhsWhen }] };
|
|
19
19
|
}
|
|
20
20
|
return d;
|
|
21
|
-
}
|
|
21
|
+
},
|
|
22
|
+
origin: 'builtin:special-bin-op'
|
|
22
23
|
});
|
|
23
24
|
for (const arg of processedArguments) {
|
|
24
25
|
if (arg) {
|
|
@@ -15,11 +15,11 @@ const containers_1 = require("../../../../../../util/containers");
|
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
function processVector(name, args, rootId, data) {
|
|
18
|
-
const fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data });
|
|
18
|
+
const fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'builtin:vector' });
|
|
19
19
|
if (!(0, config_1.getConfig)().solver.pointerTracking) {
|
|
20
20
|
return fnCall.information;
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
let vectorArgs = [];
|
|
23
23
|
let argIndex = 1;
|
|
24
24
|
for (const arg of args) {
|
|
25
25
|
// Skip invalid argument types
|
|
@@ -49,7 +49,7 @@ function processVector(name, args, rootId, data) {
|
|
|
49
49
|
nodeId: index.nodeId,
|
|
50
50
|
};
|
|
51
51
|
}) ?? [];
|
|
52
|
-
vectorArgs.
|
|
52
|
+
vectorArgs = vectorArgs.concat(flattenedIndices);
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
if ((0, config_1.isOverPointerAnalysisThreshold)(vectorArgs.length)) {
|
|
@@ -14,12 +14,12 @@ const identifier_1 = require("../../../../../environments/identifier");
|
|
|
14
14
|
function processWhileLoop(name, args, rootId, data) {
|
|
15
15
|
if (args.length !== 2 || args[1] === r_function_call_1.EmptyArgument) {
|
|
16
16
|
logger_1.dataflowLogger.warn(`While-Loop ${name.content} does not have 2 arguments, skipping`);
|
|
17
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
17
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
18
18
|
}
|
|
19
19
|
const unpackedArgs = args.map(e => (0, unpack_argument_1.unpackArgument)(e));
|
|
20
20
|
if (unpackedArgs.some(assert_1.isUndefined)) {
|
|
21
21
|
logger_1.dataflowLogger.warn(`While-Loop ${name.content} has empty arguments in ${JSON.stringify(args)}, skipping`);
|
|
22
|
-
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data }).information;
|
|
22
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
23
23
|
}
|
|
24
24
|
/* we inject the cf-dependency of the while-loop after the condition */
|
|
25
25
|
const { information, processedArguments } = (0, known_call_handling_1.processKnownFunctionCall)({
|
|
@@ -33,7 +33,7 @@ function processWhileLoop(name, args, rootId, data) {
|
|
|
33
33
|
return { ...d, controlDependencies: [...d.controlDependencies ?? [], { id: name.info.id, when: true }] };
|
|
34
34
|
}
|
|
35
35
|
return d;
|
|
36
|
-
}
|
|
36
|
+
}, origin: 'builtin:while-loop'
|
|
37
37
|
});
|
|
38
38
|
const [condition, body] = processedArguments;
|
|
39
39
|
(0, assert_1.guard)(condition !== undefined && body !== undefined, () => `While-Loop ${name.content} has no condition or body, impossible!`);
|
|
@@ -7,6 +7,7 @@ import type { DataflowGraph, FunctionArgument } from '../../../../graph/graph';
|
|
|
7
7
|
import type { NodeId } from '../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
8
8
|
import type { REnvironmentInformation } from '../../../../environments/environment';
|
|
9
9
|
import type { IdentifierReference } from '../../../../environments/identifier';
|
|
10
|
+
import type { DataflowGraphVertexAstLink, FunctionOriginInformation } from '../../../../graph/vertex';
|
|
10
11
|
import type { RSymbol } from '../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
11
12
|
export interface ForceArguments {
|
|
12
13
|
/** which of the arguments should be forced? this may be all, e.g., if the function itself is unknown on encounter */
|
|
@@ -35,5 +36,7 @@ export interface PatchFunctionCallInput<OtherInfo> {
|
|
|
35
36
|
readonly name: RSymbol<OtherInfo & ParentInformation>;
|
|
36
37
|
readonly data: DataflowProcessorInformation<OtherInfo & ParentInformation>;
|
|
37
38
|
readonly argumentProcessResult: readonly (Pick<DataflowInformation, 'entryPoint'> | undefined)[];
|
|
39
|
+
readonly origin: FunctionOriginInformation;
|
|
40
|
+
readonly link?: DataflowGraphVertexAstLink;
|
|
38
41
|
}
|
|
39
|
-
export declare function patchFunctionCall<OtherInfo>({ nextGraph, rootId, name, data, argumentProcessResult }: PatchFunctionCallInput<OtherInfo>): void;
|
|
42
|
+
export declare function patchFunctionCall<OtherInfo>({ nextGraph, rootId, name, data, argumentProcessResult, origin, link }: PatchFunctionCallInput<OtherInfo>): void;
|
|
@@ -77,7 +77,7 @@ function processAllArguments({ functionName, args, data, finalGraph, functionRoo
|
|
|
77
77
|
/* maybe all targets are not definitely of the current scope and should be still kept */
|
|
78
78
|
let assumeItMayHaveAHigherTarget = true;
|
|
79
79
|
for (const resolved of tryToResolve) {
|
|
80
|
-
if ((0, info_1.happensInEveryBranch)(resolved.controlDependencies)) {
|
|
80
|
+
if ((0, info_1.happensInEveryBranch)(resolved.controlDependencies) && !(0, identifier_1.isReferenceType)(resolved.type, identifier_1.ReferenceType.BuiltInFunction | identifier_1.ReferenceType.BuiltInConstant)) {
|
|
81
81
|
assumeItMayHaveAHigherTarget = false;
|
|
82
82
|
}
|
|
83
83
|
// When only a single index is referenced, we don't need to reference the whole object
|
|
@@ -103,7 +103,7 @@ function processAllArguments({ functionName, args, data, finalGraph, functionRoo
|
|
|
103
103
|
}
|
|
104
104
|
return { finalEnv, callArgs, remainingReadInArgs, processedArguments };
|
|
105
105
|
}
|
|
106
|
-
function patchFunctionCall({ nextGraph, rootId, name, data, argumentProcessResult }) {
|
|
106
|
+
function patchFunctionCall({ nextGraph, rootId, name, data, argumentProcessResult, origin, link }) {
|
|
107
107
|
nextGraph.addVertex({
|
|
108
108
|
tag: vertex_1.VertexType.FunctionCall,
|
|
109
109
|
id: rootId,
|
|
@@ -113,7 +113,9 @@ function patchFunctionCall({ nextGraph, rootId, name, data, argumentProcessResul
|
|
|
113
113
|
onlyBuiltin: false,
|
|
114
114
|
cds: data.controlDependencies,
|
|
115
115
|
args: argumentProcessResult.map(arg => arg === undefined ? r_function_call_1.EmptyArgument : { nodeId: arg.entryPoint, controlDependencies: undefined, call: undefined, type: identifier_1.ReferenceType.Argument }),
|
|
116
|
-
|
|
116
|
+
origin: [origin],
|
|
117
|
+
link
|
|
118
|
+
}, !nextGraph.hasVertex(rootId) || nextGraph.isRoot(rootId), true);
|
|
117
119
|
for (const arg of argumentProcessResult) {
|
|
118
120
|
if (arg) {
|
|
119
121
|
nextGraph.addEdge(rootId, arg.entryPoint, edge_1.EdgeType.Argument);
|
|
@@ -8,7 +8,7 @@ import type { NodeId } from '../../../../../r-bridge/lang-4.x/ast/model/processi
|
|
|
8
8
|
import type { RNode } from '../../../../../r-bridge/lang-4.x/ast/model/model';
|
|
9
9
|
import type { IdentifierReference } from '../../../../environments/identifier';
|
|
10
10
|
import { DataflowGraph } from '../../../../graph/graph';
|
|
11
|
-
import type { ContainerIndicesCollection } from '../../../../graph/vertex';
|
|
11
|
+
import type { ContainerIndicesCollection, FunctionOriginInformation } from '../../../../graph/vertex';
|
|
12
12
|
export interface ProcessKnownFunctionCallInput<OtherInfo> extends ForceArguments {
|
|
13
13
|
readonly name: RSymbol<OtherInfo & ParentInformation>;
|
|
14
14
|
readonly args: readonly (RNode<OtherInfo & ParentInformation> | RFunctionArgument<OtherInfo & ParentInformation>)[];
|
|
@@ -22,6 +22,7 @@ export interface ProcessKnownFunctionCallInput<OtherInfo> extends ForceArguments
|
|
|
22
22
|
readonly patchData?: (data: DataflowProcessorInformation<OtherInfo & ParentInformation>, arg: number) => DataflowProcessorInformation<OtherInfo & ParentInformation>;
|
|
23
23
|
/** Does the call have a side effect that we do not know a lot about which may have further consequences? */
|
|
24
24
|
readonly hasUnknownSideEffect?: boolean;
|
|
25
|
+
readonly origin: FunctionOriginInformation | 'default';
|
|
25
26
|
}
|
|
26
27
|
export interface ProcessKnownFunctionCallResult {
|
|
27
28
|
readonly information: DataflowInformation;
|
|
@@ -29,4 +30,4 @@ export interface ProcessKnownFunctionCallResult {
|
|
|
29
30
|
readonly fnRef: IdentifierReference;
|
|
30
31
|
}
|
|
31
32
|
export declare function markNonStandardEvaluationEdges(markAsNSE: readonly number[], callArgs: readonly (DataflowInformation | undefined)[], finalGraph: DataflowGraph, rootId: NodeId): void;
|
|
32
|
-
export declare function processKnownFunctionCall<OtherInfo>({ name, args, rootId, data, reverseOrder, markAsNSE, forceArgs, patchData, hasUnknownSideEffect }: ProcessKnownFunctionCallInput<OtherInfo>, indicesCollection?: ContainerIndicesCollection): ProcessKnownFunctionCallResult;
|
|
33
|
+
export declare function processKnownFunctionCall<OtherInfo>({ name, args, rootId, data, reverseOrder, markAsNSE, forceArgs, patchData, hasUnknownSideEffect, origin }: ProcessKnownFunctionCallInput<OtherInfo>, indicesCollection?: ContainerIndicesCollection): ProcessKnownFunctionCallResult;
|
|
@@ -23,7 +23,7 @@ function markNonStandardEvaluationEdges(markAsNSE, callArgs, finalGraph, rootId)
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
function processKnownFunctionCall({ name, args, rootId, data, reverseOrder = false, markAsNSE = undefined, forceArgs, patchData = d => d, hasUnknownSideEffect }, indicesCollection = undefined) {
|
|
26
|
+
function processKnownFunctionCall({ name, args, rootId, data, reverseOrder = false, markAsNSE = undefined, forceArgs, patchData = d => d, hasUnknownSideEffect, origin }, indicesCollection = undefined) {
|
|
27
27
|
const functionName = (0, processor_1.processDataflowFor)(name, data);
|
|
28
28
|
const finalGraph = new graph_1.DataflowGraph(data.completeAst.idMap);
|
|
29
29
|
const functionCallName = name.content;
|
|
@@ -43,6 +43,7 @@ function processKnownFunctionCall({ name, args, rootId, data, reverseOrder = fal
|
|
|
43
43
|
cds: data.controlDependencies,
|
|
44
44
|
args: reverseOrder ? [...callArgs].reverse() : callArgs,
|
|
45
45
|
indicesCollection: indicesCollection,
|
|
46
|
+
origin: origin === 'default' ? ['function'] : [origin]
|
|
46
47
|
});
|
|
47
48
|
if (hasUnknownSideEffect) {
|
|
48
49
|
finalGraph.markIdForUnknownSideEffects(rootId);
|
|
@@ -25,7 +25,7 @@ function mergeInformation(info, newInfo) {
|
|
|
25
25
|
function processDefaultFunctionProcessor(information, name, args, rootId, data) {
|
|
26
26
|
const resolve = (0, resolve_by_name_1.resolveByName)(name.content, data.environment, identifier_1.ReferenceType.Function);
|
|
27
27
|
/* if we do not know where we land, we force! */
|
|
28
|
-
const call = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: (resolve?.length ?? 0) > 0 ? undefined : 'all' });
|
|
28
|
+
const call = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, forceArgs: (resolve?.length ?? 0) > 0 ? undefined : 'all', origin: 'default' });
|
|
29
29
|
return mergeInformation(information, call.information);
|
|
30
30
|
}
|
|
31
31
|
function markAsOnlyBuiltIn(graph, rootId) {
|
|
@@ -3,4 +3,5 @@ import type { DataflowInformation } from '../../../../info';
|
|
|
3
3
|
import type { RUnnamedFunctionCall } from '../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
4
4
|
import type { ParentInformation } from '../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
5
5
|
export declare const UnnamedFunctionCallPrefix = "unnamed-function-call-";
|
|
6
|
+
export declare const UnnamedFunctionCallOrigin = "unnamed";
|
|
6
7
|
export declare function processUnnamedFunctionCall<OtherInfo>(functionCall: RUnnamedFunctionCall<OtherInfo & ParentInformation>, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
|