@eagleoutice/flowr 2.2.11 → 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.d.ts +49 -22
- package/benchmark/slicer.js +89 -29
- package/benchmark/stats/print.js +16 -10
- package/benchmark/stats/size-of.js +18 -1
- package/benchmark/stats/stats.d.ts +3 -0
- 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 +9 -3
- package/benchmark/summarizer/summarizer.js +1 -1
- package/cli/benchmark-app.d.ts +5 -0
- package/cli/benchmark-app.js +49 -6
- package/cli/benchmark-helper-app.d.ts +4 -0
- package/cli/benchmark-helper-app.js +20 -4
- package/cli/common/options.js +15 -6
- 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 +6 -2
- package/cli/repl/commands/repl-dataflow.d.ts +2 -0
- package/cli/repl/commands/repl-dataflow.js +37 -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 +60 -21
- package/config.js +24 -4
- 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.d.ts +5 -2
- package/dataflow/environments/built-in-config.js +17 -8
- package/dataflow/environments/built-in.d.ts +16 -5
- package/dataflow/environments/built-in.js +55 -6
- package/dataflow/environments/clone.d.ts +5 -0
- package/dataflow/environments/clone.js +5 -0
- package/dataflow/environments/default-builtin-config.d.ts +2 -0
- package/dataflow/environments/default-builtin-config.js +164 -13
- package/dataflow/environments/define.d.ts +5 -1
- package/dataflow/environments/define.js +36 -10
- package/dataflow/environments/overwrite.js +4 -0
- package/dataflow/environments/remove.d.ts +6 -0
- package/dataflow/environments/remove.js +24 -0
- package/dataflow/environments/resolve-by-name.js +16 -5
- package/dataflow/extractor.js +2 -2
- package/dataflow/graph/dataflowgraph-builder.d.ts +79 -7
- package/dataflow/graph/dataflowgraph-builder.js +106 -8
- 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 +17 -4
- package/dataflow/graph/graph.js +51 -12
- package/dataflow/graph/vertex.d.ts +59 -4
- package/dataflow/graph/vertex.js +32 -0
- package/dataflow/internal/linker.d.ts +3 -2
- package/dataflow/internal/linker.js +36 -25
- 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.d.ts +1 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +67 -54
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +6 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +108 -21
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +54 -17
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +10 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +140 -0
- 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 +51 -17
- 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 +4 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +100 -31
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.d.ts +7 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +41 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +35 -8
- 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.d.ts +15 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +75 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +3 -3
- package/dataflow/internal/process/functions/call/common.d.ts +5 -2
- package/dataflow/internal/process/functions/call/common.js +9 -5
- 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.d.ts +2 -0
- package/dataflow/internal/process/functions/call/named-call-handling.js +10 -6
- 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 +4 -1
- package/dataflow/internal/process/process-named-call.js +8 -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 +20 -4
- package/documentation/doc-util/doc-cfg.js +41 -7
- package/documentation/doc-util/doc-cli-option.js +4 -2
- package/documentation/doc-util/doc-code.js +10 -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 +28 -2
- package/documentation/print-cfg-wiki.d.ts +1 -0
- package/documentation/print-cfg-wiki.js +572 -0
- package/documentation/print-core-wiki.js +2 -2
- 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 +2 -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 +23 -3
- package/documentation/print-readme.js +10 -3
- package/package.json +10 -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 +17 -7
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +2 -26
- package/queries/catalog/dependencies-query/dependencies-query-format.js +4 -147
- package/queries/catalog/dependencies-query/function-info/function-info.d.ts +24 -0
- package/queries/catalog/dependencies-query/function-info/function-info.js +10 -0
- package/queries/catalog/dependencies-query/function-info/library-functions.d.ts +2 -0
- package/queries/catalog/dependencies-query/function-info/library-functions.js +18 -0
- package/queries/catalog/dependencies-query/function-info/read-functions.d.ts +2 -0
- package/queries/catalog/dependencies-query/function-info/read-functions.js +101 -0
- package/queries/catalog/dependencies-query/function-info/source-functions.d.ts +2 -0
- package/queries/catalog/dependencies-query/function-info/source-functions.js +11 -0
- package/queries/catalog/dependencies-query/function-info/write-functions.d.ts +2 -0
- package/queries/catalog/dependencies-query/function-info/write-functions.js +87 -0
- 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/data/data.d.ts +2 -2
- package/r-bridge/data/data.js +2 -2
- 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} +24 -1
- package/util/{arrays.js → collections/arrays.js} +44 -3
- package/util/collections/set.js +17 -0
- package/util/{list-access.d.ts → containers.d.ts} +24 -4
- package/util/{list-access.js → containers.js} +42 -12
- 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/ast.js +12 -1
- package/util/mermaid/cfg.d.ts +9 -2
- package/util/mermaid/cfg.js +65 -13
- 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/parallel.d.ts +2 -1
- package/util/parallel.js +11 -2
- package/util/prefix.d.ts +13 -0
- package/util/prefix.js +34 -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
|
@@ -4,66 +4,66 @@ 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
|
-
const assert_1 = require("../../../../../../util/assert");
|
|
10
8
|
const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
11
9
|
const logger_1 = require("../../../../../logger");
|
|
12
10
|
const vertex_1 = require("../../../../../graph/vertex");
|
|
13
11
|
const graph_1 = require("../../../../../graph/graph");
|
|
14
12
|
const edge_1 = require("../../../../../graph/edge");
|
|
15
|
-
const dfg_1 = require("../../../../../../util/mermaid/dfg");
|
|
16
13
|
const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
|
|
17
|
-
const
|
|
14
|
+
const containers_1 = require("../../../../../../util/containers");
|
|
18
15
|
const config_1 = require("../../../../../../config");
|
|
16
|
+
const unpack_argument_1 = require("../argument/unpack-argument");
|
|
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");
|
|
19
20
|
function processReplacementFunction(name,
|
|
20
21
|
/** The last one has to be the value */
|
|
21
22
|
args, rootId, data, config) {
|
|
22
23
|
if (args.length < 2) {
|
|
23
24
|
logger_1.dataflowLogger.warn(`Replacement ${name.content} has less than 2 arguments, skipping`);
|
|
24
|
-
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;
|
|
25
26
|
}
|
|
26
27
|
/* we only get here if <-, <<-, ... or whatever is part of the replacement is not overwritten */
|
|
27
28
|
(0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Replacement ${name.content} with ${JSON.stringify(args)}, processing`);
|
|
28
|
-
let indices =
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
const accessedArg = nonEmptyArgs.find(arg => arg.info.role === "accessed" /* RoleInParent.Accessed */);
|
|
32
|
-
const accessArg = nonEmptyArgs.find(arg => arg.info.role === "index-access" /* RoleInParent.IndexAccess */);
|
|
33
|
-
if (accessArg !== undefined && accessedArg != undefined) {
|
|
34
|
-
const leafIndex = { lexeme: accessArg.lexeme, nodeId: accessedArg.info.parent ?? '' };
|
|
35
|
-
const accessIndices = {
|
|
36
|
-
indices: [leafIndex],
|
|
37
|
-
isContainer: false
|
|
38
|
-
};
|
|
39
|
-
// Check for nested access
|
|
40
|
-
if (accessedArg.value?.type === type_1.RType.Access) {
|
|
41
|
-
indices = (0, list_access_1.constructNestedAccess)(accessedArg.value, accessIndices);
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
// use access node as reference to get complete line in slice
|
|
45
|
-
indices = [accessIndices];
|
|
46
|
-
}
|
|
47
|
-
}
|
|
29
|
+
let indices = config.activeIndices;
|
|
30
|
+
if ((0, config_1.getConfig)().solver.pointerTracking) {
|
|
31
|
+
indices ??= constructAccessedIndices(name.content, args);
|
|
48
32
|
}
|
|
49
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 */
|
|
50
|
-
|
|
34
|
+
let res = built_in_1.BuiltInProcessorMapper['builtin:assignment'](name, [args[0], args[args.length - 1]], rootId, data, {
|
|
51
35
|
superAssignment: config.assignmentOperator === '<<-',
|
|
52
36
|
makeMaybe: indices !== undefined ? false : config.makeMaybe,
|
|
53
|
-
indicesCollection: indices
|
|
37
|
+
indicesCollection: indices,
|
|
38
|
+
canBeReplacement: true
|
|
54
39
|
});
|
|
40
|
+
const createdVert = res.graph.getVertex(rootId);
|
|
41
|
+
if (createdVert?.tag === vertex_1.VertexType.FunctionCall) {
|
|
42
|
+
createdVert.origin = ['builtin:replacement'];
|
|
43
|
+
}
|
|
44
|
+
const convertedArgs = config.readIndices ? args.slice(1, -1) : (0, built_in_access_1.symbolArgumentsToStrings)(args.slice(1, -1), 0);
|
|
55
45
|
/* now, we soft-inject other arguments, so that calls like `x[y] <- 3` are linked correctly */
|
|
56
46
|
const { callArgs } = (0, common_1.processAllArguments)({
|
|
57
47
|
functionName: (0, info_1.initializeCleanDataflowInformation)(rootId, data),
|
|
58
|
-
args:
|
|
48
|
+
args: convertedArgs,
|
|
59
49
|
data,
|
|
60
50
|
functionRootId: rootId,
|
|
61
51
|
finalGraph: res.graph,
|
|
62
52
|
forceArgs: config.forceArgs,
|
|
63
53
|
});
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
54
|
+
(0, common_1.patchFunctionCall)({
|
|
55
|
+
nextGraph: res.graph,
|
|
56
|
+
data,
|
|
57
|
+
rootId,
|
|
58
|
+
name,
|
|
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
|
|
62
|
+
});
|
|
63
|
+
const firstArg = (0, unpack_argument_1.unpackArgument)(args[0])?.info.id;
|
|
64
|
+
if (firstArg) {
|
|
65
|
+
res.graph.addEdge(firstArg, rootId, edge_1.EdgeType.DefinedBy | edge_1.EdgeType.Reads);
|
|
66
|
+
}
|
|
67
67
|
/* a replacement reads all of its call args as well, at least as far as I am aware of */
|
|
68
68
|
for (const arg of callArgs) {
|
|
69
69
|
const ref = (0, graph_1.getReferenceOfArgument)(arg);
|
|
@@ -71,6 +71,75 @@ args, rootId, data, config) {
|
|
|
71
71
|
res.graph.addEdge(rootId, ref, edge_1.EdgeType.Reads);
|
|
72
72
|
}
|
|
73
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
|
+
}
|
|
74
81
|
return res;
|
|
75
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Constructs accessed indices of replacement function recursively.
|
|
85
|
+
*
|
|
86
|
+
* Example:
|
|
87
|
+
* ```r
|
|
88
|
+
* a$b <- 1
|
|
89
|
+
* # results in index with lexeme b as identifier
|
|
90
|
+
*
|
|
91
|
+
* a[[1]]$b
|
|
92
|
+
* # results in index with index 1 as identifier with a sub-index with lexeme b as identifier
|
|
93
|
+
* ```
|
|
94
|
+
*
|
|
95
|
+
* @param operation - Operation of replacement function e.g. '$\<-', '[\<-', '[[\<-'
|
|
96
|
+
* @param args - Arguments of the replacement function
|
|
97
|
+
* @returns Accessed indices construct
|
|
98
|
+
*/
|
|
99
|
+
function constructAccessedIndices(operation, args) {
|
|
100
|
+
const { accessedArg, accessArg } = (0, containers_1.getAccessOperands)(args);
|
|
101
|
+
if (accessedArg === undefined || accessArg?.value === undefined || !isSupportedOperation(operation, accessArg.value)) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
const constructIdentifier = getIdentifierBuilder(operation);
|
|
105
|
+
const leafIndex = {
|
|
106
|
+
identifier: constructIdentifier(accessArg),
|
|
107
|
+
nodeId: accessedArg.info.parent ?? ''
|
|
108
|
+
};
|
|
109
|
+
const accessIndices = {
|
|
110
|
+
indices: [leafIndex],
|
|
111
|
+
isContainer: false
|
|
112
|
+
};
|
|
113
|
+
// Check for nested access
|
|
114
|
+
let indicesCollection = undefined;
|
|
115
|
+
if (accessedArg.value?.type === type_1.RType.Access) {
|
|
116
|
+
indicesCollection = (0, containers_1.constructNestedAccess)(accessedArg.value, accessIndices, constructIdentifier);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// use access node as reference to get complete line in slice
|
|
120
|
+
indicesCollection = [accessIndices];
|
|
121
|
+
}
|
|
122
|
+
return indicesCollection;
|
|
123
|
+
}
|
|
124
|
+
function isSupportedOperation(operation, value) {
|
|
125
|
+
const isNameBasedAccess = (operation === '$<-' || operation === '@<-') && value.type === type_1.RType.Symbol;
|
|
126
|
+
const isNumericalIndexBasedAccess = (operation === '[[<-' || operation === '[<-') && value.type === type_1.RType.Number;
|
|
127
|
+
return isNameBasedAccess || isNumericalIndexBasedAccess;
|
|
128
|
+
}
|
|
129
|
+
function getIdentifierBuilder(operation) {
|
|
130
|
+
if (operation === '$<-' || operation == '@<-') {
|
|
131
|
+
return (arg) => {
|
|
132
|
+
return {
|
|
133
|
+
index: undefined,
|
|
134
|
+
lexeme: arg.lexeme,
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
// [[<- and [<-
|
|
139
|
+
return (arg) => {
|
|
140
|
+
return {
|
|
141
|
+
index: Number(arg.lexeme),
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
}
|
|
76
145
|
//# sourceMappingURL=built-in-replacement.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DataflowProcessorInformation } from '../../../../../processor';
|
|
2
|
+
import type { DataflowInformation } from '../../../../../info';
|
|
3
|
+
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
4
|
+
import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
5
|
+
import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
6
|
+
import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
7
|
+
export declare function processRm<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processRm = processRm;
|
|
4
|
+
const known_call_handling_1 = require("../known-call-handling");
|
|
5
|
+
const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
6
|
+
const logger_1 = require("../../../../../logger");
|
|
7
|
+
const remove_1 = require("../../../../../environments/remove");
|
|
8
|
+
const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
|
|
9
|
+
function processRm(name, args, rootId, data) {
|
|
10
|
+
if (args.length === 0) {
|
|
11
|
+
logger_1.dataflowLogger.warn('empty rm, skipping');
|
|
12
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
13
|
+
}
|
|
14
|
+
const res = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'builtin:rm' }).information;
|
|
15
|
+
const names = [];
|
|
16
|
+
for (const arg of args) {
|
|
17
|
+
if (arg === r_function_call_1.EmptyArgument) {
|
|
18
|
+
logger_1.dataflowLogger.warn('empty argument in rm, skipping');
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const unpacked = arg.value;
|
|
22
|
+
if (unpacked === undefined || (unpacked.type !== type_1.RType.Symbol && unpacked.type !== type_1.RType.String)) {
|
|
23
|
+
logger_1.dataflowLogger.warn(`argument is not a symbol or string, skipping ${JSON.stringify(unpacked)}`);
|
|
24
|
+
}
|
|
25
|
+
else if (unpacked.type === type_1.RType.Symbol) {
|
|
26
|
+
names.push(unpacked.content);
|
|
27
|
+
}
|
|
28
|
+
else if (unpacked.type === type_1.RType.String) {
|
|
29
|
+
names.push(unpacked.content.str);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
let env = res.environment;
|
|
33
|
+
for (const name of names) {
|
|
34
|
+
env = (0, remove_1.remove)(name, env);
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
...res,
|
|
38
|
+
environment: env
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=built-in-rm.js.map
|
|
@@ -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,12 +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) {
|
|
121
|
+
if (args.length !== 1) {
|
|
122
|
+
logger_1.dataflowLogger.warn(`Expected exactly one argument for source currently, but got ${args.length} instead, skipping`);
|
|
123
|
+
return (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'default' }).information;
|
|
124
|
+
}
|
|
106
125
|
const information = config.includeFunctionCall ?
|
|
107
|
-
(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
|
|
108
127
|
: (0, info_1.initializeCleanDataflowInformation)(rootId, data);
|
|
109
128
|
const sourceFileArgument = args[0];
|
|
110
129
|
if (!config.forceFollow && (0, config_1.getConfig)().ignoreSourceCalls) {
|
|
@@ -135,12 +154,14 @@ function processSourceCall(name, args, rootId, data, config) {
|
|
|
135
154
|
if (filepath !== undefined) {
|
|
136
155
|
const request = sourceProvider.createRequest(filepath);
|
|
137
156
|
// check if the sourced file has already been dataflow analyzed, and if so, skip it
|
|
138
|
-
|
|
139
|
-
|
|
157
|
+
const limit = (0, config_1.getConfig)().solver.resolveSource?.repeatedSourceLimit ?? 0;
|
|
158
|
+
const findCount = data.referenceChain.filter(e => e.request === request.request && e.content === request.content).length;
|
|
159
|
+
if (findCount > limit) {
|
|
160
|
+
logger_1.dataflowLogger.warn(`Found cycle (>=${limit + 1}) in dataflow analysis for ${JSON.stringify(request)}: ${JSON.stringify(data.referenceChain)}, skipping further dataflow analysis`);
|
|
140
161
|
information.graph.markIdForUnknownSideEffects(rootId);
|
|
141
162
|
return information;
|
|
142
163
|
}
|
|
143
|
-
return sourceRequest(rootId, request, data, information, (0, decorate_1.sourcedDeterministicCountingIdGenerator)(path, name.location));
|
|
164
|
+
return sourceRequest(rootId, request, data, information, (0, decorate_1.sourcedDeterministicCountingIdGenerator)((findCount > 0 ? findCount + '::' : '') + path, name.location));
|
|
144
165
|
}
|
|
145
166
|
}
|
|
146
167
|
(0, log_1.expensiveTrace)(logger_1.dataflowLogger, () => `Non-constant argument ${JSON.stringify(sourceFile)} for source is currently not supported, skipping`);
|
|
@@ -193,7 +214,13 @@ function sourceRequest(rootId, request, data, information, getId) {
|
|
|
193
214
|
for (const [k, v] of normalized.idMap) {
|
|
194
215
|
data.completeAst.idMap.set(k, v);
|
|
195
216
|
}
|
|
196
|
-
return
|
|
217
|
+
return {
|
|
218
|
+
...newInformation,
|
|
219
|
+
in: newInformation.in.concat(dataflow.in),
|
|
220
|
+
out: newInformation.out.concat(dataflow.out),
|
|
221
|
+
unknownReferences: newInformation.unknownReferences.concat(dataflow.unknownReferences),
|
|
222
|
+
exitPoints: dataflow.exitPoints
|
|
223
|
+
};
|
|
197
224
|
}
|
|
198
225
|
function standaloneSourceFile(inputRequest, data, uniqueSourceId, information) {
|
|
199
226
|
const path = inputRequest.request === 'file' ? inputRequest.content : '-inline-';
|
|
@@ -210,6 +237,6 @@ function standaloneSourceFile(inputRequest, data, uniqueSourceId, information) {
|
|
|
210
237
|
currentRequest: request,
|
|
211
238
|
environment: information.environment,
|
|
212
239
|
referenceChain: [...data.referenceChain, inputRequest]
|
|
213
|
-
}, information, (0, decorate_1.deterministicPrefixIdGenerator)(path + '
|
|
240
|
+
}, information, (0, decorate_1.deterministicPrefixIdGenerator)(path + '::' + uniqueSourceId));
|
|
214
241
|
}
|
|
215
242
|
//# sourceMappingURL=built-in-source.js.map
|
|
@@ -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) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { RFunctionArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
2
|
+
import type { RSymbol } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
3
|
+
import type { ParentInformation } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
4
|
+
import type { NodeId } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
5
|
+
import type { DataflowInformation } from '../../../../../info';
|
|
6
|
+
import type { DataflowProcessorInformation } from '../../../../../processor';
|
|
7
|
+
/**
|
|
8
|
+
* Process a vector call.
|
|
9
|
+
*
|
|
10
|
+
* Example:
|
|
11
|
+
* ```r
|
|
12
|
+
* c(1, 2, 3, 4)
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare function processVector<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processVector = processVector;
|
|
4
|
+
const r_function_call_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
5
|
+
const type_1 = require("../../../../../../r-bridge/lang-4.x/ast/model/type");
|
|
6
|
+
const known_call_handling_1 = require("../known-call-handling");
|
|
7
|
+
const config_1 = require("../../../../../../config");
|
|
8
|
+
const containers_1 = require("../../../../../../util/containers");
|
|
9
|
+
/**
|
|
10
|
+
* Process a vector call.
|
|
11
|
+
*
|
|
12
|
+
* Example:
|
|
13
|
+
* ```r
|
|
14
|
+
* c(1, 2, 3, 4)
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
function processVector(name, args, rootId, data) {
|
|
18
|
+
const fnCall = (0, known_call_handling_1.processKnownFunctionCall)({ name, args, rootId, data, origin: 'builtin:vector' });
|
|
19
|
+
if (!(0, config_1.getConfig)().solver.pointerTracking) {
|
|
20
|
+
return fnCall.information;
|
|
21
|
+
}
|
|
22
|
+
let vectorArgs = [];
|
|
23
|
+
let argIndex = 1;
|
|
24
|
+
for (const arg of args) {
|
|
25
|
+
// Skip invalid argument types
|
|
26
|
+
if (arg === r_function_call_1.EmptyArgument || arg.type !== type_1.RType.Argument || arg.value === undefined) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (isPrimitive(arg.value.type)) {
|
|
30
|
+
vectorArgs.push({
|
|
31
|
+
identifier: { index: argIndex++ },
|
|
32
|
+
nodeId: arg.value.info.id,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// Check whether argument value can be resolved
|
|
37
|
+
let indicesCollection;
|
|
38
|
+
if (arg.value.type === type_1.RType.Symbol) {
|
|
39
|
+
indicesCollection = (0, containers_1.resolveIndicesByName)(arg.value.lexeme, data.environment);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// Check whether argument is nested container
|
|
43
|
+
indicesCollection = fnCall.information.graph.getVertex(arg.value.info.id)?.indicesCollection;
|
|
44
|
+
}
|
|
45
|
+
const flattenedIndices = indicesCollection?.flatMap(indices => indices.indices)
|
|
46
|
+
.map(index => {
|
|
47
|
+
return {
|
|
48
|
+
identifier: { index: argIndex++ },
|
|
49
|
+
nodeId: index.nodeId,
|
|
50
|
+
};
|
|
51
|
+
}) ?? [];
|
|
52
|
+
vectorArgs = vectorArgs.concat(flattenedIndices);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if ((0, config_1.isOverPointerAnalysisThreshold)(vectorArgs.length)) {
|
|
56
|
+
return fnCall.information;
|
|
57
|
+
}
|
|
58
|
+
const indices = {
|
|
59
|
+
indices: vectorArgs,
|
|
60
|
+
isContainer: true,
|
|
61
|
+
};
|
|
62
|
+
// Add resolved indices to vertex
|
|
63
|
+
const vertex = fnCall.information.graph.getVertex(rootId);
|
|
64
|
+
if (vertex) {
|
|
65
|
+
vertex.indicesCollection = [indices];
|
|
66
|
+
}
|
|
67
|
+
return fnCall.information;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Checks whether the passed type is primitive i.e. number, logical or string.
|
|
71
|
+
*/
|
|
72
|
+
function isPrimitive(type) {
|
|
73
|
+
return type === type_1.RType.Number || type === type_1.RType.Logical || type === type_1.RType.String;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=built-in-vector.js.map
|
|
@@ -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 */
|
|
@@ -34,6 +35,8 @@ export interface PatchFunctionCallInput<OtherInfo> {
|
|
|
34
35
|
readonly rootId: NodeId;
|
|
35
36
|
readonly name: RSymbol<OtherInfo & ParentInformation>;
|
|
36
37
|
readonly data: DataflowProcessorInformation<OtherInfo & ParentInformation>;
|
|
37
|
-
readonly argumentProcessResult: readonly (DataflowInformation | undefined)[];
|
|
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;
|
|
@@ -64,9 +64,12 @@ function processAllArguments({ functionName, args, data, finalGraph, functionRoo
|
|
|
64
64
|
}
|
|
65
65
|
processedArguments.push(processed);
|
|
66
66
|
finalEnv = (0, overwrite_1.overwriteEnvironment)(finalEnv, processed.environment);
|
|
67
|
+
finalGraph.mergeWith(processed.graph);
|
|
67
68
|
// resolve reads within argument, we resolve before adding the `processed.environment` to avoid cyclic dependencies
|
|
68
69
|
for (const ingoing of [...processed.in, ...processed.unknownReferences]) {
|
|
69
|
-
|
|
70
|
+
// check if it is called directly
|
|
71
|
+
const vtx = finalGraph.getVertex(ingoing.nodeId);
|
|
72
|
+
const tryToResolve = ingoing.name ? (0, resolve_by_name_1.resolveByName)(ingoing.name, argEnv, vtx?.tag === vertex_1.VertexType.FunctionCall ? identifier_1.ReferenceType.Function : identifier_1.ReferenceType.Unknown) : undefined;
|
|
70
73
|
if (tryToResolve === undefined) {
|
|
71
74
|
remainingReadInArgs.push(ingoing);
|
|
72
75
|
}
|
|
@@ -74,7 +77,7 @@ function processAllArguments({ functionName, args, data, finalGraph, functionRoo
|
|
|
74
77
|
/* maybe all targets are not definitely of the current scope and should be still kept */
|
|
75
78
|
let assumeItMayHaveAHigherTarget = true;
|
|
76
79
|
for (const resolved of tryToResolve) {
|
|
77
|
-
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)) {
|
|
78
81
|
assumeItMayHaveAHigherTarget = false;
|
|
79
82
|
}
|
|
80
83
|
// When only a single index is referenced, we don't need to reference the whole object
|
|
@@ -90,7 +93,6 @@ function processAllArguments({ functionName, args, data, finalGraph, functionRoo
|
|
|
90
93
|
}
|
|
91
94
|
}
|
|
92
95
|
argEnv = (0, overwrite_1.overwriteEnvironment)(argEnv, processed.environment);
|
|
93
|
-
finalGraph.mergeWith(processed.graph);
|
|
94
96
|
if (arg.type !== type_1.RType.Argument || !arg.name) {
|
|
95
97
|
callArgs.push({ nodeId: processed.entryPoint, controlDependencies: undefined, type: identifier_1.ReferenceType.Argument });
|
|
96
98
|
}
|
|
@@ -101,7 +103,7 @@ function processAllArguments({ functionName, args, data, finalGraph, functionRoo
|
|
|
101
103
|
}
|
|
102
104
|
return { finalEnv, callArgs, remainingReadInArgs, processedArguments };
|
|
103
105
|
}
|
|
104
|
-
function patchFunctionCall({ nextGraph, rootId, name, data, argumentProcessResult }) {
|
|
106
|
+
function patchFunctionCall({ nextGraph, rootId, name, data, argumentProcessResult, origin, link }) {
|
|
105
107
|
nextGraph.addVertex({
|
|
106
108
|
tag: vertex_1.VertexType.FunctionCall,
|
|
107
109
|
id: rootId,
|
|
@@ -111,7 +113,9 @@ function patchFunctionCall({ nextGraph, rootId, name, data, argumentProcessResul
|
|
|
111
113
|
onlyBuiltin: false,
|
|
112
114
|
cds: data.controlDependencies,
|
|
113
115
|
args: argumentProcessResult.map(arg => arg === undefined ? r_function_call_1.EmptyArgument : { nodeId: arg.entryPoint, controlDependencies: undefined, call: undefined, type: identifier_1.ReferenceType.Argument }),
|
|
114
|
-
|
|
116
|
+
origin: [origin],
|
|
117
|
+
link
|
|
118
|
+
}, !nextGraph.hasVertex(rootId) || nextGraph.isRoot(rootId), true);
|
|
115
119
|
for (const arg of argumentProcessResult) {
|
|
116
120
|
if (arg) {
|
|
117
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);
|
|
@@ -4,4 +4,6 @@ import type { ParentInformation } from '../../../../../r-bridge/lang-4.x/ast/mod
|
|
|
4
4
|
import type { RFunctionArgument } from '../../../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
|
|
5
5
|
import type { RSymbol } from '../../../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
|
|
6
6
|
import type { NodeId } from '../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
7
|
+
import type { DataflowGraph } from '../../../../graph/graph';
|
|
8
|
+
export declare function markAsOnlyBuiltIn(graph: DataflowGraph, rootId: NodeId): void;
|
|
7
9
|
export declare function processNamedCall<OtherInfo>(name: RSymbol<OtherInfo & ParentInformation>, args: readonly RFunctionArgument<OtherInfo & ParentInformation>[], rootId: NodeId, data: DataflowProcessorInformation<OtherInfo & ParentInformation>): DataflowInformation;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.markAsOnlyBuiltIn = markAsOnlyBuiltIn;
|
|
3
4
|
exports.processNamedCall = processNamedCall;
|
|
4
5
|
const info_1 = require("../../../../info");
|
|
5
6
|
const known_call_handling_1 = require("./known-call-handling");
|
|
@@ -24,9 +25,16 @@ function mergeInformation(info, newInfo) {
|
|
|
24
25
|
function processDefaultFunctionProcessor(information, name, args, rootId, data) {
|
|
25
26
|
const resolve = (0, resolve_by_name_1.resolveByName)(name.content, data.environment, identifier_1.ReferenceType.Function);
|
|
26
27
|
/* if we do not know where we land, we force! */
|
|
27
|
-
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' });
|
|
28
29
|
return mergeInformation(information, call.information);
|
|
29
30
|
}
|
|
31
|
+
function markAsOnlyBuiltIn(graph, rootId) {
|
|
32
|
+
const v = graph.getVertex(rootId);
|
|
33
|
+
if (v?.tag === vertex_1.VertexType.FunctionCall) {
|
|
34
|
+
v.onlyBuiltin = true;
|
|
35
|
+
v.environment = undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
30
38
|
function processNamedCall(name, args, rootId, data) {
|
|
31
39
|
const resolved = (0, resolve_by_name_1.resolveByName)(name.content, data.environment, identifier_1.ReferenceType.Function) ?? [];
|
|
32
40
|
let defaultProcessor = resolved.length === 0;
|
|
@@ -46,11 +54,7 @@ function processNamedCall(name, args, rootId, data) {
|
|
|
46
54
|
}
|
|
47
55
|
else if (information && builtIn) {
|
|
48
56
|
// mark the function call as built in only
|
|
49
|
-
|
|
50
|
-
if (v?.tag === vertex_1.VertexType.FunctionCall) {
|
|
51
|
-
v.onlyBuiltin = true;
|
|
52
|
-
v.environment = undefined;
|
|
53
|
-
}
|
|
57
|
+
markAsOnlyBuiltIn(information.graph, rootId);
|
|
54
58
|
}
|
|
55
59
|
return information ?? (0, info_1.initializeCleanDataflowInformation)(rootId, data);
|
|
56
60
|
}
|
|
@@ -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;
|