@eagleoutice/flowr 2.6.2 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -34
- package/abstract-interpretation/data-frame/absint-visitor.d.ts +1 -1
- package/abstract-interpretation/data-frame/absint-visitor.js +6 -6
- package/abstract-interpretation/data-frame/dataframe-domain.d.ts +4 -7
- package/abstract-interpretation/data-frame/dataframe-domain.js +5 -11
- package/abstract-interpretation/data-frame/mappers/access-mapper.d.ts +3 -1
- package/abstract-interpretation/data-frame/mappers/access-mapper.js +3 -2
- package/abstract-interpretation/data-frame/mappers/arguments.js +2 -2
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.d.ts +3 -1
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.js +3 -2
- package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +7 -7
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +28 -24
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.d.ts +3 -1
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +3 -2
- package/abstract-interpretation/data-frame/semantics.js +54 -41
- package/abstract-interpretation/data-frame/shape-inference.d.ts +3 -3
- package/abstract-interpretation/data-frame/shape-inference.js +3 -3
- package/abstract-interpretation/domains/abstract-domain.d.ts +1 -0
- package/abstract-interpretation/domains/abstract-domain.js +3 -2
- package/abstract-interpretation/domains/bounded-set-domain.js +1 -1
- package/abstract-interpretation/domains/interval-domain.d.ts +2 -2
- package/abstract-interpretation/domains/interval-domain.js +3 -6
- package/abstract-interpretation/domains/lattice.d.ts +2 -0
- package/abstract-interpretation/domains/lattice.js +3 -1
- package/abstract-interpretation/domains/positive-interval-domain.d.ts +1 -1
- package/abstract-interpretation/domains/positive-interval-domain.js +1 -1
- package/abstract-interpretation/domains/satisfiable-domain.d.ts +2 -2
- package/abstract-interpretation/domains/satisfiable-domain.js +2 -2
- package/abstract-interpretation/domains/set-range-domain.d.ts +98 -0
- package/abstract-interpretation/domains/set-range-domain.js +400 -0
- package/abstract-interpretation/domains/set-upper-bound-domain.js +2 -2
- package/abstract-interpretation/domains/singleton-domain.js +2 -2
- package/abstract-interpretation/normalized-ast-fold.d.ts +1 -1
- package/benchmark/slicer.d.ts +3 -1
- package/benchmark/slicer.js +50 -27
- package/benchmark/stats/print.js +8 -5
- package/benchmark/stats/stats.d.ts +3 -2
- package/benchmark/summarizer/data.d.ts +11 -8
- package/benchmark/summarizer/first-phase/process.js +12 -9
- package/benchmark/summarizer/second-phase/graph.d.ts +3 -1
- package/benchmark/summarizer/second-phase/graph.js +3 -1
- package/benchmark/summarizer/second-phase/process.js +24 -18
- package/cli/export-quads-app.js +1 -1
- package/cli/repl/commands/repl-dataflow.js +2 -1
- package/cli/repl/commands/repl-parse.js +16 -4
- package/cli/repl/commands/repl-query.js +1 -1
- package/cli/repl/core.js +16 -13
- package/cli/repl/server/connection.js +2 -1
- package/cli/script-core/statistics-helper-core.js +2 -1
- package/cli/slicer-app.js +3 -4
- package/cli/wiki.d.ts +4 -0
- package/cli/wiki.js +165 -0
- package/config.d.ts +4 -0
- package/config.js +6 -0
- package/control-flow/cfg-dead-code.js +14 -3
- package/control-flow/cfg-simplification.d.ts +5 -2
- package/control-flow/cfg-simplification.js +3 -0
- package/control-flow/extract-cfg.d.ts +9 -3
- package/control-flow/extract-cfg.js +44 -4
- package/control-flow/semantic-cfg-guided-visitor.d.ts +2 -2
- package/control-flow/simple-visitor.js +2 -2
- package/control-flow/useless-loop.d.ts +3 -3
- package/control-flow/useless-loop.js +16 -5
- package/core/pipeline-executor.d.ts +3 -6
- package/core/pipeline-executor.js +4 -7
- package/core/print/normalize-printer.d.ts +1 -1
- package/core/print/normalize-printer.js +2 -2
- package/core/steps/all/core/00-parse.d.ts +1 -1
- package/core/steps/all/core/00-parse.js +1 -1
- package/core/steps/all/core/10-normalize.d.ts +3 -9
- package/core/steps/all/core/10-normalize.js +1 -16
- package/core/steps/all/core/11-normalize-tree-sitter.d.ts +2 -3
- package/core/steps/all/core/11-normalize-tree-sitter.js +2 -3
- package/core/steps/all/core/20-dataflow.d.ts +3 -4
- package/core/steps/all/core/20-dataflow.js +2 -2
- package/core/steps/all/static-slicing/00-slice.d.ts +4 -2
- package/core/steps/all/static-slicing/00-slice.js +3 -2
- package/core/steps/all/static-slicing/10-reconstruct.d.ts +8 -0
- package/core/steps/all/static-slicing/10-reconstruct.js +4 -1
- package/core/steps/pipeline/default-pipelines.d.ts +94 -95
- package/core/steps/pipeline/default-pipelines.js +8 -8
- package/dataflow/cluster.js +2 -2
- package/dataflow/environments/append.d.ts +5 -0
- package/dataflow/environments/append.js +6 -20
- package/dataflow/environments/built-in.d.ts +2 -1
- package/dataflow/environments/clone.d.ts +1 -2
- package/dataflow/environments/clone.js +3 -17
- package/dataflow/environments/define.d.ts +7 -3
- package/dataflow/environments/define.js +9 -56
- package/dataflow/environments/diff.js +3 -3
- package/dataflow/environments/environment.d.ts +48 -28
- package/dataflow/environments/environment.js +187 -62
- package/dataflow/environments/overwrite.d.ts +1 -5
- package/dataflow/environments/overwrite.js +2 -61
- package/dataflow/environments/reference-to-maybe.d.ts +13 -0
- package/dataflow/environments/reference-to-maybe.js +54 -0
- package/dataflow/environments/resolve-by-name.d.ts +6 -1
- package/dataflow/environments/resolve-by-name.js +56 -4
- package/dataflow/environments/scoping.d.ts +8 -4
- package/dataflow/environments/scoping.js +13 -9
- package/dataflow/eval/resolve/alias-tracking.d.ts +10 -4
- package/dataflow/eval/resolve/alias-tracking.js +15 -13
- package/dataflow/eval/resolve/resolve-argument.d.ts +2 -1
- package/dataflow/eval/resolve/resolve-argument.js +10 -10
- package/dataflow/eval/resolve/resolve.d.ts +13 -11
- package/dataflow/eval/resolve/resolve.js +16 -15
- package/dataflow/eval/values/string/string-constants.d.ts +9 -3
- package/dataflow/eval/values/string/string-constants.js +9 -3
- package/dataflow/extractor.d.ts +2 -3
- package/dataflow/extractor.js +25 -28
- package/dataflow/fn/higher-order-function.d.ts +2 -1
- package/dataflow/fn/higher-order-function.js +4 -4
- package/dataflow/graph/dataflowgraph-builder.d.ts +9 -5
- package/dataflow/graph/dataflowgraph-builder.js +21 -11
- package/dataflow/graph/diff-dataflow-graph.js +2 -2
- package/dataflow/graph/graph.d.ts +13 -11
- package/dataflow/graph/graph.js +40 -24
- package/dataflow/graph/invert-dfg.d.ts +3 -2
- package/dataflow/graph/invert-dfg.js +3 -3
- package/dataflow/graph/resolve-graph.d.ts +2 -1
- package/dataflow/graph/resolve-graph.js +2 -2
- package/dataflow/graph/unknown-replacement.d.ts +4 -2
- package/dataflow/graph/unknown-replacement.js +4 -2
- package/dataflow/graph/vertex.d.ts +3 -3
- package/dataflow/graph/vertex.js +3 -3
- package/dataflow/info.d.ts +8 -1
- package/dataflow/info.js +21 -0
- package/dataflow/internal/linker.js +10 -11
- package/dataflow/internal/process/functions/call/argument/make-argument.d.ts +2 -2
- package/dataflow/internal/process/functions/call/argument/make-argument.js +2 -3
- package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +7 -1
- package/dataflow/internal/process/functions/call/argument/unpack-argument.js +12 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +7 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +6 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +14 -14
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +10 -8
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +4 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +2 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +10 -14
- package/dataflow/internal/process/functions/call/built-in/built-in-get.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-get.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +3 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +8 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-library.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +4 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.d.ts +6 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +7 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +6 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +15 -10
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +78 -75
- package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.d.ts +3 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.js +3 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +5 -5
- package/dataflow/internal/process/functions/call/common.d.ts +1 -1
- package/dataflow/internal/process/functions/call/common.js +6 -7
- package/dataflow/internal/process/functions/call/default-call-handling.d.ts +3 -1
- package/dataflow/internal/process/functions/call/default-call-handling.js +3 -1
- package/dataflow/internal/process/functions/call/known-call-handling.js +4 -4
- package/dataflow/internal/process/functions/call/named-call-handling.js +4 -4
- package/dataflow/internal/process/functions/call/unnamed-call-handling.js +1 -1
- package/dataflow/internal/process/functions/process-argument.js +1 -1
- package/dataflow/internal/process/functions/process-parameter.js +4 -4
- package/dataflow/internal/process/process-symbol.js +1 -1
- package/dataflow/internal/process/process-value.d.ts +1 -1
- package/dataflow/internal/process/process-value.js +7 -7
- package/dataflow/origin/dfg-get-symbol-refs.d.ts +1 -1
- package/dataflow/origin/dfg-get-symbol-refs.js +1 -1
- package/dataflow/processor.d.ts +7 -16
- package/documentation/data/dfg/doc-data-dfg-util.d.ts +0 -2
- package/documentation/data/faq/faqs.js +27 -18
- package/documentation/data/faq/recommended-configs.d.ts +36 -0
- package/documentation/data/faq/recommended-configs.js +40 -0
- package/documentation/data/faq/wiki-faq-store.d.ts +1 -0
- package/documentation/data/faq/wiki-faq-store.js +10 -2
- package/documentation/data/server/doc-data-server-messages.js +1 -1
- package/documentation/doc-capabilities.d.ts +9 -0
- package/documentation/{print-capabilities-markdown.js → doc-capabilities.js} +18 -21
- package/documentation/doc-readme.d.ts +9 -0
- package/documentation/{print-readme.js → doc-readme.js} +31 -35
- package/documentation/doc-util/doc-benchmarks.d.ts +6 -4
- package/documentation/doc-util/doc-benchmarks.js +6 -4
- package/documentation/doc-util/doc-cfg.js +5 -8
- package/documentation/doc-util/doc-dfg.d.ts +7 -7
- package/documentation/doc-util/doc-dfg.js +15 -14
- package/documentation/doc-util/doc-escape.d.ts +6 -0
- package/documentation/doc-util/doc-escape.js +11 -0
- package/documentation/doc-util/doc-general.d.ts +22 -2
- package/documentation/doc-util/doc-general.js +22 -2
- package/documentation/doc-util/doc-normalized-ast.d.ts +10 -5
- package/documentation/doc-util/doc-normalized-ast.js +14 -10
- package/documentation/doc-util/doc-query.d.ts +12 -4
- package/documentation/doc-util/doc-query.js +18 -11
- package/documentation/doc-util/doc-search.d.ts +0 -30
- package/documentation/doc-util/doc-search.js +2 -73
- package/documentation/doc-util/doc-server-message.d.ts +5 -5
- package/documentation/doc-util/doc-server-message.js +4 -4
- package/documentation/doc-util/doc-types.d.ts +69 -32
- package/documentation/doc-util/doc-types.js +109 -62
- package/documentation/index.d.ts +9 -9
- package/documentation/index.js +9 -9
- package/documentation/issue-linting-rule.d.ts +9 -0
- package/documentation/{print-linter-issue.js → issue-linting-rule.js} +20 -23
- package/documentation/wiki-analyzer.d.ts +9 -0
- package/documentation/wiki-analyzer.js +425 -0
- package/documentation/wiki-cfg.d.ts +9 -0
- package/documentation/{print-cfg-wiki.js → wiki-cfg.js} +144 -160
- package/documentation/wiki-core.d.ts +14 -0
- package/documentation/{print-core-wiki.js → wiki-core.js} +164 -175
- package/documentation/wiki-dataflow-graph.d.ts +9 -0
- package/documentation/{print-dataflow-graph-wiki.js → wiki-dataflow-graph.js} +146 -177
- package/documentation/wiki-engine.d.ts +9 -0
- package/documentation/{print-engines-wiki.js → wiki-engine.js} +27 -42
- package/documentation/wiki-faq.d.ts +8 -0
- package/documentation/wiki-faq.js +21 -0
- package/documentation/wiki-interface.d.ts +9 -0
- package/documentation/{print-interface-wiki.js → wiki-interface.js} +59 -56
- package/documentation/wiki-linter.d.ts +9 -0
- package/documentation/{print-linter-wiki.js → wiki-linter.js} +52 -48
- package/documentation/wiki-linting-and-testing.d.ts +9 -0
- package/documentation/{print-linting-and-testing-wiki.js → wiki-linting-and-testing.js} +25 -32
- package/documentation/wiki-mk/doc-context.d.ts +186 -0
- package/documentation/wiki-mk/doc-context.js +84 -0
- package/documentation/wiki-mk/doc-maker.d.ts +95 -0
- package/documentation/wiki-mk/doc-maker.js +134 -0
- package/documentation/wiki-normalized-ast.d.ts +9 -0
- package/documentation/{print-normalized-ast-wiki.js → wiki-normalized-ast.js} +64 -47
- package/documentation/wiki-onboarding.d.ts +8 -0
- package/documentation/{print-onboarding-wiki.js → wiki-onboarding.js} +18 -15
- package/documentation/wiki-query.d.ts +9 -0
- package/documentation/{print-query-wiki.js → wiki-query.js} +62 -47
- package/documentation/wiki-search.d.ts +9 -0
- package/documentation/wiki-search.js +61 -0
- package/linter/linter-executor.js +3 -2
- package/linter/linter-format.d.ts +2 -2
- package/linter/linter-rules.d.ts +15 -19
- package/linter/rules/absolute-path.d.ts +1 -2
- package/linter/rules/absolute-path.js +5 -5
- package/linter/rules/dataframe-access-validation.d.ts +2 -2
- package/linter/rules/dataframe-access-validation.js +13 -9
- package/linter/rules/dead-code.d.ts +1 -1
- package/linter/rules/deprecated-functions.d.ts +1 -5
- package/linter/rules/file-path-validity.d.ts +1 -1
- package/linter/rules/file-path-validity.js +4 -4
- package/linter/rules/function-finder-util.d.ts +3 -7
- package/linter/rules/function-finder-util.js +1 -1
- package/linter/rules/naming-convention.d.ts +2 -2
- package/linter/rules/naming-convention.js +1 -1
- package/linter/rules/network-functions.d.ts +1 -1
- package/linter/rules/network-functions.js +1 -1
- package/linter/rules/seeded-randomness.d.ts +4 -3
- package/linter/rules/seeded-randomness.js +38 -18
- package/linter/rules/unused-definition.d.ts +1 -1
- package/linter/rules/useless-loop.d.ts +2 -2
- package/linter/rules/useless-loop.js +2 -2
- package/package.json +5 -17
- package/project/cache/flowr-analyzer-cache.d.ts +7 -10
- package/project/cache/flowr-analyzer-cache.js +17 -38
- package/project/cache/flowr-analyzer-controlflow-cache.d.ts +34 -0
- package/project/cache/flowr-analyzer-controlflow-cache.js +79 -0
- package/project/context/flowr-analyzer-context.d.ts +37 -5
- package/project/context/flowr-analyzer-context.js +51 -4
- package/project/context/flowr-analyzer-environment-context.d.ts +47 -0
- package/project/context/flowr-analyzer-environment-context.js +50 -0
- package/project/context/flowr-analyzer-files-context.d.ts +63 -13
- package/project/context/flowr-analyzer-files-context.js +110 -39
- package/project/context/flowr-file.d.ts +32 -10
- package/project/context/flowr-file.js +30 -9
- package/project/flowr-analyzer-builder.d.ts +22 -28
- package/project/flowr-analyzer-builder.js +32 -70
- package/project/flowr-analyzer.d.ts +55 -14
- package/project/flowr-analyzer.js +53 -8
- package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.d.ts +7 -1
- package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.js +13 -5
- package/project/plugins/file-plugins/flowr-analyzer-file-plugin.d.ts +3 -3
- package/project/plugins/file-plugins/flowr-analyzer-file-plugin.js +11 -5
- package/project/plugins/file-plugins/flowr-description-file.d.ts +3 -3
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-jupyter-file-plugin.d.ts +22 -0
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-jupyter-file-plugin.js +33 -0
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-qmd-file-plugin.d.ts +22 -0
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-qmd-file-plugin.js +33 -0
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-rmd-file-plugin.d.ts +22 -0
- package/project/plugins/file-plugins/notebooks/flowr-analyzer-rmd-file-plugin.js +33 -0
- package/project/plugins/file-plugins/notebooks/flowr-jupyter-file.d.ts +20 -0
- package/project/plugins/file-plugins/notebooks/flowr-jupyter-file.js +42 -0
- package/project/plugins/file-plugins/notebooks/flowr-rmarkdown-file.d.ts +59 -0
- package/project/plugins/file-plugins/notebooks/flowr-rmarkdown-file.js +132 -0
- package/project/plugins/file-plugins/notebooks/notebook.d.ts +0 -0
- package/project/plugins/file-plugins/notebooks/notebook.js +2 -0
- package/project/plugins/flowr-analyzer-plugin-defaults.d.ts +5 -0
- package/project/plugins/flowr-analyzer-plugin-defaults.js +23 -0
- package/project/plugins/flowr-analyzer-plugin.d.ts +2 -0
- package/project/plugins/flowr-analyzer-plugin.js +2 -0
- package/project/plugins/loading-order-plugins/flowr-analyzer-loading-order-description-file-plugin.js +1 -1
- package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-description-file-plugin.js +1 -1
- package/project/plugins/plugin-registry.d.ts +34 -0
- package/project/plugins/plugin-registry.js +62 -0
- package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.js +7 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +5 -6
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +5 -2
- package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +25 -18
- package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
- package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +1 -1
- package/queries/catalog/control-flow-query/control-flow-query-format.js +3 -2
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-executor.js +1 -1
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
- package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.d.ts +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +5 -5
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-format.js +1 -1
- package/queries/catalog/df-shape-query/df-shape-query-executor.d.ts +1 -1
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +2 -2
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +6 -6
- package/queries/catalog/df-shape-query/df-shape-query-format.js +8 -7
- package/queries/catalog/happens-before-query/happens-before-query-executor.d.ts +2 -1
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -1
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
- package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.d.ts +1 -1
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +4 -4
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +1 -1
- package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
- package/queries/catalog/linter-query/linter-query-format.js +13 -2
- package/queries/catalog/location-map-query/location-map-query-executor.js +2 -1
- 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 +1 -1
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
- package/queries/catalog/origin-query/origin-query-format.d.ts +1 -1
- package/queries/catalog/project-query/project-query-executor.js +3 -1
- package/queries/catalog/project-query/project-query-format.d.ts +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +2 -2
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +3 -3
- package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +1 -1
- package/queries/catalog/search-query/search-query-format.d.ts +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.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 +13 -1
- package/queries/query.d.ts +26 -18
- package/queries/query.js +21 -1
- package/r-bridge/lang-4.x/ast/model/collect.d.ts +2 -1
- package/r-bridge/lang-4.x/ast/model/collect.js +4 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-project.d.ts +29 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-project.js +15 -0
- package/r-bridge/lang-4.x/ast/model/processing/decorate.d.ts +5 -7
- package/r-bridge/lang-4.x/ast/model/processing/decorate.js +24 -11
- package/r-bridge/lang-4.x/ast/model/type.d.ts +2 -0
- package/r-bridge/lang-4.x/ast/model/type.js +2 -0
- package/r-bridge/lang-4.x/ast/parser/json/format.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +9 -8
- package/r-bridge/lang-4.x/ast/parser/json/parser.js +11 -10
- package/r-bridge/lang-4.x/ast/parser/main/internal/structure/normalize-root.d.ts +4 -3
- package/r-bridge/lang-4.x/ast/parser/main/internal/structure/normalize-root.js +20 -11
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +3 -3
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +5 -4
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.d.ts +3 -2
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +14 -5
- package/r-bridge/parser.d.ts +15 -5
- package/r-bridge/parser.js +27 -13
- package/r-bridge/retriever.d.ts +9 -15
- package/r-bridge/retriever.js +14 -5
- package/r-bridge/shell.d.ts +1 -1
- package/r-bridge/shell.js +1 -1
- package/reconstruct/auto-select/auto-select-defaults.d.ts +0 -1
- package/reconstruct/auto-select/magic-comments.js +1 -1
- package/reconstruct/reconstruct.d.ts +17 -9
- package/reconstruct/reconstruct.js +19 -8
- package/search/flowr-search.d.ts +12 -0
- package/search/search-executor/search-enrichers.d.ts +9 -2
- package/search/search-executor/search-enrichers.js +1 -3
- package/search/search-executor/search-generators.d.ts +1 -1
- package/search/search-executor/search-generators.js +9 -4
- package/slicing/criterion/collect-all.d.ts +3 -2
- package/slicing/criterion/collect-all.js +1 -1
- package/slicing/criterion/parse.js +4 -4
- package/slicing/static/slice-call.d.ts +3 -2
- package/slicing/static/slice-call.js +4 -4
- package/slicing/static/static-slicer.d.ts +3 -1
- package/slicing/static/static-slicer.js +6 -7
- package/statistics/features/supported/assignments/assignments.js +1 -1
- package/statistics/features/supported/control-flow/control-flow.js +2 -2
- package/statistics/features/supported/data-access/data-access.js +1 -1
- package/statistics/features/supported/defined-functions/defined-functions.js +1 -1
- package/statistics/features/supported/expression-list/statistics-expression-list.js +1 -1
- package/statistics/features/supported/loops/loops.js +1 -1
- package/statistics/features/supported/used-functions/used-functions.js +2 -2
- package/statistics/features/supported/variables/variables.js +3 -2
- package/statistics/statistics.js +3 -2
- package/util/assert.d.ts +4 -0
- package/util/assert.js +4 -0
- package/util/containers.js +1 -1
- package/util/files.d.ts +1 -1
- package/util/files.js +1 -1
- package/util/mermaid/ast.d.ts +4 -3
- package/util/mermaid/ast.js +36 -8
- package/util/mermaid/cfg.js +1 -1
- package/util/mermaid/dfg.d.ts +1 -0
- package/util/mermaid/dfg.js +3 -3
- package/util/simple-df/dfg-view.d.ts +2 -1
- package/util/simple-df/dfg-view.js +2 -2
- package/util/version.js +1 -1
- package/dataflow/environments/remove.d.ts +0 -12
- package/dataflow/environments/remove.js +0 -52
- package/documentation/print-analyzer-wiki.d.ts +0 -1
- package/documentation/print-analyzer-wiki.js +0 -141
- package/documentation/print-capabilities-markdown.d.ts +0 -1
- package/documentation/print-cfg-wiki.d.ts +0 -1
- package/documentation/print-core-wiki.d.ts +0 -5
- package/documentation/print-dataflow-graph-wiki.d.ts +0 -1
- package/documentation/print-engines-wiki.d.ts +0 -1
- package/documentation/print-faq-wiki.d.ts +0 -1
- package/documentation/print-faq-wiki.js +0 -18
- package/documentation/print-interface-wiki.d.ts +0 -1
- package/documentation/print-linter-issue.d.ts +0 -1
- package/documentation/print-linter-wiki.d.ts +0 -1
- package/documentation/print-linting-and-testing-wiki.d.ts +0 -1
- package/documentation/print-normalized-ast-wiki.d.ts +0 -1
- package/documentation/print-onboarding-wiki.d.ts +0 -1
- package/documentation/print-query-wiki.d.ts +0 -1
- package/documentation/print-readme.d.ts +0 -1
- package/documentation/print-search-wiki.d.ts +0 -1
- package/documentation/print-search-wiki.js +0 -74
- package/util/formats/adapter-format.d.ts +0 -6
- package/util/formats/adapter-format.js +0 -3
- package/util/formats/adapter.d.ts +0 -27
- package/util/formats/adapter.js +0 -58
- package/util/formats/adapters/r-adapter.d.ts +0 -4
- package/util/formats/adapters/r-adapter.js +0 -7
- package/util/formats/adapters/rmd-adapter.d.ts +0 -35
- package/util/formats/adapters/rmd-adapter.js +0 -100
|
@@ -3,15 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.WikiDataflowGraph = void 0;
|
|
6
7
|
const graph_1 = require("../dataflow/graph/graph");
|
|
7
|
-
const shell_1 = require("../r-bridge/shell");
|
|
8
8
|
const vertex_1 = require("../dataflow/graph/vertex");
|
|
9
9
|
const edge_1 = require("../dataflow/graph/edge");
|
|
10
10
|
const dataflowgraph_builder_1 = require("../dataflow/graph/dataflowgraph-builder");
|
|
11
11
|
const assert_1 = require("../util/assert");
|
|
12
12
|
const doc_dfg_1 = require("./doc-util/doc-dfg");
|
|
13
13
|
const doc_files_1 = require("./doc-util/doc-files");
|
|
14
|
-
const retriever_1 = require("../r-bridge/retriever");
|
|
15
14
|
const json_1 = require("../util/json");
|
|
16
15
|
const doc_env_1 = require("./doc-util/doc-env");
|
|
17
16
|
const doc_data_dfg_util_1 = require("./data/dfg/doc-data-dfg-util");
|
|
@@ -26,9 +25,7 @@ const identifier_1 = require("../dataflow/environments/identifier");
|
|
|
26
25
|
const r_function_call_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
|
|
27
26
|
const resolve_by_name_1 = require("../dataflow/environments/resolve-by-name");
|
|
28
27
|
const default_pipelines_1 = require("../core/steps/pipeline/default-pipelines");
|
|
29
|
-
const doc_auto_gen_1 = require("./doc-util/doc-auto-gen");
|
|
30
28
|
const text_1 = require("../util/text/text");
|
|
31
|
-
const log_1 = require("../../test/functionality/_helper/log");
|
|
32
29
|
const linker_1 = require("../dataflow/internal/linker");
|
|
33
30
|
const doc_normalized_ast_1 = require("./doc-util/doc-normalized-ast");
|
|
34
31
|
const dfg_get_origin_1 = require("../dataflow/origin/dfg-get-origin");
|
|
@@ -37,10 +34,11 @@ const alias_tracking_1 = require("../dataflow/eval/resolve/alias-tracking");
|
|
|
37
34
|
const doc_issue_1 = require("./doc-util/doc-issue");
|
|
38
35
|
const unnamed_call_handling_1 = require("../dataflow/internal/process/functions/call/unnamed-call-handling");
|
|
39
36
|
const environment_builder_1 = require("../../test/functionality/_helper/dataflow/environment-builder");
|
|
40
|
-
const config_1 = require("../config");
|
|
41
37
|
const flowr_analyzer_builder_1 = require("../project/flowr-analyzer-builder");
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
const flowr_analyzer_context_1 = require("../project/context/flowr-analyzer-context");
|
|
39
|
+
const doc_maker_1 = require("./wiki-mk/doc-maker");
|
|
40
|
+
async function subExplanation(parser, { description, code, expectedSubgraph }) {
|
|
41
|
+
expectedSubgraph = await (0, doc_dfg_1.verifyExpectedSubgraph)(parser, code, expectedSubgraph);
|
|
44
42
|
const marks = [];
|
|
45
43
|
for (const [id] of expectedSubgraph.vertices(true)) {
|
|
46
44
|
marks.push(id);
|
|
@@ -51,11 +49,11 @@ async function subExplanation(shell, { description, code, expectedSubgraph }) {
|
|
|
51
49
|
}
|
|
52
50
|
}
|
|
53
51
|
return `
|
|
54
|
-
${await (0, doc_dfg_1.printDfGraphForCode)(
|
|
52
|
+
${await (0, doc_dfg_1.printDfGraphForCode)(parser, code, { mark: new Set(marks) })}
|
|
55
53
|
|
|
56
54
|
${description}`;
|
|
57
55
|
}
|
|
58
|
-
async function printAllSubExplanations(
|
|
56
|
+
async function printAllSubExplanations(parser, expls) {
|
|
59
57
|
let result = `
|
|
60
58
|
<details>
|
|
61
59
|
|
|
@@ -64,21 +62,21 @@ async function printAllSubExplanations(shell, expls) {
|
|
|
64
62
|
`;
|
|
65
63
|
for (const sub of expls) {
|
|
66
64
|
result += `#### ${sub.name}\n`;
|
|
67
|
-
result += await subExplanation(
|
|
65
|
+
result += await subExplanation(parser, sub) + '\n';
|
|
68
66
|
}
|
|
69
67
|
return result + '\n\n</details>';
|
|
70
68
|
}
|
|
71
|
-
async function explanation({
|
|
72
|
-
await (0, doc_dfg_1.verifyExpectedSubgraph)(
|
|
69
|
+
async function explanation({ name, type, description, code, expectedSubgraph }, parser, index, ...subExplanations) {
|
|
70
|
+
await (0, doc_dfg_1.verifyExpectedSubgraph)(parser, code, expectedSubgraph);
|
|
73
71
|
return `
|
|
74
72
|
<a id='${name.toLowerCase().replaceAll(' ', '-')}'> </a>
|
|
75
73
|
### ${index}) ${name}
|
|
76
74
|
|
|
77
75
|
Type: \`${type}\` (this is the bit-flag value, e.g., when looking at the serialization)
|
|
78
76
|
|
|
79
|
-
${await subExplanation(
|
|
77
|
+
${await subExplanation(parser, { name, description, code, expectedSubgraph })}
|
|
80
78
|
|
|
81
|
-
${subExplanations.length > 0 ? await printAllSubExplanations(
|
|
79
|
+
${subExplanations.length > 0 ? await printAllSubExplanations(parser, subExplanations) : ''}
|
|
82
80
|
`;
|
|
83
81
|
}
|
|
84
82
|
function edgeTypeToId(edgeType) {
|
|
@@ -87,18 +85,17 @@ function edgeTypeToId(edgeType) {
|
|
|
87
85
|
function linkEdgeName(edgeType, page = '') {
|
|
88
86
|
return `[\`${(0, edge_1.edgeTypeToName)(edgeType)}\`](${page}#${edgeTypeToId(edgeType)})`;
|
|
89
87
|
}
|
|
90
|
-
async function getVertexExplanations(
|
|
88
|
+
async function getVertexExplanations(parser, ctx) {
|
|
91
89
|
/* we use the map to ensure order easily :D */
|
|
92
90
|
const vertexExplanations = new Map();
|
|
93
91
|
vertexExplanations.set(vertex_1.VertexType.Value, [{
|
|
94
|
-
shell,
|
|
95
92
|
name: 'Value Vertex',
|
|
96
93
|
type: vertex_1.VertexType.Value,
|
|
97
94
|
description: `
|
|
98
95
|
Describes a constant value (numbers, booleans/logicals, strings, ...).
|
|
99
96
|
In general, the respective vertex is more or less a dummy vertex as you can see from its implementation.
|
|
100
97
|
|
|
101
|
-
${
|
|
98
|
+
${ctx.hierarchy('DataflowGraphVertexValue')}
|
|
102
99
|
|
|
103
100
|
${(0, doc_structure_1.block)({
|
|
104
101
|
type: 'NOTE',
|
|
@@ -112,14 +109,13 @@ and ask for the value associated with it.
|
|
|
112
109
|
Please be aware that such nodes may be the result from language semantics as well, and not just from constants directly in the source.
|
|
113
110
|
For example, an access operation like \`df$column\` will treat the column name as a constant value.
|
|
114
111
|
|
|
115
|
-
${(0, doc_structure_1.details)('Example: Semantics Create a Value', `In the following graph, the original type printed by mermaid is still \`RSymbol\` (from the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized
|
|
116
|
-
await (0, doc_dfg_1.printDfGraphForCode)(
|
|
112
|
+
${(0, doc_structure_1.details)('Example: Semantics Create a Value', `In the following graph, the original type printed by mermaid is still \`RSymbol\` (from the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized-AST)), however, the shape of the vertex signals to you that the symbol is in-fact treated as a constant! If you do not know what \`df$column\` even means, please refer to the [R topic](https://rdrr.io/r/base/Extract.html).\n` +
|
|
113
|
+
await (0, doc_dfg_1.printDfGraphForCode)(parser, 'df$column', { mark: new Set([1]) }))}
|
|
117
114
|
`,
|
|
118
115
|
code: '42',
|
|
119
116
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().constant('0')
|
|
120
117
|
}, []]);
|
|
121
118
|
vertexExplanations.set(vertex_1.VertexType.Use, [{
|
|
122
|
-
shell,
|
|
123
119
|
name: 'Use Vertex',
|
|
124
120
|
type: vertex_1.VertexType.Use,
|
|
125
121
|
description: `
|
|
@@ -128,7 +124,7 @@ Describes symbol/variable references which are read (or potentially read at a gi
|
|
|
128
124
|
Similar to the [value vertex](#value-vertex) described above, this is more a marker vertex as
|
|
129
125
|
you can see from the implementation.
|
|
130
126
|
|
|
131
|
-
${
|
|
127
|
+
${ctx.hierarchy('DataflowGraphVertexUse')}
|
|
132
128
|
|
|
133
129
|
${(0, doc_structure_1.block)({
|
|
134
130
|
type: 'NOTE',
|
|
@@ -148,26 +144,26 @@ Consider a case, in which we refer to a variable with a string, as in \`get("x")
|
|
|
148
144
|
${(0, doc_structure_1.details)('Example: Semantics Create a Symbol', `In the following graph, the original type printed by mermaid is still \`RString\` (from the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized%20AST)), however, the shape of the vertex signals to you that the symbol is in-fact treated as a variable use! ` +
|
|
149
145
|
'If you are unsure what `get` does, refer to the [documentation](https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/get). ' +
|
|
150
146
|
'Please note, that the lexeme being printed as `"x"` may be misleading (after all it is recovered from the AST), the quotes are not part of the reference.\n' +
|
|
151
|
-
await (0, doc_dfg_1.printDfGraphForCode)(
|
|
147
|
+
await (0, doc_dfg_1.printDfGraphForCode)(parser, 'get("x")', { mark: new Set([1]) }))}
|
|
152
148
|
|
|
153
149
|
But now to the interesting stuff: how do we actually know which values are read by the respective variable use?
|
|
154
150
|
This usually involves a [variable definition](#variable-definition-vertex) and a [reads edge](#reads-edge) linking the two.
|
|
155
151
|
|
|
156
152
|
${(0, doc_structure_1.details)('Example: Reads Edge Identifying a Single Definition', 'In the following graph, the `x` is read from the definition `x <- 1`.\n' +
|
|
157
|
-
await (0, doc_dfg_1.printDfGraphForCode)(
|
|
153
|
+
await (0, doc_dfg_1.printDfGraphForCode)(parser, 'x <- 1\nprint(x)', { mark: new Set([3, '0->3']), codeOpen: true }))}
|
|
158
154
|
|
|
159
155
|
In general, there may be many such edges, identifying every possible definition of the variable.
|
|
160
156
|
|
|
161
|
-
${(0, doc_structure_1.details)('Example: Reads Edge Identifying Multiple Definitions (conditional)', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
162
|
-
${(0, doc_structure_1.details)('Example: Reads Edge Identifying Multiple Definitions (loop)', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
163
|
-
${(0, doc_structure_1.details)('Example: Reads Edge Identifying Multiple Definitions (side-effect)', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
157
|
+
${(0, doc_structure_1.details)('Example: Reads Edge Identifying Multiple Definitions (conditional)', await (0, doc_dfg_1.printDfGraphForCode)(parser, 'x <- 1\nif(u) x <- 2\nprint(x)', { mark: new Set([10, '10->0', '10->4']), codeOpen: true }))}
|
|
158
|
+
${(0, doc_structure_1.details)('Example: Reads Edge Identifying Multiple Definitions (loop)', await (0, doc_dfg_1.printDfGraphForCode)(parser, 'x <- 1\nfor(i in v) x <- 2\nprint(x)', { mark: new Set([11, '11->0', '11->5']), codeOpen: true }))}
|
|
159
|
+
${(0, doc_structure_1.details)('Example: Reads Edge Identifying Multiple Definitions (side-effect)', await (0, doc_dfg_1.printDfGraphForCode)(parser, 'f <- function() x <<- 2\nx <- 2\nif(u) f()\nprint(x)', { mark: new Set([16, '16->1', '16->7']), codeOpen: true }))}
|
|
164
160
|
|
|
165
161
|
${(0, doc_structure_1.block)({
|
|
166
162
|
type: 'IMPORTANT',
|
|
167
163
|
content: `
|
|
168
164
|
If you want to obtain the locations where a variable is defined, or read, or re-defined, refrain from tracking these details manually in the dataflow graph
|
|
169
165
|
as there are some edge-cases that require special attention.
|
|
170
|
-
In general, the ${
|
|
166
|
+
In general, the ${ctx.link(dfg_get_origin_1.getOriginInDfg)} function explained below in [working with the dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow%20Graph#working-with-the-dataflow-graph) will help you to get the information you need.
|
|
171
167
|
`
|
|
172
168
|
})}
|
|
173
169
|
|
|
@@ -176,7 +172,6 @@ ${(0, doc_structure_1.block)({
|
|
|
176
172
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().use('1@x', 'x')
|
|
177
173
|
}, []]);
|
|
178
174
|
vertexExplanations.set(vertex_1.VertexType.FunctionCall, [{
|
|
179
|
-
shell,
|
|
180
175
|
name: 'Function Call Vertex',
|
|
181
176
|
type: vertex_1.VertexType.FunctionCall,
|
|
182
177
|
description: `
|
|
@@ -187,19 +182,20 @@ the _name_ of the called function, the passed _arguments_, and the _environment_
|
|
|
187
182
|
However, the implementation reveals that it may hold an additional \`onlyBuiltin\` flag to indicate that the call is only calling builtin functions — however, this is only a flag to improve performance,
|
|
188
183
|
and it should not be relied on as it may under-approximate the actual calling targets (e.g., being \`false\` even though all calls resolve to builtins).
|
|
189
184
|
|
|
190
|
-
${
|
|
185
|
+
${ctx.hierarchy('DataflowGraphVertexFunctionCall')}
|
|
186
|
+
|
|
191
187
|
The related function argument references are defined like this:
|
|
192
|
-
${
|
|
188
|
+
${ctx.hierarchy('FunctionArgument')}
|
|
193
189
|
|
|
194
190
|
There is another element of potential interest to you, the \`origin\` property which records how flowR created the respective function call.
|
|
195
|
-
These origins may hold the name of any processor that is part of the ${
|
|
191
|
+
These origins may hold the name of any processor that is part of the ${ctx.link('BuiltInProcessorMapper')} to signal that the respective processor was responsible for creating the vertex.
|
|
196
192
|
The entry \`function\` signals that flowR used a processor for a user-defined function defined within the source code, \`unnamed\` signals that the function as an anonymous function definition.
|
|
197
193
|
However, in general, flowR may use any fitting handler as an origin. For example, within a access definition, flowR will correspondingly redefine the meaning of \`:=\` to that of the \`table:assign\`.
|
|
198
194
|
|
|
199
195
|
${(0, doc_structure_1.details)('Example: Simple Function Call (unresolved)', await (async () => {
|
|
200
196
|
const code = 'foo(x,3,y=3,)';
|
|
201
|
-
const [text, info] = await (0, doc_dfg_1.printDfGraphForCode)(
|
|
202
|
-
const callInfo =
|
|
197
|
+
const [text, info] = await (0, doc_dfg_1.printDfGraphForCode)(parser, code, { mark: new Set([8]), exposeResult: true });
|
|
198
|
+
const callInfo = info.dataflow.graph.vertices(true).find(([, vertex]) => vertex.tag === vertex_1.VertexType.FunctionCall && vertex.name === 'foo');
|
|
203
199
|
(0, assert_1.guard)(callInfo !== undefined, () => `Could not find call vertex for ${code}`);
|
|
204
200
|
const [callId, callVert] = callInfo;
|
|
205
201
|
const inverseMapReferenceTypes = Object.fromEntries(Object.entries(identifier_1.ReferenceType).map(([k, v]) => [v, k]));
|
|
@@ -249,13 +245,13 @@ ${(0, doc_structure_1.details)('1) the function resolves only to builtin definit
|
|
|
249
245
|
|
|
250
246
|
Let's have a look at a simple assignment:
|
|
251
247
|
|
|
252
|
-
${await (0, doc_dfg_1.printDfGraphForCode)(
|
|
248
|
+
${await (0, doc_dfg_1.printDfGraphForCode)(parser, 'x <- 2')}
|
|
253
249
|
|
|
254
250
|
In this case, the call does not have a single ${linkEdgeName(edge_1.EdgeType.Calls)} edge, which in general means (i.e., if the analysis is done and you are not looking at an intermediate result) it is bound to anything
|
|
255
251
|
global beyond the scope of the given script. _flowR_ generally (theoretically at least) does not know if the call really refers to a built-in variable or function,
|
|
256
252
|
as any code that is not part of the analysis could cause the semantics to change.
|
|
257
253
|
However, it is (in most cases) safe to assume we call a builtin if there is a builtin function with the given name and if there is no ${linkEdgeName(edge_1.EdgeType.Calls)} edge attached to a call.
|
|
258
|
-
If you want to check the resolve targets, refer to ${
|
|
254
|
+
If you want to check the resolve targets, refer to ${ctx.link(resolve_by_name_1.resolveByName)}.
|
|
259
255
|
`)}
|
|
260
256
|
|
|
261
257
|
${(0, doc_structure_1.details)('2) the function only resolves to definitions that are present in the program', `
|
|
@@ -264,7 +260,7 @@ Let's have a look at a call to a function named \`foo\` which is defined in the
|
|
|
264
260
|
|
|
265
261
|
${await (async () => {
|
|
266
262
|
const code = 'foo <- function() 3\nfoo()';
|
|
267
|
-
const [text, info] = await (0, doc_dfg_1.printDfGraphForCode)(
|
|
263
|
+
const [text, info] = await (0, doc_dfg_1.printDfGraphForCode)(parser, code, { exposeResult: true, mark: new Set([6, '6->0', '6->1', '6->3']) });
|
|
268
264
|
const numberOfEdges = [...info.dataflow.graph.edges()].flatMap(e => [...e[1].keys()]).length;
|
|
269
265
|
const callVertex = info.dataflow.graph.vertices(true).find(([, vertex]) => vertex.tag === vertex_1.VertexType.FunctionCall && vertex.name === 'foo');
|
|
270
266
|
(0, assert_1.guard)(callVertex !== undefined, () => `Could not find call vertex for ${code}`);
|
|
@@ -279,12 +275,12 @@ While it seems to be somewhat redundant given the ${linkEdgeName(edge_1.EdgeType
|
|
|
279
275
|
you have to consider cases in which aliases are involved in the call resolution (e.g., with higher order functions).
|
|
280
276
|
|
|
281
277
|
${(0, doc_structure_1.details)('Example: Alias in Call Resolution', `In the following example, \`g\` ${linkEdgeName(edge_1.EdgeType.Reads)} the previous definition, but ${linkEdgeName(edge_1.EdgeType.Calls)} the function assigned to \`f\`.\n`
|
|
282
|
-
+ await (0, doc_dfg_1.printDfGraphForCode)(
|
|
278
|
+
+ await (0, doc_dfg_1.printDfGraphForCode)(parser, 'f <- function() 3\ng <- f\ng()', { mark: new Set(['9', '9->5', '9->3']) }))}
|
|
283
279
|
|
|
284
280
|
Lastly, the ${linkEdgeName(edge_1.EdgeType.Returns)} edge links the call to the return vertices(s) of the function.
|
|
285
281
|
Please be aware, that these multiple exit points may be counter intuitive as they often appear with a nested call (usually a call to the built-in \`{\` function).
|
|
286
282
|
|
|
287
|
-
${(0, doc_structure_1.details)('(Advanced) Example: Multiple Exit Points May Still Reflect As One', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
283
|
+
${(0, doc_structure_1.details)('(Advanced) Example: Multiple Exit Points May Still Reflect As One', await (0, doc_dfg_1.printDfGraphForCode)(parser, `
|
|
288
284
|
f <- function() {
|
|
289
285
|
if(u) return(3)
|
|
290
286
|
if(v) return(2)
|
|
@@ -297,7 +293,6 @@ But you have to beware that \`{\` is a function call as well (see below) and it
|
|
|
297
293
|
In this scenario we show two types of such returns (or exit points): _explicit_ returns with the \`return\` function and _implicit_ returns (the result of the last evaluated expression).
|
|
298
294
|
However, they are actually linked with the call of the built-in function \`{\` (and, in fact, they are highlighted in the mermaid graph).
|
|
299
295
|
`)}
|
|
300
|
-
|
|
301
296
|
`;
|
|
302
297
|
})()}
|
|
303
298
|
|
|
@@ -312,8 +307,8 @@ Users may write… interesting pieces of code - for reasons we should not be int
|
|
|
312
307
|
Consider a case in which you have a built-in function (like the assignment operator \`<-\`) and a user that wants to redefine the meaning of the function call _sometimes_:
|
|
313
308
|
|
|
314
309
|
${await (async () => {
|
|
315
|
-
const [text, info] = await (0, doc_dfg_1.printDfGraphForCode)(
|
|
316
|
-
const interestingUseOfAssignment =
|
|
310
|
+
const [text, info] = await (0, doc_dfg_1.printDfGraphForCode)(parser, 'x <- 2\nif(u) `<-` <- `*`\nx <- 3', { switchCodeAndGraph: true, mark: new Set([9, '9->0', '9->10']), exposeResult: true });
|
|
311
|
+
const interestingUseOfAssignment = info.dataflow.graph.vertices(true).find(([, vertex]) => vertex.id === 11);
|
|
317
312
|
(0, assert_1.guard)(interestingUseOfAssignment !== undefined, () => 'Could not find interesting assignment vertex for the code');
|
|
318
313
|
const [id, interestingVertex] = interestingUseOfAssignment;
|
|
319
314
|
const env = interestingVertex.environment;
|
|
@@ -334,11 +329,11 @@ For starters, let's have a look at the environment of the call to \`<-\` in the
|
|
|
334
329
|
${(0, doc_env_1.printEnvironmentToMarkdown)(env.current)}
|
|
335
330
|
|
|
336
331
|
Great, you should see a definition of \`<-\` which is constraint by the [control dependency](#control-dependencies) to the \`if\`.
|
|
337
|
-
Hence, trying to re-resolve the call using
|
|
332
|
+
Hence, trying to re-resolve the call using ${ctx.link(linker_1.getAllFunctionCallTargets)} (defined in ${(0, doc_files_1.getFilePathMd)('../dataflow/internal/linker.ts')}) with the id \`${id}\` of the call as starting point will present you with
|
|
338
333
|
the following target ids: { \`${[...(0, linker_1.getAllFunctionCallTargets)(id, info.dataflow.graph)].join('`, `')}\` }.
|
|
339
334
|
This way we know that the call may refer to the built-in assignment operator or to the multiplication.
|
|
340
|
-
Similarly, trying to resolve the name with
|
|
341
|
-
{ \`${(0, resolve_by_name_1.
|
|
335
|
+
Similarly, trying to resolve the name with ${ctx.link(resolve_by_name_1.resolveByName)}\` using the environment attached to the call vertex (filtering for any reference type) returns (in a similar fashion):
|
|
336
|
+
{ \`${(0, resolve_by_name_1.resolveByNameAnyType)(name, env)?.map(d => d.nodeId).join('`, `')}\` } (however, the latter will not trace aliases).
|
|
342
337
|
|
|
343
338
|
`;
|
|
344
339
|
})()}
|
|
@@ -346,26 +341,26 @@ Similarly, trying to resolve the name with \`${resolve_by_name_1.resolveByName.n
|
|
|
346
341
|
`)}
|
|
347
342
|
|
|
348
343
|
|
|
349
|
-
Similar to finding the definitions read by a variable use, please use the ${
|
|
350
|
-
as explained in the [working with the dataflow graph](${doc_files_1.FlowrWikiBaseRef}/
|
|
344
|
+
Similar to finding the definitions read by a variable use, please use the ${ctx.link(linker_1.getAllFunctionCallTargets)} function to find all possible definitions of a function call,
|
|
345
|
+
as explained in the [working with the dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow%20Graph#working-with-the-dataflow-graph) section.`
|
|
351
346
|
})}
|
|
352
347
|
|
|
353
348
|
Function calls are the most complicated mechanism in R as essentially everything is a function call.
|
|
354
349
|
Even **control structures** like \`if(p) a else b\` are desugared into function calls (e.g., as \`\` \`if\`(p, a, b) \`\`).
|
|
355
|
-
${(0, doc_structure_1.details)('Example: <code>if</code> as a Function Call', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
350
|
+
${(0, doc_structure_1.details)('Example: <code>if</code> as a Function Call', await (0, doc_dfg_1.printDfGraphForCode)(parser, 'if(p) a else b'))}
|
|
356
351
|
|
|
357
352
|
Similarly, you should be aware of calls to **anonymous functions**, which may appear given directly (e.g. as \`(function() 1)()\`) or indirectly, with code
|
|
358
353
|
directly calling the return of another function call: \`foo()()\`.
|
|
359
|
-
${(0, doc_structure_1.details)('Example: Anonymous Function Call (given directly)', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
354
|
+
${(0, doc_structure_1.details)('Example: Anonymous Function Call (given directly)', await (0, doc_dfg_1.printDfGraphForCode)(parser, '(function() 1)()', { mark: new Set([6, '6->4']) }))}
|
|
360
355
|
|
|
361
|
-
${(0, doc_structure_1.details)('Example: Anonymous Function Call (given indirectly)', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
356
|
+
${(0, doc_structure_1.details)('Example: Anonymous Function Call (given indirectly)', await (0, doc_dfg_1.printDfGraphForCode)(parser, 'foo <- function() return(function() 3)\nfoo()()', { mark: new Set([12, '12->4']) }))}
|
|
362
357
|
|
|
363
358
|
${(0, doc_structure_1.block)({
|
|
364
359
|
type: 'NOTE',
|
|
365
360
|
content: `Now you might be asking yourself how to differentiate anonymous and named functions and what you have to keep in mind when working with them?
|
|
366
361
|
|
|
367
362
|
Unnamed functions have an array of signatures which you can use to identify them.
|
|
368
|
-
But in short: the \`origin\` attribute of the ${
|
|
363
|
+
But in short: the \`origin\` attribute of the ${ctx.link('DataflowGraphVertexFunctionCall')} is \`${unnamed_call_handling_1.UnnamedFunctionCallOrigin}\`.
|
|
369
364
|
Please be aware that unnamed functions still have a \`name\` property to give it a unique identifier that can be used for debugging and reference.
|
|
370
365
|
This name _always_ starts with \`${unnamed_call_handling_1.UnnamedFunctionCallPrefix}\`.
|
|
371
366
|
|
|
@@ -377,39 +372,38 @@ To know which function is called, please rely on the ${linkEdgeName(edge_1.EdgeT
|
|
|
377
372
|
|
|
378
373
|
Another interesting case is a function with **side effects**, most prominently with the super-assignment \`<<-\`.
|
|
379
374
|
In this case, you may encounter the ${linkEdgeName(edge_1.EdgeType.SideEffectOnCall)} as exemplified below.
|
|
380
|
-
${(0, doc_structure_1.details)('Example: Function Call with a Side-Effect', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
375
|
+
${(0, doc_structure_1.details)('Example: Function Call with a Side-Effect', await (0, doc_dfg_1.printDfGraphForCode)(parser, 'f <- function() x <<- 3\n f()', { mark: new Set([8, '1->8']) }))}
|
|
381
376
|
|
|
382
377
|
`,
|
|
383
378
|
code: 'foo()',
|
|
384
379
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().call('1@foo', 'foo', [])
|
|
385
380
|
}, []]);
|
|
386
381
|
vertexExplanations.set(vertex_1.VertexType.VariableDefinition, [{
|
|
387
|
-
shell,
|
|
388
382
|
name: 'Variable Definition Vertex',
|
|
389
383
|
type: vertex_1.VertexType.VariableDefinition,
|
|
390
384
|
description: `
|
|
391
385
|
Defined variables most commonly occur in the context of an assignment, for example, with the \`<-\` operator as shown above.
|
|
392
386
|
|
|
393
|
-
${(0, doc_structure_1.details)('Example: Super Definition (<code><<-</code>)', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
387
|
+
${(0, doc_structure_1.details)('Example: Super Definition (<code><<-</code>)', await (0, doc_dfg_1.printDfGraphForCode)(parser, 'x <<- 1', { mark: new Set([0]) }))}
|
|
394
388
|
|
|
395
389
|
The implementation is relatively sparse and similar to the other marker vertices:
|
|
396
390
|
|
|
397
|
-
${
|
|
391
|
+
${ctx.hierarchy('DataflowGraphVertexVariableDefinition')}
|
|
398
392
|
|
|
399
393
|
Of course, there are not just operators that define variables, but also functions, like \`assign\`.
|
|
400
394
|
|
|
401
|
-
${(0, doc_structure_1.details)('Example: Using <code>assign</code>', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
395
|
+
${(0, doc_structure_1.details)('Example: Using <code>assign</code>', await (0, doc_dfg_1.printDfGraphForCode)(parser, 'assign("x", 1)\nx', { mark: new Set([1]) })
|
|
402
396
|
+ `\nThe example may be misleading as the visualization uses \`${node_id_1.recoverName.name}\` to print the lexeme of the variable. However, this actually defines the variable \`x\` (without the quotes) as you can see with the ${linkEdgeName(edge_1.EdgeType.Reads)} edge.`)}
|
|
403
397
|
|
|
404
398
|
Please be aware, that the name of the symbol defined may differ from what you read in the program as R allows the assignments to strings, escaped names, and more:
|
|
405
399
|
|
|
406
|
-
${(0, doc_structure_1.details)('Example: Assigning with an Escaped Name', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
407
|
-
${(0, doc_structure_1.details)('Example: Assigning with a String', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
400
|
+
${(0, doc_structure_1.details)('Example: Assigning with an Escaped Name', await (0, doc_dfg_1.printDfGraphForCode)(parser, '`x` <- 1\nx', { mark: new Set([0]) }))}
|
|
401
|
+
${(0, doc_structure_1.details)('Example: Assigning with a String', await (0, doc_dfg_1.printDfGraphForCode)(parser, '"x" <- 1\nx', { mark: new Set([0]) }))}
|
|
408
402
|
|
|
409
403
|
Definitions may be constrained by conditionals (_flowR_ takes care of calculating the dominating front for you).
|
|
410
404
|
|
|
411
405
|
${(0, doc_structure_1.details)('Conditional Assignments', await (async () => {
|
|
412
|
-
const constrainedDefinitions = await (0, doc_dfg_1.printDfGraphForCode)(
|
|
406
|
+
const constrainedDefinitions = await (0, doc_dfg_1.printDfGraphForCode)(parser, 'x <- 0\nif(u) x <- 1 else x <- 2\nx', { exposeResult: true });
|
|
413
407
|
const [text, info] = constrainedDefinitions;
|
|
414
408
|
const finalEnvironment = (0, doc_env_1.printEnvironmentToMarkdown)(info.dataflow.environment.current);
|
|
415
409
|
return `
|
|
@@ -428,18 +422,17 @@ As you can see, _flowR_ is able to recognize that the initial definition of \`x\
|
|
|
428
422
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().defineVariable('1@x', 'x')
|
|
429
423
|
}, []]);
|
|
430
424
|
vertexExplanations.set(vertex_1.VertexType.FunctionDefinition, [{
|
|
431
|
-
shell,
|
|
432
425
|
name: 'Function Definition Vertex',
|
|
433
426
|
type: vertex_1.VertexType.FunctionDefinition,
|
|
434
427
|
description: `
|
|
435
428
|
Defining a function does do a lot of things: 1) it creates a new scope, 2) it may introduce parameters which act as promises and which are only evaluated if they are actually required in the body, 3) it may access the enclosing environments and the callstack.
|
|
436
429
|
The vertex object in the dataflow graph stores multiple things, including all exit points, the enclosing environment if necessary, and the information of the subflow (the "body" of the function).
|
|
437
430
|
|
|
438
|
-
${
|
|
431
|
+
${ctx.hierarchy('DataflowGraphVertexFunctionDefinition')}
|
|
439
432
|
The subflow is defined like this:
|
|
440
|
-
${
|
|
433
|
+
${ctx.hierarchy('DataflowFunctionFlowInformation')}
|
|
441
434
|
And if you are interested in the exit points, they are defined like this:
|
|
442
|
-
${
|
|
435
|
+
${ctx.hierarchy('ExitPoint')}
|
|
443
436
|
|
|
444
437
|
|
|
445
438
|
Whenever we visualize a function definition, we use a dedicated node to represent the anonymous function object,
|
|
@@ -455,9 +448,8 @@ the actual dataflow graph is flat, and you can query all root vertices (i.e., th
|
|
|
455
448
|
vertices of function definitions or not (e.g., \`${new graph_1.DataflowGraph(undefined).vertices.name}\`)
|
|
456
449
|
|
|
457
450
|
${(0, doc_structure_1.details)('Example: Nested Function Definitions', await (async () => {
|
|
458
|
-
const [text, info] = await (0, doc_dfg_1.printDfGraphForCode)(
|
|
459
|
-
const definitions = info.dataflow.graph.
|
|
460
|
-
.filter(([, vertex]) => vertex.tag === vertex_1.VertexType.FunctionDefinition)
|
|
451
|
+
const [text, info] = await (0, doc_dfg_1.printDfGraphForCode)(parser, 'f <- function() { g <- function() 3 }', { mark: new Set([9, 6]), exposeResult: true });
|
|
452
|
+
const definitions = info.dataflow.graph.verticesOfType(vertex_1.VertexType.FunctionDefinition)
|
|
461
453
|
.map(([id, vertex]) => `| \`${id}\` | { \`${[...vertex.subflow.graph].join('`, `')}\` } |`)
|
|
462
454
|
.toArray();
|
|
463
455
|
return `
|
|
@@ -478,8 +470,8 @@ However, you can use the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normal
|
|
|
478
470
|
|
|
479
471
|
${(0, doc_structure_1.details)('Example: Parameters of a Function', await (async () => {
|
|
480
472
|
const code = 'f <- function(x, y = 3) x + y';
|
|
481
|
-
const [text, info] = await (0, doc_dfg_1.printDfGraphForCode)(
|
|
482
|
-
const ast = await (0, doc_normalized_ast_1.printNormalizedAstForCode)(
|
|
473
|
+
const [text, info] = await (0, doc_dfg_1.printDfGraphForCode)(parser, code, { mark: new Set([10, 1, 3]), exposeResult: true });
|
|
474
|
+
const ast = await (0, doc_normalized_ast_1.printNormalizedAstForCode)(parser, code, { prefix: 'flowchart LR\n', showCode: false });
|
|
483
475
|
const functionDefinition = [...info.dataflow.graph.vertices(true)].find(([, vertex]) => vertex.tag === vertex_1.VertexType.FunctionDefinition);
|
|
484
476
|
(0, assert_1.guard)(functionDefinition !== undefined, () => `Could not find function definition for ${code}`);
|
|
485
477
|
const [id] = functionDefinition;
|
|
@@ -500,7 +492,7 @@ ${ast}
|
|
|
500
492
|
|
|
501
493
|
Last but not least, please keep in mind that R offers another way of writing anonymous functions (using the backslash):
|
|
502
494
|
|
|
503
|
-
${await (0, doc_dfg_1.printDfGraphForCode)(
|
|
495
|
+
${await (0, doc_dfg_1.printDfGraphForCode)(parser, '\\(x) x + 1', { switchCodeAndGraph: true })}
|
|
504
496
|
|
|
505
497
|
Besides this being a theoretically "shorter" way of defining a function, this behaves similarly to the use of \`function\`.
|
|
506
498
|
|
|
@@ -514,14 +506,13 @@ Besides this being a theoretically "shorter" way of defining a function, this be
|
|
|
514
506
|
const get = vertexExplanations.get(vertex);
|
|
515
507
|
(0, assert_1.guard)(get !== undefined, () => `No explanation for vertex type ${vertex}`);
|
|
516
508
|
const [expl, subExplanations] = get;
|
|
517
|
-
results.push(await explanation(expl, ++i, ...subExplanations));
|
|
509
|
+
results.push(await explanation(expl, parser, ++i, ...subExplanations));
|
|
518
510
|
}
|
|
519
511
|
return results.join('\n');
|
|
520
512
|
}
|
|
521
|
-
async function getEdgesExplanations(
|
|
513
|
+
async function getEdgesExplanations(parser, ctx) {
|
|
522
514
|
const edgeExplanations = new Map();
|
|
523
515
|
edgeExplanations.set(edge_1.EdgeType.Reads, [{
|
|
524
|
-
shell,
|
|
525
516
|
name: 'Reads Edge',
|
|
526
517
|
type: edge_1.EdgeType.Reads,
|
|
527
518
|
description: `
|
|
@@ -532,20 +523,20 @@ ${(0, doc_structure_1.block)({
|
|
|
532
523
|
content: `
|
|
533
524
|
A ${linkEdgeName(edge_1.EdgeType.Reads)} edge is not a transitive closure and only links the "directly read" definition(s).
|
|
534
525
|
Our abstract domains resolving transitive ${linkEdgeName(edge_1.EdgeType.Reads)} edges (and for that matter, following ${linkEdgeName(edge_1.EdgeType.Returns)} as well)
|
|
535
|
-
are currently tailored to what we need in _flowR_. Hence, we offer a function like ${
|
|
536
|
-
as well as ${
|
|
537
|
-
Refer to ${
|
|
526
|
+
are currently tailored to what we need in _flowR_. Hence, we offer a function like ${ctx.link(linker_1.getAllFunctionCallTargets)},
|
|
527
|
+
as well as ${ctx.link(resolve_by_name_1.resolvesToBuiltInConstant)} which do this for specific cases.
|
|
528
|
+
Refer to ${ctx.link(dfg_get_origin_1.getOriginInDfg)} for a more general solution, as explained in [working with the dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow%20Graph#working-with-the-dataflow-graph).
|
|
538
529
|
|
|
539
|
-
${(0, doc_structure_1.details)('Example: Multi-Level Reads', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
530
|
+
${(0, doc_structure_1.details)('Example: Multi-Level Reads', await (0, doc_dfg_1.printDfGraphForCode)(parser, 'x <- 3\ny <- x\nprint(y)', { mark: new Set(['9->7', '7->3', '4->0']) }))}
|
|
540
531
|
|
|
541
532
|
Similarly, ${linkEdgeName(edge_1.EdgeType.Reads)} can be cyclic, for example in the context of loops:
|
|
542
533
|
|
|
543
|
-
${(0, doc_structure_1.details)('Example: Cyclic Reads', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
534
|
+
${(0, doc_structure_1.details)('Example: Cyclic Reads', await (0, doc_dfg_1.printDfGraphForCode)(parser, 'for(i in v) x <- x + 1', { mark: new Set(['3->2']) }))}
|
|
544
535
|
`
|
|
545
536
|
})}
|
|
546
537
|
|
|
547
538
|
Reads edges may point to built-in definitions as well, to signal that something relates to a built-in element of flowR.
|
|
548
|
-
Their targets are not part of the ${
|
|
539
|
+
Their targets are not part of the ${ctx.link(graph_1.DataflowGraph)} but only markers to signal that the respective definition is a built-in.
|
|
549
540
|
|
|
550
541
|
|
|
551
542
|
Please refer to the explanation of the respective vertices for more information.
|
|
@@ -564,12 +555,11 @@ Please refer to the explanation of the respective vertices for more information.
|
|
|
564
555
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().reads('1:20', '1@x')
|
|
565
556
|
}]]);
|
|
566
557
|
edgeExplanations.set(edge_1.EdgeType.DefinedBy, [{
|
|
567
|
-
shell,
|
|
568
558
|
name: 'DefinedBy Edge', /* concat for link generation */
|
|
569
559
|
type: edge_1.EdgeType.DefinedBy,
|
|
570
560
|
description: `
|
|
571
561
|
The source vertex is usually a [\`variable definition\`](#variable-definition-vertex) linking the defined symbol to the entry point of the resulting side.
|
|
572
|
-
${(0, doc_structure_1.details)('In general, this does not have to be the right hand side of the operator.', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
562
|
+
${(0, doc_structure_1.details)('In general, this does not have to be the right hand side of the operator.', await (0, doc_dfg_1.printDfGraphForCode)(parser, '3 -> x', { mark: new Set([0]) }))}
|
|
573
563
|
|
|
574
564
|
However, nested definitions can carry it (in the nested case, \`x\` is defined by the return value of <code>\\\`<-\\\`(y, z)</code>). Additionally, we link the assignment function.
|
|
575
565
|
|
|
@@ -588,16 +578,14 @@ However, nested definitions can carry it (in the nested case, \`x\` is defined b
|
|
|
588
578
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().definedBy('1@x', '1:8')
|
|
589
579
|
}]]);
|
|
590
580
|
edgeExplanations.set(edge_1.EdgeType.Calls, [{
|
|
591
|
-
shell,
|
|
592
581
|
name: 'Calls Edge',
|
|
593
582
|
type: edge_1.EdgeType.Calls,
|
|
594
583
|
description: `Link the [function call](#function-call-vertex) to the [function definition](#function-definition-vertex) that is called. To find all called definitions,
|
|
595
|
-
please use the ${
|
|
584
|
+
please use the ${ctx.link(dfg_get_origin_1.getOriginInDfg.name)} function, as explained in [working with the dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Working%20with%20the%20Dataflow%20Graph).`,
|
|
596
585
|
code: 'foo <- function() {}\nfoo()',
|
|
597
586
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().calls('2@foo', '1@function')
|
|
598
587
|
}, []]);
|
|
599
588
|
edgeExplanations.set(edge_1.EdgeType.Returns, [{
|
|
600
|
-
shell,
|
|
601
589
|
name: 'Returns Edge',
|
|
602
590
|
type: edge_1.EdgeType.Returns,
|
|
603
591
|
description: `Link the [function call](#function-call-vertex) to the exit points of the target definition (this may incorporate the call-context).
|
|
@@ -605,17 +593,17 @@ As you can see in the example, this happens for user-defined functions (like \`f
|
|
|
605
593
|
However, these edges are specific to scenarios in which flowR knows that a specific element is returned.
|
|
606
594
|
For contrast, compare this to a use of, for example, \`+\`:
|
|
607
595
|
|
|
608
|
-
${(0, doc_structure_1.details)('Example: No returns edge for +', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
596
|
+
${(0, doc_structure_1.details)('Example: No returns edge for +', await (0, doc_dfg_1.printDfGraphForCode)(parser, '1 + 1'))}
|
|
609
597
|
|
|
610
598
|
Here, we do not get a ${linkEdgeName(edge_1.EdgeType.Returns)} edge as this function call creates a new value based on its arguments.
|
|
611
|
-
In these scenarios you should rely on the \`args\` property of the ${
|
|
599
|
+
In these scenarios you should rely on the \`args\` property of the ${ctx.link('DataflowGraphVertexFunctionCall')}
|
|
612
600
|
and use the arguments to calculate what you need to know. Alternatively, you can track the ${linkEdgeName(edge_1.EdgeType.Argument)} edges.
|
|
613
601
|
|
|
614
602
|
In general, the ${linkEdgeName(edge_1.EdgeType.Returns)} edge already does most of the heavy lifting for you, by respecting control flow influences and
|
|
615
603
|
(as long as flowR is able to detect it) dead code.
|
|
616
604
|
|
|
617
605
|
${(0, doc_structure_1.details)('Example: Tricky Returns', `We show the _simplified_ DFG for simplicity and highlight all ${linkEdgeName(edge_1.EdgeType.Returns)} edges involved in tracking the return of a call to \`f\` (as ${linkEdgeName(edge_1.EdgeType.Returns)} are never transitive and must hence be followed):\n` +
|
|
618
|
-
await (0, doc_dfg_1.printDfGraphForCode)(
|
|
606
|
+
await (0, doc_dfg_1.printDfGraphForCode)(parser, 'f <- function() { if(u) { return(3); 2 } else 42 }\nf()', {
|
|
619
607
|
simplified: true,
|
|
620
608
|
mark: new Set(['19->15', '15->14', '14->12', '14->11', '11->9', '9->7'])
|
|
621
609
|
})
|
|
@@ -640,9 +628,8 @@ f <- function() x
|
|
|
640
628
|
x <- 3
|
|
641
629
|
f()
|
|
642
630
|
`.trim();
|
|
643
|
-
const dfInfo = await (0, doc_dfg_1.printDfGraphForCode)(
|
|
631
|
+
const dfInfo = await (0, doc_dfg_1.printDfGraphForCode)(parser, lateBindingExample, { switchCodeAndGraph: true, codeOpen: true, mark: new Set([1, '1->5', '9->5']) });
|
|
644
632
|
edgeExplanations.set(edge_1.EdgeType.DefinesOnCall, [{
|
|
645
|
-
shell,
|
|
646
633
|
name: 'DefinesOnCall Edge',
|
|
647
634
|
type: edge_1.EdgeType.DefinesOnCall,
|
|
648
635
|
description: `*This edge is usually joined with ${linkEdgeName(edge_1.EdgeType.DefinedByOnCall)}!*
|
|
@@ -666,7 +653,6 @@ ${dfInfo}
|
|
|
666
653
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().definesOnCall('$11', '$1').definedByOnCall('$1', '$11')
|
|
667
654
|
}, []]);
|
|
668
655
|
edgeExplanations.set(edge_1.EdgeType.DefinedByOnCall, [{
|
|
669
|
-
shell,
|
|
670
656
|
name: 'DefinedByOnCall Edge',
|
|
671
657
|
type: edge_1.EdgeType.DefinedByOnCall,
|
|
672
658
|
description: `*This edge is usually joined with ${linkEdgeName(edge_1.EdgeType.DefinesOnCall)}!*
|
|
@@ -676,7 +662,6 @@ ${dfInfo}
|
|
|
676
662
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().definesOnCall('$11', '$1').definedByOnCall('$1', '$11')
|
|
677
663
|
}, []]);
|
|
678
664
|
edgeExplanations.set(edge_1.EdgeType.Argument, [{
|
|
679
|
-
shell,
|
|
680
665
|
name: 'Argument Edge',
|
|
681
666
|
type: edge_1.EdgeType.Argument,
|
|
682
667
|
description: `Links a [function call](#function-call-vertex) to the entry point of its arguments. If we do not know the target of such a call, we automatically assume that all arguments are read by the call as well!
|
|
@@ -687,7 +672,6 @@ The exception to this is the [function definition](#function-definition-vertex)
|
|
|
687
672
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().argument('1@f', '1@x').reads('1@f', '1@x').argument('1@f', '1@y').reads('1@f', '1@y')
|
|
688
673
|
}, []]);
|
|
689
674
|
edgeExplanations.set(edge_1.EdgeType.SideEffectOnCall, [{
|
|
690
|
-
shell,
|
|
691
675
|
name: 'SideEffectOnCall Edge',
|
|
692
676
|
type: edge_1.EdgeType.SideEffectOnCall,
|
|
693
677
|
description: 'Links a global side effect to an affected function call (e.g., a super definition within the function body)',
|
|
@@ -695,7 +679,6 @@ The exception to this is the [function definition](#function-definition-vertex)
|
|
|
695
679
|
expectedSubgraph: (0, dataflowgraph_builder_1.emptyGraph)().sideEffectOnCall('1@x', '2@f')
|
|
696
680
|
}, []]);
|
|
697
681
|
edgeExplanations.set(edge_1.EdgeType.NonStandardEvaluation, [{
|
|
698
|
-
shell,
|
|
699
682
|
name: 'NonStandardEvaluation Edge',
|
|
700
683
|
type: edge_1.EdgeType.NonStandardEvaluation,
|
|
701
684
|
description: `
|
|
@@ -712,9 +695,8 @@ Yet, you may choose to follow these references for other queries. For now, _flow
|
|
|
712
695
|
Besides the obvious quotation there are other cases in which _flowR_ may choose to create a ${linkEdgeName(edge_1.EdgeType.NonStandardEvaluation)} edge, there are
|
|
713
696
|
some that may appear to be counter-intuitive. For example, a for-loop body, as in the following example.
|
|
714
697
|
|
|
715
|
-
${(0, doc_structure_1.details)('Example: For-Loop Body', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
716
|
-
${(0, doc_structure_1.details)('Example: While-Loop Body', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
717
|
-
|
|
698
|
+
${(0, doc_structure_1.details)('Example: For-Loop Body', await (0, doc_dfg_1.printDfGraphForCode)(parser, 'for(i in v) b', { mark: new Set([2, '4->2']) }))}
|
|
699
|
+
${(0, doc_structure_1.details)('Example: While-Loop Body', await (0, doc_dfg_1.printDfGraphForCode)(parser, 'while(TRUE) b', { mark: new Set([1, '3->1']) }))}
|
|
718
700
|
`
|
|
719
701
|
})}
|
|
720
702
|
`,
|
|
@@ -735,33 +717,28 @@ ${(0, doc_structure_1.details)('Example: While-Loop Body', await (0, doc_dfg_1.p
|
|
|
735
717
|
const get = edgeExplanations.get(edge);
|
|
736
718
|
(0, assert_1.guard)(get !== undefined, () => `No explanation for edge type ${edge}`);
|
|
737
719
|
const [expl, subExplanations] = get;
|
|
738
|
-
results.push(`<a id='${edgeTypeToId(edge)}'></a>` + await explanation(expl, ++i, ...subExplanations));
|
|
720
|
+
results.push(`<a id='${edgeTypeToId(edge)}'></a>` + await explanation(expl, parser, ++i, ...subExplanations));
|
|
739
721
|
}
|
|
740
722
|
return results.join('\n');
|
|
741
723
|
}
|
|
742
724
|
async function dummyDataflow() {
|
|
743
|
-
const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder(
|
|
725
|
+
const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder().build();
|
|
726
|
+
analyzer.addRequest('x <- 1\nx + 1');
|
|
744
727
|
const result = await analyzer.dataflow();
|
|
745
728
|
analyzer.close();
|
|
746
729
|
return result;
|
|
747
730
|
}
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
})
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
inlineTypes: ['MergeableRecord']
|
|
760
|
-
});
|
|
761
|
-
return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'dataflow graph', rVersion: rversion })}
|
|
762
|
-
|
|
763
|
-
This page briefly summarizes flowR's dataflow graph, represented by the ${(0, doc_types_1.shortLink)(graph_1.DataflowGraph.name, vertexType.info)} class within the code.
|
|
764
|
-
In case you want to manually build such a graph (e.g., for testing), you can use the ${(0, doc_types_1.shortLink)(dataflowgraph_builder_1.DataflowGraphBuilder.name, vertexType.info)}.
|
|
731
|
+
/**
|
|
732
|
+
* https://github.com/flowr-analysis/flowr/wiki/Dataflow-Graph
|
|
733
|
+
*/
|
|
734
|
+
class WikiDataflowGraph extends doc_maker_1.DocMaker {
|
|
735
|
+
constructor() {
|
|
736
|
+
super('wiki/Dataflow Graph.md', module.filename, 'dataflow graph');
|
|
737
|
+
}
|
|
738
|
+
async text({ ctx, treeSitter }) {
|
|
739
|
+
return `
|
|
740
|
+
This page briefly summarizes flowR's dataflow graph, represented by the ${ctx.link(graph_1.DataflowGraph)} class within the code.
|
|
741
|
+
In case you want to manually build such a graph (e.g., for testing), you can use the ${ctx.link(dataflowgraph_builder_1.DataflowGraphBuilder)}.
|
|
765
742
|
If you are interested in which features we support and which features are still to be worked on, please refer to our [capabilities](${doc_files_1.FlowrWikiBaseRef}/Capabilities) page.
|
|
766
743
|
In summary, we discuss the following topics:
|
|
767
744
|
|
|
@@ -772,7 +749,7 @@ In summary, we discuss the following topics:
|
|
|
772
749
|
- [Unknown Side Effects](#unknown-side-effects)
|
|
773
750
|
- [Working with the Dataflow Graph](#dfg-working)
|
|
774
751
|
|
|
775
|
-
Please be aware that the accompanied [dataflow information](#dataflow-information) (${
|
|
752
|
+
Please be aware that the accompanied [dataflow information](#dataflow-information) (${ctx.link('DataflowInformation')}) returned by _flowR_ contains things besides the graph,
|
|
776
753
|
like the entry and exit points of the subgraphs, and currently active references (see [below](#dataflow-information)).
|
|
777
754
|
Additionally, you may be interested in the set of [Unknown Side Effects](#unknown-side-effects), marking calls which _flowR_ is unable to handle correctly.
|
|
778
755
|
|
|
@@ -786,11 +763,11 @@ wiki page if you are unsure.
|
|
|
786
763
|
> There is also a simplified perspective available with ${(0, doc_cli_option_1.getReplCommand)('dataflowsimple*')} that does not show everything but is easier to read.
|
|
787
764
|
> When using _flowR_ as a library, you may use the functions in ${(0, doc_files_1.getFilePathMd)('../util/mermaid/dfg.ts')}.
|
|
788
765
|
>
|
|
789
|
-
> If you receive a dataflow graph in its serialized form (e.g., by talking to a [_flowR_ server](${doc_files_1.FlowrWikiBaseRef}/Interface)), you can use ${
|
|
766
|
+
> If you receive a dataflow graph in its serialized form (e.g., by talking to a [_flowR_ server](${doc_files_1.FlowrWikiBaseRef}/Interface)), you can use ${ctx.link(`${graph_1.DataflowGraph.name}::${graph_1.DataflowGraph.fromJson.name}`, { realNameWrapper: 'i', codeFont: true })} to retrieve the graph from the JSON representation.
|
|
790
767
|
>
|
|
791
768
|
> Also, check out the [${doc_files_1.FlowrGithubGroupName}/sample-analyzer-df-diff](${doc_files_1.FlowrGithubBaseRef}/sample-analyzer-df-diff) repository for a complete example project creating and comparing dataflow graphs.
|
|
792
769
|
|
|
793
|
-
${await (0, doc_dfg_1.printDfGraphForCode)(
|
|
770
|
+
${await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'x <- 3\ny <- x + 1\ny')}
|
|
794
771
|
|
|
795
772
|
|
|
796
773
|
The above dataflow graph showcases the general gist. We define a dataflow graph as a directed graph G = (V, E), differentiating between ${(0, doc_data_dfg_util_1.getAllVertices)().length} types of vertices V and
|
|
@@ -806,7 +783,7 @@ The following vertices types exist:
|
|
|
806
783
|
|
|
807
784
|
1. ${(0, doc_data_dfg_util_1.getAllVertices)().map(([k, v], index) => `[\`${k}\`](#${index + 1}-${v.toLowerCase().replace(/\s/g, '-')}-vertex)`).join('\n1. ')}
|
|
808
785
|
|
|
809
|
-
${
|
|
786
|
+
${(0, doc_structure_1.details)('Class Diagram', 'All boxes should link to their respective implementation:\n' + (0, doc_code_1.codeBlock)('mermaid', ctx.mermaid('DataflowGraphVertexInfo', ['MergeableRecord'])))}
|
|
810
787
|
|
|
811
788
|
</details>
|
|
812
789
|
|
|
@@ -818,7 +795,7 @@ The following edges types exist, internally we use bitmasks to represent multipl
|
|
|
818
795
|
|
|
819
796
|
1. ${(0, doc_data_dfg_util_1.getAllEdges)().map(([k, v], index) => `[\`${k}\` (${v})](#${index + 1}-${k.toLowerCase().replace(/\s/g, '-')}-edge)`).join('\n1. ')}
|
|
820
797
|
|
|
821
|
-
${
|
|
798
|
+
${(0, doc_structure_1.details)('Class Diagram', 'All boxes should link to their respective implementation:\n' + (0, doc_code_1.codeBlock)('mermaid', ctx.mermaid('EdgeType', ['MergeableRecord'])))}
|
|
822
799
|
|
|
823
800
|
</details>
|
|
824
801
|
|
|
@@ -830,9 +807,9 @@ The following sections present details on the different types of vertices and ed
|
|
|
830
807
|
> [!NOTE]
|
|
831
808
|
> Every dataflow vertex holds an \`id\` which links it to the respective node in the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized-AST).
|
|
832
809
|
> So if you want more information about the respective vertex, you can usually access more information
|
|
833
|
-
> using the <code>${
|
|
810
|
+
> using the <code>${ctx.link(`${graph_1.DataflowGraph.name}`, { codeFont: false, realNameWrapper: 'i' })}::idMap</code> linked to the dataflow graph:
|
|
834
811
|
${(0, doc_general_1.prefixLines)((0, doc_code_1.codeBlock)('ts', 'const node = graph.idMap.get(id);'), '> ')}
|
|
835
|
-
> In case you just need the name (\`lexeme\`) of the respective vertex, ${
|
|
812
|
+
> In case you just need the name (\`lexeme\`) of the respective vertex, ${ctx.link(node_id_1.recoverName)} can help you out:
|
|
836
813
|
${(0, doc_general_1.prefixLines)((0, doc_code_1.codeBlock)('ts', `const name = ${node_id_1.recoverName.name}(id, graph.idMap);`), '> ')}
|
|
837
814
|
>
|
|
838
815
|
> Please note, that not every node in the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized-AST) is represented in the dataflow graph.
|
|
@@ -846,32 +823,32 @@ ${(0, doc_structure_1.section)('Vertices', 2, 'vertices')}
|
|
|
846
823
|
|
|
847
824
|
1. ${(0, doc_data_dfg_util_1.getAllVertices)().map(([k, v], index) => `[\`${k}\`](#${index + 1}-${v.toLowerCase().replace(/\s/g, '-')}-vertex)`).join('\n1. ')}
|
|
848
825
|
|
|
849
|
-
${await getVertexExplanations(
|
|
826
|
+
${await getVertexExplanations(treeSitter, ctx)}
|
|
850
827
|
|
|
851
828
|
${(0, doc_structure_1.section)('Edges', 2, 'edges')}
|
|
852
829
|
|
|
853
830
|
1. ${(0, doc_data_dfg_util_1.getAllEdges)().map(([k, v], index) => `[\`${k}\` (${v})](#${index + 1}-${k.toLowerCase().replace(/\s/g, '-')}-edge)`).join('\n1. ')}
|
|
854
831
|
|
|
855
|
-
${await getEdgesExplanations(
|
|
832
|
+
${await getEdgesExplanations(treeSitter, ctx)}
|
|
856
833
|
|
|
857
834
|
${(0, doc_structure_1.section)('Control Dependencies', 2, 'control-dependencies')}
|
|
858
835
|
|
|
859
836
|
Each vertex may have a list of active control dependencies.
|
|
860
|
-
They hold the ${
|
|
837
|
+
They hold the ${ctx.link('NodeId')} of all nodes that effect if the current vertex is part of the execution or not,
|
|
861
838
|
and a boolean flag \`when\` to indicate if the control dependency is active when the condition is \`true\` or \`false\`.
|
|
862
839
|
|
|
863
840
|
As an example, consider the following dataflow graph:
|
|
864
841
|
|
|
865
|
-
${await (0, doc_dfg_1.printDfGraphForCode)(
|
|
842
|
+
${await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'if(p) a else b')}
|
|
866
843
|
|
|
867
844
|
Whenever we visualize a graph, we represent the control dependencies as grayed out edges with a \`CD\` prefix, followed
|
|
868
845
|
by the \`when\` flag.
|
|
869
846
|
In the above example, both \`a\` and \`b\` depend on the \`if\`. Please note that they are _not_ linked to the result of
|
|
870
847
|
the condition itself as this is the more general linkage point (and harmonizes with other control structures, especially those which are user-defined).
|
|
871
848
|
|
|
872
|
-
${(0, doc_structure_1.details)('Example: Multiple Vertices (Assignment)', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
873
|
-
${(0, doc_structure_1.details)('Example: Multiple Vertices (Arithmetic Expression)', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
874
|
-
${(0, doc_structure_1.details)('Example: Nested Conditionals', await (0, doc_dfg_1.printDfGraphForCode)(
|
|
849
|
+
${(0, doc_structure_1.details)('Example: Multiple Vertices (Assignment)', await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'if(p) a <- 1'))}
|
|
850
|
+
${(0, doc_structure_1.details)('Example: Multiple Vertices (Arithmetic Expression)', await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'if(p) 3 + 2'))}
|
|
851
|
+
${(0, doc_structure_1.details)('Example: Nested Conditionals', await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'if(x) { if(y) a else b } else c'))}
|
|
875
852
|
|
|
876
853
|
|
|
877
854
|
${(0, doc_structure_1.section)('Dataflow Information', 2, 'dataflow-information')}
|
|
@@ -898,9 +875,9 @@ ${(0, doc_code_1.codeBlock)('ts', dummyDataflow.toString())}
|
|
|
898
875
|
Now, you can find the dataflow _information_ with \`result.dataflow\`. More specifically, the graph is stored in \`result.dataflow.graph\` and looks like this:
|
|
899
876
|
|
|
900
877
|
${await (async () => {
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
878
|
+
const result = await dummyDataflow();
|
|
879
|
+
const dfGraphString = (0, doc_dfg_1.printDfGraph)(result.graph);
|
|
880
|
+
return `
|
|
904
881
|
${dfGraphString}
|
|
905
882
|
|
|
906
883
|
However, the dataflow information contains more, quite a lot of information in fact.
|
|
@@ -916,15 +893,15 @@ ${(0, doc_code_1.codeBlock)('text', JSON.stringify(result, json_1.jsonReplacer))
|
|
|
916
893
|
|
|
917
894
|
You may be interested in its implementation:
|
|
918
895
|
|
|
919
|
-
${
|
|
896
|
+
${ctx.hierarchy('DataflowInformation')}
|
|
920
897
|
|
|
921
898
|
Let's start by looking at the properties of the dataflow information object: ${Object.keys(result).map(k => `\`${k}\``).join(', ')}.
|
|
922
899
|
|
|
923
900
|
${(() => {
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
901
|
+
/* this includes the meta field for timing and the quick CFG in order to enable re-use and improve performance */
|
|
902
|
+
(0, assert_1.guard)(Object.keys(result).length === 9, () => 'Update Dataflow Documentation!');
|
|
903
|
+
return '';
|
|
904
|
+
})()}
|
|
928
905
|
|
|
929
906
|
There are three sets of references.
|
|
930
907
|
**in** (ids: ${JSON.stringify(new Set(result.in.map(n => n.nodeId)), json_1.jsonReplacer)}) and **out** (ids: ${JSON.stringify(new Set(result.out.map(n => n.nodeId)), json_1.jsonReplacer)}) contain the
|
|
@@ -951,7 +928,7 @@ In case _flowR_ encounters a function call that it cannot handle, it marks the c
|
|
|
951
928
|
You can find these as part of the dataflow graph, specifically as \`unknownSideEffects\` (with a leading underscore if sesrialized as JSON).
|
|
952
929
|
In the following graph, _flowR_ realizes that it is unable to correctly handle the impacts of the \`load\` call and therefore marks it as such (marked in bright red):
|
|
953
930
|
|
|
954
|
-
${await (0, doc_dfg_1.printDfGraphForCode)(
|
|
931
|
+
${await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'load("file")\nprint(x + y)')}
|
|
955
932
|
|
|
956
933
|
In general, as we cannot handle these correctly, we leave it up to other analyses (and [queries](${doc_files_1.FlowrWikiBaseRef}/Query%20API)) to handle these cases
|
|
957
934
|
as they see fit.
|
|
@@ -963,27 +940,27 @@ Consider R's basic [\`graphics\`](https://www.rdocumentation.org/packages/graphi
|
|
|
963
940
|
implicitly draws on the current device and does not explicitly link a function like \`points\` to the last call opening a new graphic device. In such a scenario, we use a linked side effect to mark the relation:
|
|
964
941
|
|
|
965
942
|
${await (async () => {
|
|
966
|
-
|
|
967
|
-
|
|
943
|
+
const [result, df] = await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'plot(data)\npoints(data2)', { exposeResult: true });
|
|
944
|
+
return `
|
|
968
945
|
${result}
|
|
969
946
|
|
|
970
947
|
Such side effects are not marked explicitly (with a big edge) but they are part of the unknown side effects: [${[...df.dataflow.graph.unknownSideEffects].map(doc_dfg_1.formatSideEffect).join(',')}].
|
|
971
948
|
Additionally, we express this by a ${linkEdgeName(edge_1.EdgeType.Reads)} edge.
|
|
972
949
|
`;
|
|
973
|
-
|
|
950
|
+
})()}
|
|
974
951
|
|
|
975
952
|
${(0, doc_structure_1.section)('Working with the Dataflow Graph', 2, 'dfg-working')}
|
|
976
953
|
|
|
977
|
-
The ${
|
|
954
|
+
The ${ctx.link('DataflowInformation')} is the core result of _flowR_ and summarizes a lot of information.
|
|
978
955
|
Depending on what you are interested in, there exists a plethora of functions and queries to help you out, answering the most important questions:
|
|
979
956
|
|
|
980
957
|
* The **[Query API](${doc_files_1.FlowrWikiBaseRef}/Query%20API)** provides many functions to query the dataflow graph for specific information (dependencies, calls, slices, clusters, ...)
|
|
981
958
|
* The **[Search API](${doc_files_1.FlowrWikiBaseRef}/Search%20API)** allows you to search for specific vertices or edges in the dataflow graph or the original program
|
|
982
|
-
* ${
|
|
983
|
-
* ${
|
|
984
|
-
* ${
|
|
985
|
-
* ${
|
|
986
|
-
* ${
|
|
959
|
+
* ${ctx.link(node_id_1.recoverName.name)} and ${ctx.link(node_id_1.recoverContent.name)} to get the name or content of a vertex in the dataflow graph
|
|
960
|
+
* ${ctx.link(alias_tracking_1.resolveIdToValue.name)} to resolve the value of a variable or id (if possible, see [below](#dfg-resolving-values))
|
|
961
|
+
* ${ctx.link(edge_1.edgeIncludesType.name)} to check if an edge includes a specific type and ${ctx.link(edge_1.splitEdgeTypes.name)} to split the bitmask of edges into its types (see [below](#dfg-resolving-values))
|
|
962
|
+
* ${ctx.link(identify_link_to_last_call_relation_1.getValueOfArgument.name)} to get the (syntactical) value of an argument in a function call
|
|
963
|
+
* ${ctx.link(dfg_get_origin_1.getOriginInDfg.name)} to get information about where a read, call, ... comes from (see [below](#dfg-resolving-values))
|
|
987
964
|
|
|
988
965
|
Some of these functions have been explained in their respective wiki pages. However, some are part of the [Dataflow Graph API](${doc_files_1.FlowrWikiBaseRef}/Dataflow-Graph) and so we explain them here.
|
|
989
966
|
If you are interested in which features we support and which features are still to be worked on, please refer to our [capabilities](${doc_files_1.FlowrWikiBaseRef}/Capabilities) page.
|
|
@@ -993,12 +970,12 @@ ${(0, doc_structure_1.section)('Resolving Values', 3, 'dfg-resolving-values')}
|
|
|
993
970
|
FlowR supports a [configurable](${doc_files_1.FlowrWikiBaseRef}/Interface#configuring-flowr) level of value tracking—all with the goal of knowing the static value domain of a variable.
|
|
994
971
|
These capabilities are exposed by the [resolve value Query](${doc_files_1.FlowrWikiBaseRef}/Query-API#resolve-value-query) and backed by two important functions:
|
|
995
972
|
|
|
996
|
-
${
|
|
973
|
+
${ctx.link(alias_tracking_1.resolveIdToValue.name)} provides an environment-sensitive (see ${ctx.link('REnvironmentInformation')})
|
|
997
974
|
value resolution depending on if the environment is provided.
|
|
998
|
-
The idea of ${
|
|
975
|
+
The idea of ${ctx.link(alias_tracking_1.resolveIdToValue.name)} is to provide a compromise between precision and performance, to
|
|
999
976
|
be used _during_ and _after_ the core analysis. After the dataflow analysis completes, there are much more expensive queries possible (such as the resolution of the data frame shape, see the [Query API](${doc_files_1.FlowrWikiBaseRef}/Query-API)).
|
|
1000
977
|
|
|
1001
|
-
Additionally, to ${
|
|
978
|
+
Additionally, to ${ctx.link(alias_tracking_1.resolveIdToValue.name)}, we offer the aforementioned ${ctx.link(identify_link_to_last_call_relation_1.getValueOfArgument.name)} to retrieve the value of an argument in a function call.
|
|
1002
979
|
Be aware, that this function is currently not optimized for speed, so if you frequently require the values of multiple arguments of the same function call, you may want to open [an issue](${doc_issue_1.NewIssueUrl}) to request support for resolving
|
|
1003
980
|
multiple arguments at once.
|
|
1004
981
|
|
|
@@ -1008,54 +985,46 @@ The [edges](#edges) of the dataflow graph use bitmasks to represent an edge with
|
|
|
1008
985
|
difficult to check whether a given edge is a read edge.
|
|
1009
986
|
Consider the following example:
|
|
1010
987
|
|
|
1011
|
-
${await (0, doc_dfg_1.printDfGraphForCode)(
|
|
988
|
+
${await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'print(x)', { mark: new Set(['3->1']) })}
|
|
1012
989
|
|
|
1013
990
|
Retrieving the _types_ of the edge from the print call to its argument returns:
|
|
1014
991
|
${await (async () => {
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
992
|
+
const dfg = await (0, default_pipelines_1.createDataflowPipeline)(treeSitter, {
|
|
993
|
+
context: (0, flowr_analyzer_context_1.contextFromInput)('print(x)')
|
|
994
|
+
}).allRemainingSteps();
|
|
995
|
+
const edge = dfg.dataflow.graph.outgoingEdges(3);
|
|
996
|
+
if (edge) {
|
|
997
|
+
const wanted = edge.get(1);
|
|
998
|
+
if (wanted) {
|
|
999
|
+
return '`' + wanted.types + '`';
|
|
1000
|
+
}
|
|
1023
1001
|
}
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
${(0, doc_types_1.shortLink)(edge_1.edgeIncludesType.name, vertexType.info)} to check whether a specific type (or one of a collection of types) is included in the edge.
|
|
1002
|
+
new Error('Could not find edge');
|
|
1003
|
+
})()}—which is usually not very helpful.
|
|
1004
|
+
You can use ${ctx.link(edge_1.splitEdgeTypes.name)} to get the individual bitmasks of all included types, and
|
|
1005
|
+
${ctx.link(edge_1.edgeIncludesType.name)} to check whether a specific type (or one of a collection of types) is included in the edge.
|
|
1029
1006
|
|
|
1030
1007
|
${(0, doc_structure_1.section)('Handling Origins', 3, 'dfg-handling-origins')}
|
|
1031
1008
|
|
|
1032
1009
|
If you are writing another analysis on top of the dataflow graph, you probably want to know all definitions that serve as the source of a read, all functions
|
|
1033
1010
|
that are called by an invocation, and more.
|
|
1034
|
-
For this, the ${
|
|
1011
|
+
For this, the ${ctx.link(dfg_get_origin_1.getOriginInDfg)} function provides you with a collection of ${ctx.link('Origin')} objects:
|
|
1035
1012
|
|
|
1036
|
-
${
|
|
1013
|
+
${ctx.hierarchy('Origin', { openTop: true })}
|
|
1037
1014
|
|
|
1038
1015
|
Their respective uses are documented alongside their implementation:
|
|
1039
1016
|
|
|
1040
|
-
${['SimpleOrigin', 'FunctionCallOrigin', 'BuiltInFunctionOrigin'].sort().map(key => `- ${
|
|
1017
|
+
${['SimpleOrigin', 'FunctionCallOrigin', 'BuiltInFunctionOrigin'].sort().map(key => `- ${ctx.link(key)}\\\n${ctx.doc(key, { type: 'interface' })}`).join('\n')}
|
|
1041
1018
|
|
|
1042
1019
|
Please note, the current structure of this function is biased by what implementations already exist in flowR.
|
|
1043
1020
|
Hence, we do not just track definitions and constants, but also the origins of function calls, albeit we do not yet track the origins of values (only resorting to
|
|
1044
1021
|
a constant origin). If you are confused by this please start a discussion—in a way we are still deciding on a good API for this.
|
|
1045
1022
|
|
|
1046
1023
|
`;
|
|
1047
|
-
|
|
1024
|
+
})()}
|
|
1048
1025
|
|
|
1049
1026
|
`;
|
|
1027
|
+
}
|
|
1050
1028
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
(0, log_1.setMinLevelOfAllLogs)(6 /* LogLevel.Fatal */);
|
|
1054
|
-
const shell = new shell_1.RShell();
|
|
1055
|
-
void getText(shell).then(str => {
|
|
1056
|
-
console.log(str);
|
|
1057
|
-
}).finally(() => {
|
|
1058
|
-
shell.close();
|
|
1059
|
-
});
|
|
1060
|
-
}
|
|
1061
|
-
//# sourceMappingURL=print-dataflow-graph-wiki.js.map
|
|
1029
|
+
exports.WikiDataflowGraph = WikiDataflowGraph;
|
|
1030
|
+
//# sourceMappingURL=wiki-dataflow-graph.js.map
|