@eagleoutice/flowr 1.3.14 → 1.4.2
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 +3 -3
- package/abstract-interpretation/domain.d.ts +27 -0
- package/abstract-interpretation/domain.js +146 -0
- package/abstract-interpretation/handler/binop/binop.d.ts +16 -0
- package/abstract-interpretation/handler/binop/binop.js +40 -0
- package/abstract-interpretation/handler/binop/operators.d.ts +2 -0
- package/abstract-interpretation/handler/binop/operators.js +42 -0
- package/abstract-interpretation/handler/handler.d.ts +6 -0
- package/abstract-interpretation/handler/handler.js +3 -0
- package/abstract-interpretation/processor.d.ts +10 -0
- package/abstract-interpretation/processor.js +84 -0
- package/benchmark/slicer.d.ts +6 -8
- package/benchmark/slicer.js +5 -15
- package/benchmark/stats/print.d.ts +1 -1
- package/benchmark/stats/print.js +0 -2
- package/benchmark/stats/stats.d.ts +3 -4
- package/benchmark/stats/stats.js +1 -1
- package/cli/benchmark-app.d.ts +1 -0
- package/cli/benchmark-app.js +21 -6
- package/cli/benchmark-helper-app.d.ts +2 -0
- package/cli/benchmark-helper-app.js +15 -6
- package/cli/common/features.d.ts +1 -1
- package/cli/common/options.d.ts +1 -1
- package/cli/common/options.js +4 -1
- package/cli/common/script.d.ts +1 -1
- package/cli/common/scripts-info.d.ts +3 -2
- package/cli/common/scripts-info.js +15 -1
- package/cli/export-quads-app.js +1 -5
- package/cli/repl/commands/cfg.d.ts +1 -1
- package/cli/repl/commands/cfg.js +3 -3
- package/cli/repl/commands/commands.d.ts +4 -2
- package/cli/repl/commands/commands.js +67 -28
- package/cli/repl/commands/dataflow.d.ts +1 -1
- package/cli/repl/commands/dataflow.js +2 -2
- package/cli/repl/commands/execute.d.ts +2 -2
- package/cli/repl/commands/main.d.ts +2 -2
- package/cli/repl/commands/normalize.d.ts +1 -1
- package/cli/repl/commands/normalize.js +2 -2
- package/cli/repl/commands/parse.d.ts +1 -1
- package/cli/repl/commands/parse.js +12 -12
- package/cli/repl/commands/quit.d.ts +1 -1
- package/cli/repl/commands/quit.js +4 -1
- package/cli/repl/commands/version.d.ts +1 -1
- package/cli/repl/core.d.ts +5 -3
- package/cli/repl/core.js +63 -7
- package/cli/repl/execute.d.ts +1 -1
- package/cli/repl/execute.js +3 -3
- package/cli/repl/server/connection.d.ts +2 -2
- package/cli/repl/server/connection.js +4 -8
- package/cli/repl/server/messages/analysis.d.ts +3 -3
- package/cli/repl/server/messages/analysis.js +12 -32
- package/cli/repl/server/messages/error.d.ts +1 -1
- package/cli/repl/server/messages/hello.d.ts +2 -2
- package/cli/repl/server/messages/messages.d.ts +5 -5
- package/cli/repl/server/messages/repl.d.ts +1 -1
- package/cli/repl/server/messages/slice.d.ts +3 -3
- package/cli/repl/server/net.d.ts +16 -0
- package/cli/repl/server/net.js +42 -3
- package/cli/repl/server/send.d.ts +2 -2
- package/cli/repl/server/server.d.ts +2 -2
- package/cli/repl/server/validate.d.ts +3 -3
- package/cli/statistics-helper-app.js +2 -3
- package/cli/summarizer-app.js +1 -2
- package/config.d.ts +16 -0
- package/config.js +75 -0
- package/core/input.d.ts +5 -5
- package/core/output.d.ts +1 -1
- package/core/print/dataflow-printer.d.ts +3 -3
- package/core/print/normalize-printer.d.ts +2 -2
- package/core/print/parse-printer.d.ts +2 -3
- package/core/print/parse-printer.js +6 -4
- package/core/print/print.d.ts +1 -1
- package/core/print/slice-diff-ansi.d.ts +1 -1
- package/core/slicer.d.ts +5 -4
- package/core/slicer.js +2 -2
- package/core/steps.d.ts +10 -9
- package/core/steps.js +5 -4
- package/dataflow/environments/append.d.ts +1 -1
- package/dataflow/environments/environment.d.ts +4 -4
- package/dataflow/environments/environment.js +8 -0
- package/dataflow/environments/overwrite.d.ts +1 -1
- package/dataflow/environments/register.d.ts +2 -2
- package/dataflow/environments/register.js +1 -0
- package/dataflow/environments/resolve-by-name.d.ts +2 -2
- package/dataflow/environments/scoping.d.ts +1 -1
- package/dataflow/extractor.d.ts +5 -5
- package/dataflow/extractor.js +10 -2
- package/dataflow/graph/diff.d.ts +3 -3
- package/dataflow/graph/graph.d.ts +8 -7
- package/dataflow/graph/quads.d.ts +2 -2
- package/dataflow/graph/vertex.d.ts +5 -5
- package/dataflow/internal/info.d.ts +2 -2
- package/dataflow/internal/linker.d.ts +3 -3
- package/dataflow/internal/process/access.d.ts +3 -3
- package/dataflow/internal/process/expression-list.d.ts +3 -3
- package/dataflow/internal/process/expression-list.js +0 -4
- package/dataflow/internal/process/functions/argument.d.ts +4 -4
- package/dataflow/internal/process/functions/exit-points.d.ts +1 -1
- package/dataflow/internal/process/functions/function-call.d.ts +3 -3
- package/dataflow/internal/process/functions/function-call.js +7 -1
- package/dataflow/internal/process/functions/function-definition.d.ts +3 -3
- package/dataflow/internal/process/functions/parameter.d.ts +3 -3
- package/dataflow/internal/process/functions/source.d.ts +8 -0
- package/dataflow/internal/process/functions/source.js +81 -0
- package/dataflow/internal/process/if-then-else.d.ts +3 -3
- package/dataflow/internal/process/loops/for-loop.d.ts +3 -3
- package/dataflow/internal/process/loops/repeat-loop.d.ts +3 -3
- package/dataflow/internal/process/loops/while-loop.d.ts +3 -3
- package/dataflow/internal/process/operators/assignment.d.ts +3 -3
- package/dataflow/internal/process/operators/non-assignment-binary-op.d.ts +3 -3
- package/dataflow/internal/process/operators/pipe.d.ts +3 -3
- package/dataflow/internal/process/operators/unary-op.d.ts +3 -3
- package/dataflow/internal/process/symbol.d.ts +3 -3
- package/dataflow/internal/process/uninteresting-leaf.d.ts +2 -2
- package/dataflow/processor.d.ts +12 -3
- package/flowr.d.ts +5 -2
- package/flowr.js +19 -12
- package/package.json +50 -18
- package/r-bridge/lang-4.x/ast/index.d.ts +1 -0
- package/r-bridge/lang-4.x/ast/index.js +3 -0
- package/r-bridge/lang-4.x/ast/model/collect.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/model.d.ts +6 -6
- package/r-bridge/lang-4.x/ast/model/nodes/info/index.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/info/r-delimiter.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +4 -4
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +4 -4
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +4 -4
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/operators.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/decorate.d.ts +4 -2
- package/r-bridge/lang-4.x/ast/model/processing/decorate.js +6 -1
- package/r-bridge/lang-4.x/ast/model/processing/fold.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/processing/role.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/model/processing/stateful-fold.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/processing/visitor.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/parser/json/format.d.ts +14 -0
- package/r-bridge/lang-4.x/ast/parser/json/format.js +26 -0
- package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +7 -0
- package/r-bridge/lang-4.x/ast/parser/json/parser.js +57 -0
- package/r-bridge/lang-4.x/ast/parser/xml/data.d.ts +4 -7
- package/r-bridge/lang-4.x/ast/parser/xml/hooks.d.ts +5 -5
- package/r-bridge/lang-4.x/ast/parser/xml/index.d.ts +0 -2
- package/r-bridge/lang-4.x/ast/parser/xml/index.js +0 -2
- package/r-bridge/lang-4.x/ast/parser/xml/input-format.d.ts +6 -2
- package/r-bridge/lang-4.x/ast/parser/xml/input-format.js +7 -10
- package/r-bridge/lang-4.x/ast/parser/xml/internal/access.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/access.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/control/if-then-else.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/control/if-then-else.js +1 -1
- package/r-bridge/lang-4.x/ast/parser/xml/internal/control/if-then.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/control/if-then.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/expression/expression.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/expression/expression.js +4 -4
- package/r-bridge/lang-4.x/ast/parser/xml/internal/functions/argument.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/functions/argument.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/functions/call.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/functions/call.js +4 -4
- package/r-bridge/lang-4.x/ast/parser/xml/internal/functions/definition.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/functions/definition.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/functions/parameter.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/functions/parameter.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/index.d.ts +0 -1
- package/r-bridge/lang-4.x/ast/parser/xml/internal/index.js +0 -1
- package/r-bridge/lang-4.x/ast/parser/xml/internal/loops/break.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/loops/break.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/loops/for.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/loops/for.js +3 -6
- package/r-bridge/lang-4.x/ast/parser/xml/internal/loops/next.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/loops/next.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/loops/repeat.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/loops/repeat.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/loops/while.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/loops/while.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/meta.d.ts +9 -14
- package/r-bridge/lang-4.x/ast/parser/xml/internal/meta.js +15 -23
- package/r-bridge/lang-4.x/ast/parser/xml/internal/operators/binary.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/operators/binary.js +6 -6
- package/r-bridge/lang-4.x/ast/parser/xml/internal/operators/special.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/parser/xml/internal/operators/unary.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/operators/unary.js +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/other/comment.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/other/comment.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/other/line-directive.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/other/line-directive.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/structure/elements.d.ts +4 -4
- package/r-bridge/lang-4.x/ast/parser/xml/internal/structure/elements.js +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/structure/root.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/structure/root.js +3 -4
- package/r-bridge/lang-4.x/ast/parser/xml/internal/structure/single-element.d.ts +4 -4
- package/r-bridge/lang-4.x/ast/parser/xml/internal/structure/single-element.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/values/number.d.ts +4 -4
- package/r-bridge/lang-4.x/ast/parser/xml/internal/values/number.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/values/string.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/values/string.js +2 -2
- package/r-bridge/lang-4.x/ast/parser/xml/internal/values/symbol.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/parser/xml/internal/values/symbol.js +4 -4
- package/r-bridge/lang-4.x/values.d.ts +0 -1
- package/r-bridge/lang-4.x/values.js +14 -6
- package/r-bridge/retriever.d.ts +26 -22
- package/r-bridge/retriever.js +73 -23
- package/r-bridge/shell-executor.d.ts +11 -0
- package/r-bridge/shell-executor.js +50 -0
- package/r-bridge/shell.d.ts +12 -31
- package/r-bridge/shell.js +36 -94
- package/reconstruct/reconstruct.d.ts +1 -1
- package/slicing/criterion/collect-all.d.ts +3 -3
- package/slicing/criterion/filters/all-variables.d.ts +1 -1
- package/slicing/criterion/parse.d.ts +1 -1
- package/slicing/static/static-slicer.d.ts +3 -3
- package/statistics/features/common-syntax-probability.d.ts +3 -2
- package/statistics/features/common-syntax-probability.js +0 -3
- package/statistics/features/feature.d.ts +6 -6
- package/statistics/features/post-processing.d.ts +2 -2
- package/statistics/features/supported/assignments/assignments.d.ts +2 -2
- package/statistics/features/supported/assignments/post-process.d.ts +2 -2
- package/statistics/features/supported/assignments/post-process.js +6 -6
- package/statistics/features/supported/comments/comments.d.ts +2 -2
- package/statistics/features/supported/comments/post-process.d.ts +2 -2
- package/statistics/features/supported/comments/post-process.js +2 -2
- package/statistics/features/supported/control-flow/control-flow.d.ts +2 -2
- package/statistics/features/supported/control-flow/post-process.d.ts +2 -2
- package/statistics/features/supported/data-access/data-access.d.ts +3 -3
- package/statistics/features/supported/data-access/post-process.d.ts +2 -2
- package/statistics/features/supported/data-access/post-process.js +4 -4
- package/statistics/features/supported/defined-functions/defined-functions.d.ts +4 -4
- package/statistics/features/supported/defined-functions/post-process.d.ts +2 -2
- package/statistics/features/supported/defined-functions/post-process.js +4 -4
- package/statistics/features/supported/expression-list/expression-list.d.ts +2 -2
- package/statistics/features/supported/expression-list/post-process.d.ts +2 -2
- package/statistics/features/supported/expression-list/post-process.js +3 -3
- package/statistics/features/supported/loops/loops.d.ts +2 -2
- package/statistics/features/supported/loops/post-process.d.ts +2 -2
- package/statistics/features/supported/loops/post-process.js +3 -3
- package/statistics/features/supported/used-functions/post-process.d.ts +2 -2
- package/statistics/features/supported/used-functions/post-process.js +5 -5
- package/statistics/features/supported/used-functions/used-functions.d.ts +3 -3
- package/statistics/features/supported/used-packages/post-process.d.ts +2 -2
- package/statistics/features/supported/used-packages/post-process.js +5 -5
- package/statistics/features/supported/used-packages/used-packages.d.ts +2 -2
- package/statistics/features/supported/values/post-process.d.ts +2 -2
- package/statistics/features/supported/values/post-process.js +3 -3
- package/statistics/features/supported/values/values.d.ts +2 -2
- package/statistics/features/supported/variables/post-process.d.ts +3 -3
- package/statistics/features/supported/variables/post-process.js +3 -3
- package/statistics/features/supported/variables/variables.d.ts +2 -2
- package/statistics/meta-statistics.d.ts +1 -1
- package/statistics/output/ansi.js +1 -1
- package/statistics/output/print-stats.d.ts +2 -2
- package/statistics/output/statistics-file.d.ts +1 -1
- package/statistics/statistics.d.ts +4 -4
- package/statistics/statistics.js +7 -8
- package/util/args.d.ts +8 -4
- package/util/args.js +11 -4
- package/util/{cfg.d.ts → cfg/cfg.d.ts} +18 -6
- package/util/{cfg.js → cfg/cfg.js} +42 -37
- package/util/cfg/visitor.d.ts +14 -0
- package/util/cfg/visitor.js +64 -0
- package/util/diff.d.ts +1 -1
- package/util/files.d.ts +7 -1
- package/util/files.js +11 -1
- package/util/log.js +3 -0
- package/util/mermaid/ast.d.ts +1 -1
- package/util/mermaid/cfg.d.ts +2 -2
- package/util/mermaid/dfg.d.ts +3 -3
- package/util/objects.d.ts +1 -1
- package/util/quads.d.ts +2 -2
- package/util/summarizer/benchmark/data.d.ts +1 -1
- package/util/summarizer/benchmark/first-phase/input.d.ts +2 -1
- package/util/summarizer/benchmark/first-phase/input.js +20 -4
- package/util/summarizer/benchmark/first-phase/process.d.ts +4 -3
- package/util/summarizer/benchmark/first-phase/process.js +14 -5
- package/util/summarizer/benchmark/second-phase/graph.d.ts +1 -1
- package/util/summarizer/benchmark/second-phase/graph.js +1 -1
- package/util/summarizer/benchmark/second-phase/process.d.ts +3 -1
- package/util/summarizer/benchmark/second-phase/process.js +48 -11
- package/util/summarizer/benchmark/summarizer.d.ts +3 -6
- package/util/summarizer/benchmark/summarizer.js +16 -11
- package/util/summarizer/statistics/first-phase/process.js +8 -8
- package/util/summarizer/statistics/post-process/clusterer.d.ts +2 -2
- package/util/summarizer/statistics/post-process/file-based-count.d.ts +1 -1
- package/util/summarizer/statistics/post-process/histogram.d.ts +2 -2
- package/util/summarizer/statistics/post-process/post-process-output.d.ts +2 -2
- package/util/summarizer/statistics/post-process/post-process-output.js +4 -5
- package/util/summarizer/statistics/second-phase/process.d.ts +2 -2
- package/util/summarizer/statistics/summarizer.d.ts +3 -2
- package/util/summarizer/summarizer.d.ts +1 -1
- package/r-bridge/lang-4.x/ast/parser/xml/config.d.ts +0 -25
- package/r-bridge/lang-4.x/ast/parser/xml/config.js +0 -16
- package/r-bridge/lang-4.x/ast/parser/xml/internal/xml-to-json.d.ts +0 -9
- package/r-bridge/lang-4.x/ast/parser/xml/internal/xml-to-json.js +0 -51
- package/r-bridge/lang-4.x/ast/parser/xml/parser.d.ts +0 -17
- package/r-bridge/lang-4.x/ast/parser/xml/parser.js +0 -30
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[](https://github.com/Code-Inspect/flowr/wiki)\
|
|
2
|
-
[](https://github.com/Code-Inspect/flowr/actions/workflows/qa.yaml) [](https://codecov.io/gh/Code-Inspect/flowr) [](https://hub.docker.com/r/eagleoutice/flowr) [](https://github.com/Code-Inspect/flowr/releases/latest)
|
|
2
|
+
[](https://github.com/Code-Inspect/flowr/actions/workflows/qa.yaml) [](https://codecov.io/gh/Code-Inspect/flowr) [](https://hub.docker.com/r/eagleoutice/flowr) [](https://github.com/Code-Inspect/flowr/releases/latest) [](https://marketplace.visualstudio.com/items?itemName=code-inspect.vscode-flowr)
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
*flowR* is a static [dataflow analyzer](https://en.wikipedia.org/wiki/Data-flow_analysis) and [program slicer](https://github.com/Code-Inspect/flowr/wiki/Terminology#program-slice) for the [*R*](https://www.r-project.org/) programming language (currently tested for versions `4.x`).
|
|
5
|
+
*flowR* is a static [dataflow analyzer](https://en.wikipedia.org/wiki/Data-flow_analysis) and [program slicer](https://github.com/Code-Inspect/flowr/wiki/Terminology#program-slice) for the [*R*](https://www.r-project.org/) programming language (currently tested for versions `4.x`). It is available as a [Visual Studio Code extension](https://marketplace.visualstudio.com/items?itemName=code-inspect.vscode-flowr) and as a [docker image](https://hub.docker.com/r/eagleoutice/flowr).
|
|
6
6
|
|
|
7
7
|
## ⭐ Getting Started
|
|
8
8
|
|
|
9
|
-
To get started with _flowR_, please check out the [Overview](https://github.com/Code-Inspect/flowr/wiki/Overview). The [Setup](https://github.com/Code-Inspect/flowr/wiki/Setup) wiki page explains how you can download and setup _flowR_ on your system. With docker 🐳️, the following line should be enough (and drop you directly into the REPL):
|
|
9
|
+
To get started with _flowR_, please check out the [Overview](https://github.com/Code-Inspect/flowr/wiki/Overview). The [Setup](https://github.com/Code-Inspect/flowr/wiki/Setup) wiki page explains how you can download and setup _flowR_ on your system. For Visual Studio Code, please see the [marketplace entry](https://marketplace.visualstudio.com/items?itemName=code-inspect.vscode-flowr). With docker 🐳️, the following line should be enough (and drop you directly into the REPL):
|
|
10
10
|
|
|
11
11
|
```shell
|
|
12
12
|
docker run -it --rm eagleoutice/flowr
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
interface IntervalBound {
|
|
2
|
+
readonly value: number;
|
|
3
|
+
readonly inclusive: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare class Interval {
|
|
6
|
+
readonly min: IntervalBound;
|
|
7
|
+
readonly max: IntervalBound;
|
|
8
|
+
constructor(min: IntervalBound, max: IntervalBound);
|
|
9
|
+
toString(): string;
|
|
10
|
+
}
|
|
11
|
+
export declare class Domain {
|
|
12
|
+
private readonly _intervals;
|
|
13
|
+
private constructor();
|
|
14
|
+
static bottom(): Domain;
|
|
15
|
+
static fromIntervals(intervals: Interval[] | Set<Interval>): Domain;
|
|
16
|
+
static fromScalar(n: number): Domain;
|
|
17
|
+
get intervals(): Set<Interval>;
|
|
18
|
+
private set intervals(value);
|
|
19
|
+
addInterval(interval: Interval): void;
|
|
20
|
+
toString(): string;
|
|
21
|
+
}
|
|
22
|
+
export declare function doIntervalsOverlap(interval1: Interval, interval2: Interval): boolean;
|
|
23
|
+
export declare function unifyDomains(domains: Domain[]): Domain;
|
|
24
|
+
export declare function unifyOverlappingIntervals(intervals: Interval[]): Interval[];
|
|
25
|
+
export declare function addDomains(domain1: Domain, domain2: Domain): Domain;
|
|
26
|
+
export declare function subtractDomains(domain1: Domain, domain2: Domain): Domain;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.subtractDomains = exports.addDomains = exports.unifyOverlappingIntervals = exports.unifyDomains = exports.doIntervalsOverlap = exports.Domain = exports.Interval = void 0;
|
|
4
|
+
const assert_1 = require("../util/assert");
|
|
5
|
+
class Interval {
|
|
6
|
+
min;
|
|
7
|
+
max;
|
|
8
|
+
constructor(min, max) {
|
|
9
|
+
this.min = min;
|
|
10
|
+
this.max = max;
|
|
11
|
+
(0, assert_1.guard)(min.value <= max.value, () => `The interval ${this.toString()} has a minimum that is greater than its maximum`);
|
|
12
|
+
(0, assert_1.guard)(min.value !== max.value || (min.inclusive === max.inclusive), `The bound ${min.value} cannot be in- and exclusive at the same time`);
|
|
13
|
+
}
|
|
14
|
+
toString() {
|
|
15
|
+
return `${this.min.inclusive ? '[' : '('}${this.min.value}, ${this.max.value}${this.max.inclusive ? ']' : ')'}`;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.Interval = Interval;
|
|
19
|
+
class Domain {
|
|
20
|
+
_intervals;
|
|
21
|
+
constructor(intervals = []) {
|
|
22
|
+
this._intervals = new Set(unifyOverlappingIntervals(intervals));
|
|
23
|
+
}
|
|
24
|
+
static bottom() {
|
|
25
|
+
return new Domain();
|
|
26
|
+
}
|
|
27
|
+
static fromIntervals(intervals) {
|
|
28
|
+
return new Domain(Array.from(intervals));
|
|
29
|
+
}
|
|
30
|
+
static fromScalar(n) {
|
|
31
|
+
return new Domain([new Interval({ value: n, inclusive: true }, { value: n, inclusive: true })]);
|
|
32
|
+
}
|
|
33
|
+
get intervals() {
|
|
34
|
+
return this._intervals;
|
|
35
|
+
}
|
|
36
|
+
set intervals(intervals) {
|
|
37
|
+
this._intervals.clear();
|
|
38
|
+
for (const interval of intervals) {
|
|
39
|
+
this._intervals.add(interval);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
addInterval(interval) {
|
|
43
|
+
this.intervals = unifyOverlappingIntervals([...this.intervals, interval]);
|
|
44
|
+
}
|
|
45
|
+
toString() {
|
|
46
|
+
return `{${Array.from(this.intervals).join(', ')}}`;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.Domain = Domain;
|
|
50
|
+
function compareIntervals(compareType, interval1, interval2) {
|
|
51
|
+
const diff = interval1.value - interval2.value;
|
|
52
|
+
if (diff !== 0 || compareType === 2 /* CompareType.IgnoreInclusivity */) {
|
|
53
|
+
return diff;
|
|
54
|
+
}
|
|
55
|
+
switch (compareType) {
|
|
56
|
+
case 0 /* CompareType.Min */:
|
|
57
|
+
return Number(!interval1.inclusive) - Number(!interval2.inclusive);
|
|
58
|
+
case 1 /* CompareType.Max */:
|
|
59
|
+
return Number(interval1.inclusive) - Number(interval2.inclusive);
|
|
60
|
+
default:
|
|
61
|
+
(0, assert_1.assertUnreachable)(compareType);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function compareIntervalsByTheirMinimum(interval1, interval2) {
|
|
65
|
+
return compareIntervals(0 /* CompareType.Min */, interval1.min, interval2.min);
|
|
66
|
+
}
|
|
67
|
+
function compareIntervalsByTheirMaximum(interval1, interval2) {
|
|
68
|
+
return compareIntervals(1 /* CompareType.Max */, interval1.max, interval2.max);
|
|
69
|
+
}
|
|
70
|
+
function doIntervalsOverlap(interval1, interval2) {
|
|
71
|
+
const diff1 = compareIntervals(2 /* CompareType.IgnoreInclusivity */, interval1.max, interval2.min);
|
|
72
|
+
const diff2 = compareIntervals(2 /* CompareType.IgnoreInclusivity */, interval2.max, interval1.min);
|
|
73
|
+
// If one interval ends before the other starts, they don't overlap
|
|
74
|
+
if (diff1 < 0 || diff2 < 0) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
// If their end and start are equal, they only overlap if both are inclusive
|
|
78
|
+
if (diff1 === 0) {
|
|
79
|
+
return interval1.max.inclusive && interval2.min.inclusive;
|
|
80
|
+
}
|
|
81
|
+
if (diff2 === 0) {
|
|
82
|
+
return interval2.max.inclusive && interval1.min.inclusive;
|
|
83
|
+
}
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
exports.doIntervalsOverlap = doIntervalsOverlap;
|
|
87
|
+
function unifyDomains(domains) {
|
|
88
|
+
const unifiedIntervals = unifyOverlappingIntervals(domains.flatMap(domain => Array.from(domain.intervals)));
|
|
89
|
+
return Domain.fromIntervals(unifiedIntervals);
|
|
90
|
+
}
|
|
91
|
+
exports.unifyDomains = unifyDomains;
|
|
92
|
+
function unifyOverlappingIntervals(intervals) {
|
|
93
|
+
if (intervals.length === 0) {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
const sortedIntervals = intervals.sort(compareIntervalsByTheirMinimum);
|
|
97
|
+
const unifiedIntervals = [];
|
|
98
|
+
let currentInterval = sortedIntervals[0];
|
|
99
|
+
for (const nextInterval of sortedIntervals) {
|
|
100
|
+
if (doIntervalsOverlap(currentInterval, nextInterval)) {
|
|
101
|
+
const intervalWithEarlierStart = compareIntervalsByTheirMinimum(currentInterval, nextInterval) < 0 ? currentInterval : nextInterval;
|
|
102
|
+
const intervalWithLaterEnd = compareIntervalsByTheirMaximum(currentInterval, nextInterval) > 0 ? currentInterval : nextInterval;
|
|
103
|
+
currentInterval = new Interval(intervalWithEarlierStart.min, intervalWithLaterEnd.max);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
unifiedIntervals.push(currentInterval);
|
|
107
|
+
currentInterval = nextInterval;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
unifiedIntervals.push(currentInterval);
|
|
111
|
+
return unifiedIntervals;
|
|
112
|
+
}
|
|
113
|
+
exports.unifyOverlappingIntervals = unifyOverlappingIntervals;
|
|
114
|
+
function addDomains(domain1, domain2) {
|
|
115
|
+
const intervals = new Set();
|
|
116
|
+
for (const interval1 of domain1.intervals) {
|
|
117
|
+
for (const interval2 of domain2.intervals) {
|
|
118
|
+
intervals.add(new Interval({
|
|
119
|
+
value: interval1.min.value + interval2.min.value,
|
|
120
|
+
inclusive: interval1.min.inclusive && interval2.min.inclusive
|
|
121
|
+
}, {
|
|
122
|
+
value: interval1.max.value + interval2.max.value,
|
|
123
|
+
inclusive: interval1.max.inclusive && interval2.max.inclusive
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return Domain.fromIntervals(intervals);
|
|
128
|
+
}
|
|
129
|
+
exports.addDomains = addDomains;
|
|
130
|
+
function subtractDomains(domain1, domain2) {
|
|
131
|
+
const intervals = new Set();
|
|
132
|
+
for (const interval1 of domain1.intervals) {
|
|
133
|
+
for (const interval2 of domain2.intervals) {
|
|
134
|
+
intervals.add(new Interval({
|
|
135
|
+
value: interval1.min.value - interval2.max.value,
|
|
136
|
+
inclusive: interval1.min.inclusive && interval2.max.inclusive
|
|
137
|
+
}, {
|
|
138
|
+
value: interval1.max.value - interval2.min.value,
|
|
139
|
+
inclusive: interval1.max.inclusive && interval2.min.inclusive
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return Domain.fromIntervals(intervals);
|
|
144
|
+
}
|
|
145
|
+
exports.subtractDomains = subtractDomains;
|
|
146
|
+
//# sourceMappingURL=domain.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Handler } from '../handler';
|
|
2
|
+
import type { AINode } from '../../processor';
|
|
3
|
+
import type { BinaryOperatorFlavor, ParentInformation, RBinaryOp } from '../../../r-bridge';
|
|
4
|
+
export type BinOpOperators = {
|
|
5
|
+
[key in BinaryOperatorFlavor]: (lhs: AINode, rhs: AINode, node: RBinaryOp<ParentInformation>) => AINode;
|
|
6
|
+
};
|
|
7
|
+
export declare class BinOp implements Handler<AINode> {
|
|
8
|
+
readonly node: RBinaryOp<ParentInformation>;
|
|
9
|
+
lhs: AINode | undefined;
|
|
10
|
+
rhs: AINode | undefined;
|
|
11
|
+
constructor(node: RBinaryOp<ParentInformation>);
|
|
12
|
+
getName(): string;
|
|
13
|
+
enter(): void;
|
|
14
|
+
exit(): AINode;
|
|
15
|
+
next(node: AINode): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BinOp = void 0;
|
|
4
|
+
const processor_1 = require("../../processor");
|
|
5
|
+
const assert_1 = require("../../../util/assert");
|
|
6
|
+
const operators_1 = require("./operators");
|
|
7
|
+
class BinOp {
|
|
8
|
+
node;
|
|
9
|
+
lhs;
|
|
10
|
+
rhs;
|
|
11
|
+
constructor(node) {
|
|
12
|
+
this.node = node;
|
|
13
|
+
}
|
|
14
|
+
getName() {
|
|
15
|
+
return `Bin Op (${this.node.flavor})`;
|
|
16
|
+
}
|
|
17
|
+
enter() {
|
|
18
|
+
processor_1.aiLogger.trace(`Entered ${this.getName()}`);
|
|
19
|
+
}
|
|
20
|
+
exit() {
|
|
21
|
+
processor_1.aiLogger.trace(`Exited ${this.getName()}`);
|
|
22
|
+
(0, assert_1.guard)(this.lhs !== undefined, `No LHS found for assignment ${this.node.info.id}`);
|
|
23
|
+
(0, assert_1.guard)(this.rhs !== undefined, `No RHS found for assignment ${this.node.info.id}`);
|
|
24
|
+
return operators_1.operators[this.node.flavor](this.lhs, this.rhs, this.node);
|
|
25
|
+
}
|
|
26
|
+
next(node) {
|
|
27
|
+
processor_1.aiLogger.trace(`${this.getName()} received`);
|
|
28
|
+
if (this.lhs === undefined) {
|
|
29
|
+
this.lhs = node;
|
|
30
|
+
}
|
|
31
|
+
else if (this.rhs === undefined) {
|
|
32
|
+
this.rhs = node;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
(0, assert_1.guard)(false, `BinOp ${this.node.info.id} already has both LHS and RHS`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.BinOp = BinOp;
|
|
40
|
+
//# sourceMappingURL=binop.js.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.operators = void 0;
|
|
4
|
+
const assert_1 = require("../../../util/assert");
|
|
5
|
+
const domain_1 = require("../../domain");
|
|
6
|
+
exports.operators = {
|
|
7
|
+
'assignment': (lhs, rhs, node) => {
|
|
8
|
+
return {
|
|
9
|
+
id: lhs.id,
|
|
10
|
+
domain: rhs.domain,
|
|
11
|
+
astNode: node.lhs,
|
|
12
|
+
};
|
|
13
|
+
},
|
|
14
|
+
'arithmetic': (lhs, rhs, node) => {
|
|
15
|
+
switch (node.operator) {
|
|
16
|
+
case '+':
|
|
17
|
+
return {
|
|
18
|
+
id: lhs.id,
|
|
19
|
+
domain: (0, domain_1.addDomains)(lhs.domain, rhs.domain),
|
|
20
|
+
astNode: node,
|
|
21
|
+
};
|
|
22
|
+
case '-':
|
|
23
|
+
return {
|
|
24
|
+
id: lhs.id,
|
|
25
|
+
domain: (0, domain_1.subtractDomains)(lhs.domain, rhs.domain),
|
|
26
|
+
astNode: node,
|
|
27
|
+
};
|
|
28
|
+
default:
|
|
29
|
+
(0, assert_1.guard)(false, `Unknown binary operator ${node.operator}`);
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
'logical': () => {
|
|
33
|
+
(0, assert_1.guard)(false, 'Not implemented yet');
|
|
34
|
+
},
|
|
35
|
+
'model formula': () => {
|
|
36
|
+
(0, assert_1.guard)(false, 'Not implemented yet');
|
|
37
|
+
},
|
|
38
|
+
'comparison': () => {
|
|
39
|
+
(0, assert_1.guard)(false, 'Not implemented yet');
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=operators.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DataflowInformation } from '../dataflow/internal/info';
|
|
2
|
+
import type { NodeId, NormalizedAst, ParentInformation, RNodeWithParent } from '../r-bridge';
|
|
3
|
+
import { Domain } from './domain';
|
|
4
|
+
export declare const aiLogger: import("tslog").Logger<import("tslog").ILogObj>;
|
|
5
|
+
export interface AINode {
|
|
6
|
+
readonly id: NodeId;
|
|
7
|
+
readonly domain: Domain;
|
|
8
|
+
readonly astNode: RNodeWithParent<ParentInformation>;
|
|
9
|
+
}
|
|
10
|
+
export declare function runAbstractInterpretation(ast: NormalizedAst, dfg: DataflowInformation): DataflowInformation;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runAbstractInterpretation = exports.aiLogger = void 0;
|
|
4
|
+
const cfg_1 = require("../util/cfg/cfg");
|
|
5
|
+
const visitor_1 = require("../util/cfg/visitor");
|
|
6
|
+
const assert_1 = require("../util/assert");
|
|
7
|
+
const dataflow_1 = require("../dataflow");
|
|
8
|
+
const binop_1 = require("./handler/binop/binop");
|
|
9
|
+
const domain_1 = require("./domain");
|
|
10
|
+
const log_1 = require("../util/log");
|
|
11
|
+
exports.aiLogger = log_1.log.getSubLogger({ name: 'abstract-interpretation' });
|
|
12
|
+
class Stack {
|
|
13
|
+
backingStore = [];
|
|
14
|
+
size() {
|
|
15
|
+
return this.backingStore.length;
|
|
16
|
+
}
|
|
17
|
+
peek() {
|
|
18
|
+
return this.backingStore[this.size() - 1];
|
|
19
|
+
}
|
|
20
|
+
pop() {
|
|
21
|
+
return this.backingStore.pop();
|
|
22
|
+
}
|
|
23
|
+
push(item) {
|
|
24
|
+
this.backingStore.push(item);
|
|
25
|
+
return item;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function getDomainOfDfgChild(node, dfg, nodeMap) {
|
|
29
|
+
const dfgNode = dfg.graph.get(node);
|
|
30
|
+
(0, assert_1.guard)(dfgNode !== undefined, `No DFG-Node found with ID ${node}`);
|
|
31
|
+
const [_, children] = dfgNode;
|
|
32
|
+
const ids = Array.from(children.entries())
|
|
33
|
+
.filter(([_, edge]) => edge.types.has(dataflow_1.EdgeType.Reads))
|
|
34
|
+
.map(([id, _]) => id);
|
|
35
|
+
const domains = [];
|
|
36
|
+
for (const id of ids) {
|
|
37
|
+
const domain = nodeMap.get(id)?.domain;
|
|
38
|
+
(0, assert_1.guard)(domain !== undefined, `No domain found for ID ${id}`);
|
|
39
|
+
domains.push(domain);
|
|
40
|
+
}
|
|
41
|
+
return (0, domain_1.unifyDomains)(domains);
|
|
42
|
+
}
|
|
43
|
+
function runAbstractInterpretation(ast, dfg) {
|
|
44
|
+
const cfg = (0, cfg_1.extractCFG)(ast);
|
|
45
|
+
const operationStack = new Stack();
|
|
46
|
+
const nodeMap = new Map();
|
|
47
|
+
(0, visitor_1.visitCfg)(cfg, (node, _) => {
|
|
48
|
+
const astNode = ast.idMap.get(node.id);
|
|
49
|
+
if (astNode?.type === "RBinaryOp" /* RType.BinaryOp */) {
|
|
50
|
+
operationStack.push(new binop_1.BinOp(astNode)).enter();
|
|
51
|
+
}
|
|
52
|
+
else if (astNode?.type === "RSymbol" /* RType.Symbol */) {
|
|
53
|
+
operationStack.peek()?.next({
|
|
54
|
+
id: astNode.info.id,
|
|
55
|
+
domain: getDomainOfDfgChild(node.id, dfg, nodeMap),
|
|
56
|
+
astNode: astNode,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
else if (astNode?.type === "RNumber" /* RType.Number */) {
|
|
60
|
+
const num = astNode.content.num;
|
|
61
|
+
operationStack.peek()?.next({
|
|
62
|
+
id: astNode.info.id,
|
|
63
|
+
domain: domain_1.Domain.fromScalar(num),
|
|
64
|
+
astNode: astNode,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
else if (node.type === "end-marker" /* CfgVertexType.EndMarker */) {
|
|
68
|
+
const operation = operationStack.pop();
|
|
69
|
+
if (operation === undefined) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const operationResult = operation.exit();
|
|
73
|
+
(0, assert_1.guard)(!nodeMap.has(operationResult.id), `Domain for ID ${operationResult.id} already exists`);
|
|
74
|
+
nodeMap.set(operationResult.id, operationResult);
|
|
75
|
+
operationStack.peek()?.next(operationResult);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
exports.aiLogger.warn(`Unknown node type ${node.type}`);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return dfg;
|
|
82
|
+
}
|
|
83
|
+
exports.runAbstractInterpretation = runAbstractInterpretation;
|
|
84
|
+
//# sourceMappingURL=processor.js.map
|
package/benchmark/slicer.d.ts
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Provides a top-level slicer that can be used to slice code *and* retrieve stats.
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
|
-
import { NormalizedAst, RParseRequestFromFile, RParseRequestFromText } from '../r-bridge';
|
|
6
|
-
import { DataflowInformation } from '../dataflow/internal/info';
|
|
7
|
-
import { SlicingCriteria, SlicingCriteriaFilter, SliceResult, ReconstructionResult } from '../slicing';
|
|
8
|
-
import { PerSliceStats, SlicerStats } from './stats';
|
|
9
|
-
import { MergeableRecord } from '../util/objects';
|
|
5
|
+
import type { NormalizedAst, RParseRequestFromFile, RParseRequestFromText } from '../r-bridge';
|
|
6
|
+
import type { DataflowInformation } from '../dataflow/internal/info';
|
|
7
|
+
import type { SlicingCriteria, SlicingCriteriaFilter, SliceResult, ReconstructionResult } from '../slicing';
|
|
8
|
+
import type { PerSliceStats, SlicerStats } from './stats';
|
|
9
|
+
import type { MergeableRecord } from '../util/objects';
|
|
10
10
|
export declare const benchmarkLogger: import("tslog").Logger<import("tslog").ILogObj>;
|
|
11
11
|
/**
|
|
12
12
|
* Returns the stats but also the result of all setup steps (parsing, normalization, and the dataflow analysis) during the slicing.
|
|
@@ -15,8 +15,6 @@ export declare const benchmarkLogger: import("tslog").Logger<import("tslog").ILo
|
|
|
15
15
|
export interface BenchmarkSlicerStats extends MergeableRecord {
|
|
16
16
|
/** the measurements obtained during the benchmark */
|
|
17
17
|
stats: SlicerStats;
|
|
18
|
-
/** the used token map when translating what was parsed from R */
|
|
19
|
-
tokenMap: Record<string, string>;
|
|
20
18
|
/** the initial and unmodified AST produced by the R side/the 'parse' step */
|
|
21
19
|
parse: string;
|
|
22
20
|
/** the normalized AST produced by the 'normalization' step, including its parent decoration */
|
|
@@ -52,8 +50,8 @@ export declare class BenchmarkSlicer {
|
|
|
52
50
|
private readonly shell;
|
|
53
51
|
private stats;
|
|
54
52
|
private loadedXml;
|
|
55
|
-
private tokenMap;
|
|
56
53
|
private dataflow;
|
|
54
|
+
private ai;
|
|
57
55
|
private normalizedAst;
|
|
58
56
|
private totalStopwatch;
|
|
59
57
|
private finished;
|
package/benchmark/slicer.js
CHANGED
|
@@ -29,12 +29,12 @@ exports.benchmarkLogger = log_1.log.getSubLogger({ name: 'benchmark' });
|
|
|
29
29
|
class BenchmarkSlicer {
|
|
30
30
|
/** Measures all data that is recorded *once* per slicer (complete setup up to the dataflow graph creation) */
|
|
31
31
|
commonMeasurements = new stopwatch_1.Measurements();
|
|
32
|
-
perSliceMeasurements = new Map;
|
|
32
|
+
perSliceMeasurements = new Map();
|
|
33
33
|
shell;
|
|
34
34
|
stats;
|
|
35
35
|
loadedXml;
|
|
36
|
-
tokenMap;
|
|
37
36
|
dataflow;
|
|
37
|
+
ai;
|
|
38
38
|
normalizedAst;
|
|
39
39
|
totalStopwatch;
|
|
40
40
|
finished = false;
|
|
@@ -43,7 +43,6 @@ class BenchmarkSlicer {
|
|
|
43
43
|
constructor() {
|
|
44
44
|
this.totalStopwatch = this.commonMeasurements.start('total');
|
|
45
45
|
this.shell = this.commonMeasurements.measure('initialize R session', () => new r_bridge_1.RShell());
|
|
46
|
-
this.commonMeasurements.measure('inject home path', () => this.shell.tryToInjectHomeLibPath());
|
|
47
46
|
}
|
|
48
47
|
/**
|
|
49
48
|
* Initialize the slicer on the given request.
|
|
@@ -51,19 +50,11 @@ class BenchmarkSlicer {
|
|
|
51
50
|
*/
|
|
52
51
|
async init(request) {
|
|
53
52
|
(0, assert_1.guard)(this.stats === undefined, 'cannot initialize the slicer twice');
|
|
54
|
-
await this.commonMeasurements.measureAsync('ensure installation of xmlparsedata', () => this.shell.ensurePackageInstalled('xmlparsedata', true));
|
|
55
|
-
this.tokenMap = await this.commonMeasurements.measureAsync('retrieve token map',
|
|
56
|
-
// with this being the first time, there is no preexisting caching!
|
|
57
|
-
() => this.shell.tokenMap());
|
|
58
53
|
this.stepper = new core_1.SteppingSlicer({
|
|
59
54
|
shell: this.shell,
|
|
60
|
-
request: {
|
|
61
|
-
...request,
|
|
62
|
-
ensurePackageInstalled: true
|
|
63
|
-
},
|
|
55
|
+
request: { ...request },
|
|
64
56
|
stepOfInterest: core_1.LAST_STEP,
|
|
65
|
-
criterion: []
|
|
66
|
-
tokenMap: this.tokenMap
|
|
57
|
+
criterion: []
|
|
67
58
|
});
|
|
68
59
|
this.loadedXml = await this.measureCommonStep('parse', 'retrieve AST from R code');
|
|
69
60
|
this.normalizedAst = await this.measureCommonStep('normalize', 'normalize R AST');
|
|
@@ -208,8 +199,7 @@ class BenchmarkSlicer {
|
|
|
208
199
|
stats: this.stats,
|
|
209
200
|
parse: this.loadedXml,
|
|
210
201
|
dataflow: this.dataflow,
|
|
211
|
-
normalize: this.normalizedAst
|
|
212
|
-
tokenMap: this.tokenMap,
|
|
202
|
+
normalize: this.normalizedAst
|
|
213
203
|
};
|
|
214
204
|
}
|
|
215
205
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SummarizedSlicerStats, UltimateSlicerStats } from '../../util/summarizer/benchmark/data';
|
|
1
|
+
import type { SummarizedSlicerStats, UltimateSlicerStats } from '../../util/summarizer/benchmark/data';
|
|
2
2
|
/**
|
|
3
3
|
* Converts the given stats to a human-readable string.
|
|
4
4
|
* You may have to {@link summarizeSlicerStats | summarize} the stats first.
|
package/benchmark/stats/print.js
CHANGED
|
@@ -72,7 +72,6 @@ function stats2string(stats) {
|
|
|
72
72
|
let result = `
|
|
73
73
|
Request: ${JSON.stringify(stats.request)}
|
|
74
74
|
Shell init time: ${print(stats.commonMeasurements, 'initialize R session')}
|
|
75
|
-
Retrieval of token map: ${print(stats.commonMeasurements, 'retrieve token map')}
|
|
76
75
|
AST retrieval: ${print(stats.commonMeasurements, 'retrieve AST from R code')}
|
|
77
76
|
AST normalization: ${print(stats.commonMeasurements, 'normalize R AST')}
|
|
78
77
|
Dataflow creation: ${print(stats.commonMeasurements, 'produce dataflow information')}
|
|
@@ -117,7 +116,6 @@ function ultimateStats2String(stats) {
|
|
|
117
116
|
return `
|
|
118
117
|
Summarized: ${stats.totalRequests} requests and ${stats.totalSlices} slices
|
|
119
118
|
Shell init time: ${formatSummarizedTimeMeasure(stats.commonMeasurements.get('initialize R session'))}
|
|
120
|
-
Retrieval of token map: ${formatSummarizedTimeMeasure(stats.commonMeasurements.get('retrieve token map'))}
|
|
121
119
|
AST retrieval: ${formatSummarizedTimeMeasure(stats.commonMeasurements.get('retrieve AST from R code'))}
|
|
122
120
|
AST normalization: ${formatSummarizedTimeMeasure(stats.commonMeasurements.get('normalize R AST'))}
|
|
123
121
|
Dataflow creation: ${formatSummarizedTimeMeasure(stats.commonMeasurements.get('produce dataflow information'))}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { SingleSlicingCriterion, SlicingCriteria } from '../../slicing';
|
|
2
|
-
import { NodeId, RParseRequestFromFile, RParseRequestFromText } from '../../r-bridge';
|
|
3
|
-
|
|
4
|
-
export declare const CommonSlicerMeasurements: readonly ["initialize R session", "inject home path", "ensure installation of xmlparsedata", "retrieve token map", "retrieve AST from R code", "normalize R AST", "produce dataflow information", "close R session", "total"];
|
|
1
|
+
import type { ReconstructionResult, SingleSlicingCriterion, SlicingCriteria } from '../../slicing';
|
|
2
|
+
import type { NodeId, RParseRequestFromFile, RParseRequestFromText } from '../../r-bridge';
|
|
3
|
+
export declare const CommonSlicerMeasurements: readonly ["initialize R session", "retrieve AST from R code", "normalize R AST", "produce dataflow information", "close R session", "total"];
|
|
5
4
|
export type CommonSlicerMeasurements = typeof CommonSlicerMeasurements[number];
|
|
6
5
|
export declare const PerSliceMeasurements: readonly ["static slicing", "reconstruct code", "total"];
|
|
7
6
|
export type PerSliceMeasurements = typeof PerSliceMeasurements[number];
|
package/benchmark/stats/stats.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PerSliceMeasurements = exports.CommonSlicerMeasurements = void 0;
|
|
4
|
-
exports.CommonSlicerMeasurements = ['initialize R session', '
|
|
4
|
+
exports.CommonSlicerMeasurements = ['initialize R session', 'retrieve AST from R code', 'normalize R AST', 'produce dataflow information', 'close R session', 'total'];
|
|
5
5
|
exports.PerSliceMeasurements = ['static slicing', 'reconstruct code', 'total'];
|
|
6
6
|
//# sourceMappingURL=stats.js.map
|
package/cli/benchmark-app.d.ts
CHANGED
package/cli/benchmark-app.js
CHANGED
|
@@ -9,6 +9,7 @@ const parallel_1 = require("../util/parallel");
|
|
|
9
9
|
const assert_1 = require("../util/assert");
|
|
10
10
|
const fs_1 = __importDefault(require("fs"));
|
|
11
11
|
const common_1 = require("./common");
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
12
13
|
const options = (0, common_1.processCommandLineArgs)('benchmark', [], {
|
|
13
14
|
subtitle: 'Slice given files with additional benchmark information',
|
|
14
15
|
examples: [
|
|
@@ -21,15 +22,17 @@ if (options.input.length === 0) {
|
|
|
21
22
|
process.exit(0);
|
|
22
23
|
}
|
|
23
24
|
(0, assert_1.guard)(options.slice === 'all' || options.slice === 'no', 'slice must be either all or no');
|
|
25
|
+
(0, assert_1.guard)(options.runs === undefined || options.runs > 0, 'runs must be greater than zero');
|
|
24
26
|
function removeIfExists(summarizedRaw) {
|
|
25
27
|
if (fs_1.default.existsSync(summarizedRaw)) {
|
|
26
28
|
console.log(`Removing existing ${summarizedRaw}`);
|
|
27
|
-
fs_1.default.
|
|
29
|
+
fs_1.default.rmSync(summarizedRaw, { recursive: true });
|
|
28
30
|
}
|
|
29
31
|
}
|
|
30
32
|
async function benchmark() {
|
|
31
33
|
removeIfExists(options.output);
|
|
32
|
-
|
|
34
|
+
fs_1.default.mkdirSync(options.output);
|
|
35
|
+
console.log(`Storing output in ${options.output}`);
|
|
33
36
|
console.log(`Using ${options.parallel} parallel executors`);
|
|
34
37
|
// we do not use the limit argument to be able to pick the limit randomly
|
|
35
38
|
const files = [];
|
|
@@ -43,10 +46,22 @@ async function benchmark() {
|
|
|
43
46
|
}
|
|
44
47
|
const limit = options.limit ?? files.length;
|
|
45
48
|
const verboseAdd = options.verbose ? ['--verbose'] : [];
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
const args = files.map((f, i) => [
|
|
50
|
+
'--input', f.content,
|
|
51
|
+
'--file-id', `${i}`,
|
|
52
|
+
'--output', path_1.default.join(options.output, `${path_1.default.parse(f.content).name}.json`),
|
|
53
|
+
'--slice', options.slice, ...verboseAdd
|
|
54
|
+
]);
|
|
55
|
+
const runs = options.runs ?? 1;
|
|
56
|
+
for (let i = 1; i <= runs; i++) {
|
|
57
|
+
console.log(`Run ${i} of ${runs}`);
|
|
58
|
+
const pool = new parallel_1.LimitedThreadPool(`${__dirname}/benchmark-helper-app`,
|
|
59
|
+
// we reverse here "for looks", since the helper pops from the end, and we want file ids to be ascending :D
|
|
60
|
+
args.map(a => [...a, '--run-num', `${i}`]).reverse(), limit, options.parallel);
|
|
61
|
+
await pool.run();
|
|
62
|
+
const stats = pool.getStats();
|
|
63
|
+
console.log(`Run ${i} of ${runs}: Benchmarked ${stats.counter} files, skipped ${stats.skipped.length} files due to errors`);
|
|
64
|
+
}
|
|
50
65
|
}
|
|
51
66
|
void benchmark();
|
|
52
67
|
//# sourceMappingURL=benchmark-app.js.map
|