@eagleoutice/flowr 2.9.12 → 2.9.14
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 +35 -23
- package/abstract-interpretation/absint-visitor.d.ts +1 -1
- package/abstract-interpretation/absint-visitor.js +20 -20
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +2 -2
- package/benchmark/slicer.d.ts +5 -3
- package/benchmark/slicer.js +26 -10
- package/benchmark/stats/print.js +12 -0
- package/benchmark/stats/stats.d.ts +3 -2
- package/benchmark/stats/stats.js +1 -1
- package/benchmark/summarizer/data.d.ts +1 -0
- package/benchmark/summarizer/second-phase/process.js +5 -0
- package/cli/benchmark-app.d.ts +1 -0
- package/cli/benchmark-app.js +1 -0
- package/cli/benchmark-helper-app.d.ts +2 -1
- package/cli/benchmark-helper-app.js +6 -3
- package/cli/common/options.d.ts +8 -0
- package/cli/common/options.js +3 -1
- package/cli/common/scripts-info.d.ts +8 -0
- package/cli/export-quads-app.js +1 -1
- package/cli/flowr.js +3 -3
- package/cli/repl/commands/repl-dataflow.js +5 -5
- package/cli/repl/core.d.ts +3 -3
- package/cli/repl/parser/slice-query-parser.d.ts +1 -1
- package/cli/repl/parser/slice-query-parser.js +2 -2
- package/cli/repl/server/connection.d.ts +2 -2
- package/cli/repl/server/connection.js +2 -2
- package/cli/repl/server/messages/message-slice.d.ts +1 -1
- package/cli/repl/server/messages/message-slice.js +2 -2
- package/cli/repl/server/server.d.ts +2 -2
- package/cli/script-core/statistics-core.d.ts +2 -2
- package/cli/script-core/statistics-helper-core.d.ts +2 -2
- package/cli/script-core/statistics-helper-core.js +1 -1
- package/cli/slicer-app.js +2 -2
- package/cli/statistics-app.js +1 -1
- package/cli/statistics-helper-app.js +1 -1
- package/cli/wiki.js +2 -2
- package/config.d.ts +65 -24
- package/config.js +197 -161
- package/control-flow/extract-cfg.js +7 -10
- package/control-flow/semantic-cfg-guided-visitor.d.ts +1 -1
- package/control-flow/semantic-cfg-guided-visitor.js +43 -43
- package/control-flow/useless-loop.d.ts +1 -1
- package/control-flow/useless-loop.js +3 -3
- package/core/print/dataflow-printer.d.ts +0 -14
- package/core/print/dataflow-printer.js +0 -21
- package/core/steps/all/core/20-dataflow.d.ts +3 -3
- package/core/steps/all/core/20-dataflow.js +3 -2
- package/core/steps/all/static-slicing/00-slice.d.ts +2 -5
- package/core/steps/all/static-slicing/00-slice.js +6 -8
- package/core/steps/pipeline/default-pipelines.d.ts +89 -89
- package/core/steps/pipeline-step.d.ts +2 -2
- package/dataflow/environments/built-in-proc-name.d.ts +83 -0
- package/dataflow/environments/built-in-proc-name.js +88 -0
- package/dataflow/environments/built-in.d.ts +1 -83
- package/dataflow/environments/built-in.js +37 -120
- package/dataflow/environments/default-builtin-config.d.ts +1 -1
- package/dataflow/environments/default-builtin-config.js +75 -75
- package/dataflow/environments/identifier.d.ts +1 -0
- package/dataflow/environments/identifier.js +1 -0
- package/dataflow/eval/resolve/alias-tracking.js +12 -15
- package/dataflow/eval/resolve/resolve.js +2 -2
- package/dataflow/fn/exceptions-of-function.d.ts +1 -1
- package/dataflow/fn/exceptions-of-function.js +2 -2
- package/dataflow/graph/call-graph.d.ts +49 -19
- package/dataflow/graph/call-graph.js +117 -114
- package/dataflow/graph/dataflowgraph-builder.d.ts +1 -1
- package/dataflow/graph/dataflowgraph-builder.js +2 -2
- package/dataflow/graph/df-helper.d.ts +132 -0
- package/dataflow/graph/df-helper.js +131 -0
- package/dataflow/graph/diff-dataflow-graph.d.ts +5 -10
- package/dataflow/graph/diff-dataflow-graph.js +3 -28
- package/dataflow/graph/edge.d.ts +1 -0
- package/dataflow/graph/edge.js +1 -0
- package/dataflow/graph/graph-helper.d.ts +55 -0
- package/dataflow/graph/graph-helper.js +105 -0
- package/dataflow/graph/graph.d.ts +6 -1
- package/dataflow/graph/graph.js +14 -9
- package/dataflow/graph/vertex.d.ts +1 -1
- package/dataflow/info.d.ts +14 -4
- package/dataflow/info.js +28 -16
- package/dataflow/internal/linker.d.ts +14 -10
- package/dataflow/internal/linker.js +29 -32
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +4 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +7 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +4 -4
- 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.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-library.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-list.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-local.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-local.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-recall.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.js +5 -5
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +5 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-dispatch.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.js +7 -7
- package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +23 -12
- package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.js +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.js +6 -9
- 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 +2 -2
- package/dataflow/internal/process/functions/call/known-call-handling.js +2 -2
- package/dataflow/internal/process/functions/call/named-call-handling.d.ts +1 -1
- package/dataflow/internal/process/functions/call/named-call-handling.js +1 -1
- package/dataflow/internal/process/functions/call/unnamed-call-handling.js +2 -2
- package/dataflow/internal/process/process-uninteresting-leaf.d.ts +1 -1
- package/dataflow/internal/process/process-uninteresting-leaf.js +1 -1
- package/dataflow/origin/dfg-get-origin.d.ts +1 -1
- package/dataflow/origin/dfg-get-symbol-refs.js +6 -6
- package/documentation/doc-readme.js +2 -2
- package/documentation/doc-util/doc-dfg.d.ts +3 -0
- package/documentation/doc-util/doc-dfg.js +5 -7
- package/documentation/doc-util/doc-normalized-ast.d.ts +0 -6
- package/documentation/doc-util/doc-normalized-ast.js +0 -23
- package/documentation/doc-util/doc-structure.js +3 -3
- package/documentation/doc-util/doc-types.js +3 -3
- package/documentation/wiki-analyzer.js +7 -5
- package/documentation/wiki-core.js +6 -7
- package/documentation/wiki-dataflow-graph.js +15 -13
- package/documentation/wiki-interface.js +8 -6
- package/documentation/wiki-linter.js +6 -5
- package/documentation/wiki-mk/doc-context.js +3 -4
- package/documentation/wiki-normalized-ast.js +5 -4
- package/documentation/wiki-query.js +28 -3
- package/engines.d.ts +2 -2
- package/engines.js +4 -4
- package/linter/linter-rules.d.ts +24 -1
- package/linter/linter-rules.js +3 -1
- package/linter/rules/dataframe-access-validation.js +5 -5
- package/linter/rules/naming-convention.d.ts +1 -1
- package/linter/rules/naming-convention.js +7 -3
- package/linter/rules/seeded-randomness.js +2 -2
- package/linter/rules/stop-with-call-arg.d.ts +35 -0
- package/linter/rules/stop-with-call-arg.js +72 -0
- package/linter/rules/useless-loop.d.ts +1 -1
- package/package.json +3 -1
- package/project/cache/flowr-analyzer-cache.d.ts +1 -1
- package/project/cache/flowr-analyzer-cache.js +1 -1
- package/project/context/flowr-analyzer-context.d.ts +6 -6
- package/project/context/flowr-analyzer-context.js +2 -2
- package/project/context/flowr-analyzer-files-context.d.ts +2 -2
- package/project/context/flowr-analyzer-files-context.js +28 -8
- package/project/flowr-analyzer-builder.d.ts +13 -6
- package/project/flowr-analyzer-builder.js +12 -3
- package/project/flowr-analyzer.d.ts +4 -4
- package/queries/catalog/call-context-query/identify-link-to-nested-call-relation.js +2 -2
- package/queries/catalog/call-graph-query/call-graph-query-format.d.ts +1 -1
- package/queries/catalog/call-graph-query/call-graph-query-format.js +2 -2
- package/queries/catalog/cluster-query/cluster-query-format.js +2 -2
- package/queries/catalog/config-query/config-query-format.d.ts +5 -5
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +2 -2
- package/queries/catalog/dataflow-query/dataflow-query-format.js +2 -2
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +1 -2
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +2 -2
- package/queries/catalog/does-call-query/does-call-query-executor.js +2 -2
- package/queries/catalog/does-call-query/does-call-query-format.d.ts +2 -2
- package/queries/catalog/files-query/files-query-format.d.ts +3 -3
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -2
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +1 -1
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +1 -1
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +2 -2
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -3
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +2 -2
- package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +2 -2
- package/queries/catalog/linter-query/linter-query-format.d.ts +3 -3
- package/queries/catalog/location-map-query/location-map-query-executor.js +2 -2
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +2 -2
- package/queries/catalog/origin-query/origin-query-executor.d.ts +1 -1
- package/queries/catalog/origin-query/origin-query-executor.js +3 -3
- package/queries/catalog/origin-query/origin-query-format.d.ts +2 -2
- package/queries/catalog/provenance-query/provenance-query-executor.d.ts +9 -0
- package/queries/catalog/provenance-query/provenance-query-executor.js +37 -0
- package/queries/catalog/provenance-query/provenance-query-format.d.ts +35 -0
- package/queries/catalog/provenance-query/provenance-query-format.js +62 -0
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +4 -4
- package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +2 -2
- package/queries/catalog/resolve-value-query/resolve-value-query-format.js +4 -0
- package/queries/catalog/search-query/search-query-format.js +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +4 -2
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +4 -4
- package/queries/catalog/static-slice-query/static-slice-query-format.js +3 -3
- package/queries/query.d.ts +27 -19
- package/queries/query.js +2 -0
- package/r-bridge/lang-4.x/ast/model/model.d.ts +13 -2
- package/r-bridge/lang-4.x/ast/model/model.js +20 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +8 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +13 -0
- package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -2
- package/r-bridge/lang-4.x/ast/parser/json/parser.js +2 -2
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +6 -2
- package/search/flowr-search-filters.d.ts +1 -1
- package/search/flowr-search-printer.js +3 -3
- package/search/search-executor/search-enrichers.js +2 -2
- package/search/search-executor/search-generators.js +1 -1
- package/slicing/criterion/parse.d.ts +40 -16
- package/slicing/criterion/parse.js +67 -63
- package/slicing/static/slicer-types.d.ts +2 -3
- package/slicing/static/static-slicer.d.ts +3 -4
- package/slicing/static/static-slicer.js +9 -12
- package/statistics/statistics.d.ts +2 -2
- package/util/diff.d.ts +2 -2
- package/util/mermaid/ast.js +4 -4
- package/util/mermaid/cfg.js +5 -5
- package/util/mermaid/dfg.d.ts +33 -18
- package/util/mermaid/dfg.js +46 -31
- package/util/mermaid/mermaid.d.ts +57 -12
- package/util/mermaid/mermaid.js +74 -67
- package/util/objects.d.ts +12 -0
- package/util/objects.js +28 -0
- package/util/range.d.ts +8 -0
- package/util/range.js +13 -1
- package/util/slice-direction.d.ts +7 -0
- package/util/slice-direction.js +12 -0
- package/util/summarizer.js +1 -1
- package/util/version.js +1 -1
- package/dataflow/graph/invert-dfg.d.ts +0 -6
- package/dataflow/graph/invert-dfg.js +0 -20
- package/dataflow/graph/resolve-graph.d.ts +0 -8
- package/dataflow/graph/resolve-graph.js +0 -59
|
@@ -29,6 +29,7 @@ const flowr_analyzer_plugin_1 = require("../project/plugins/flowr-analyzer-plugi
|
|
|
29
29
|
const flowr_analyzer_environment_context_1 = require("../project/context/flowr-analyzer-environment-context");
|
|
30
30
|
const flowr_analyzer_functions_context_1 = require("../project/context/flowr-analyzer-functions-context");
|
|
31
31
|
const flowr_analyzer_meta_context_1 = require("../project/context/flowr-analyzer-meta-context");
|
|
32
|
+
const config_1 = require("../config");
|
|
32
33
|
async function analyzerQuickExample() {
|
|
33
34
|
const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder()
|
|
34
35
|
.setEngine('tree-sitter')
|
|
@@ -172,23 +173,24 @@ The following sections highlight some of the most important configuration option
|
|
|
172
173
|
${(0, doc_structure_1.section)('Configuring flowR', 3)}
|
|
173
174
|
|
|
174
175
|
You can fundamentally change the behavior of flowR using the [config file](${doc_files_1.FlowrWikiBaseRef}/Interface#configuring-flowr),
|
|
175
|
-
embedded in the interface ${ctx.link(
|
|
176
|
+
embedded in the interface ${ctx.link(config_1.FlowrConfig)}.
|
|
176
177
|
With the builder you can either provide a complete configuration or amend the default configuration using:
|
|
177
178
|
|
|
178
179
|
* ${ctx.linkM(flowr_analyzer_builder_1.FlowrAnalyzerBuilder, 'setConfig')} to set a complete configuration
|
|
180
|
+
* ${ctx.linkM(flowr_analyzer_builder_1.FlowrAnalyzerBuilder, 'configure')} to set the value of a specific key in the config
|
|
179
181
|
* ${ctx.linkM(flowr_analyzer_builder_1.FlowrAnalyzerBuilder, 'amendConfig')} to amend the default configuration
|
|
180
182
|
|
|
181
|
-
By default, the builder uses flowR's standard configuration obtained with ${ctx.
|
|
183
|
+
By default, the builder uses flowR's standard configuration obtained with ${ctx.linkO(config_1.FlowrConfig, 'default')}.
|
|
182
184
|
|
|
183
185
|
${(0, doc_structure_1.block)({
|
|
184
186
|
type: 'NOTE',
|
|
185
|
-
content: `During the analysis with the ${ctx.link(flowr_analyzer_1.FlowrAnalyzer
|
|
187
|
+
content: `During the analysis with the ${ctx.link(flowr_analyzer_1.FlowrAnalyzer)}, you can also access the configuration with
|
|
186
188
|
the ${ctx.link(flowr_analyzer_context_1.FlowrAnalyzerContext)}.`
|
|
187
189
|
})}
|
|
188
190
|
|
|
189
191
|
${(0, doc_structure_1.section)('Configuring the Engine', 3)}
|
|
190
192
|
|
|
191
|
-
FlowR supports multiple
|
|
193
|
+
FlowR supports multiple ${ctx.linkPage('wiki/Engines', 'engines')} for parsing and analyzing R code.
|
|
192
194
|
With the builder, you can select the engine to use with:
|
|
193
195
|
|
|
194
196
|
* ${ctx.linkM(flowr_analyzer_builder_1.FlowrAnalyzerBuilder, 'setEngine')} to set the desired engine.
|
|
@@ -292,7 +294,7 @@ ${(0, doc_structure_1.section)('File Loading', 4)}
|
|
|
292
294
|
|
|
293
295
|
These plugins register for every file encountered by the [files context](#Files_Context) and determine whether and _how_ they can process the file.
|
|
294
296
|
They are responsible for transforming the raw file content into a representation that flowR can work with during the analysis.
|
|
295
|
-
For example, the ${ctx.link(flowr_analyzer_description_file_plugin_1.FlowrAnalyzerDescriptionFilePlugin
|
|
297
|
+
For example, the ${ctx.link(flowr_analyzer_description_file_plugin_1.FlowrAnalyzerDescriptionFilePlugin)} adds support for R \`DESCRIPTION\` files by parsing their content into key-value pairs.
|
|
296
298
|
These can then be used by other plugins, e.g. the ${ctx.link(flowr_analyzer_package_versions_description_file_plugin_1.FlowrAnalyzerPackageVersionsDescriptionFilePlugin)} that extracts package version information from these files.
|
|
297
299
|
|
|
298
300
|
If multiple file plugins could apply (${ctx.link('DefaultFlowrAnalyzerFilePlugin::' + flowr_analyzer_file_plugin_1.FlowrAnalyzerFilePlugin.defaultPlugin().applies.name)}) to the same file,
|
|
@@ -45,11 +45,10 @@ const doc_structure_1 = require("./doc-util/doc-structure");
|
|
|
45
45
|
const shell_1 = require("../r-bridge/shell");
|
|
46
46
|
const log_1 = require("../../test/functionality/_helper/log");
|
|
47
47
|
const log_2 = require("../util/log");
|
|
48
|
+
const model_1 = require("../r-bridge/lang-4.x/ast/model/model");
|
|
48
49
|
async function makeAnalyzerExample() {
|
|
49
50
|
const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder()
|
|
50
|
-
.
|
|
51
|
-
c.ignoreSourceCalls = true;
|
|
52
|
-
})
|
|
51
|
+
.configure('ignoreSourceCalls', true)
|
|
53
52
|
.setEngine('tree-sitter')
|
|
54
53
|
.build();
|
|
55
54
|
analyzer.addRequest('x <- 1; y <- x; print(y);');
|
|
@@ -310,7 +309,7 @@ If you are interested in the raw token types that we may encounter, have a look
|
|
|
310
309
|
The normalization function ${ctx.link(parser_2.normalize)} takes the output from the previous steps and uses the ${ctx.link(format_1.prepareParsedData)} and
|
|
311
310
|
${ctx.link(format_1.convertPreparedParsedData)} functions to first transform the serialized parsing output to an object.
|
|
312
311
|
Next, ${ctx.link(normalize_root_1.normalizeRootObjToAst)} transforms this object to a normalized AST and ${ctx.link(decorate_1.decorateAst)} adds additional information to the AST (like roles, ids, depth, etc.).
|
|
313
|
-
While looking at the mermaid visualization of such an AST is nice and usually sufficient, looking at the objects themselves shows you the full range of information the AST provides (all encompassed within the ${ctx.link(
|
|
312
|
+
While looking at the mermaid visualization of such an AST is nice and usually sufficient, looking at the objects themselves shows you the full range of information the AST provides (all encompassed within the ${ctx.link(model_1.RNode)} type).
|
|
314
313
|
|
|
315
314
|
Let's have a look at the normalized AST for the sample code \`${sampleCode}\` (please refer to the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized-AST) wiki page for more information):
|
|
316
315
|
|
|
@@ -360,7 +359,7 @@ We use the ${ctx.link(extractor_1.produceDataFlowGraph)} function as an entry po
|
|
|
360
359
|
The function is mainly backed by its ${ctx.link('processors')} object which maps each type in the normalized AST to an appropriate handler ("fold-function").
|
|
361
360
|
|
|
362
361
|
To understand these handlers, let's start with the simplest one, ${ctx.link(process_uninteresting_leaf_1.processUninterestingLeaf)} signals that
|
|
363
|
-
we do not care about this node and just produce an empty dataflow information (using ${ctx.
|
|
362
|
+
we do not care about this node and just produce an empty dataflow information (using ${ctx.linkO(info_1.DataflowInformation, 'initialize')}).
|
|
364
363
|
Looking at the function showcases the general structure of a processor:
|
|
365
364
|
|
|
366
365
|
${ctx.hierarchy(process_uninteresting_leaf_1.processUninterestingLeaf, { maxDepth: 2, openTop: true })}
|
|
@@ -386,7 +385,7 @@ ${ctx.hierarchy(process_value_1.processValue, { maxDepth: 2, openTop: true })}
|
|
|
386
385
|
|
|
387
386
|
Please note, that we add the [value vertex](${doc_files_1.FlowrWikiBaseRef}/Dataflow-Graph#value-vertex) to the newly created dataflow graph,
|
|
388
387
|
which holds a reference to the constant. If you are confused with the use of the ${ctx.link('ParentInformation')} type,
|
|
389
|
-
this stems from the [AST decoration](#normalization) and signals that we have a decorated ${ctx.link(
|
|
388
|
+
this stems from the [AST decoration](#normalization) and signals that we have a decorated ${ctx.link(model_1.RNode)} (which may have additional information in \`OtherInfo\`).
|
|
390
389
|
|
|
391
390
|
Yet again, this is not very interesting. When looking at the ${ctx.link('processors')} object you may be confused by
|
|
392
391
|
many lines just mapping the node to the ${ctx.link(process_named_call_1.processAsNamedCall)} function.
|
|
@@ -426,7 +425,7 @@ to produce a new dataflow information.
|
|
|
426
425
|
|
|
427
426
|
Given the [dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow-Graph), you can do a lot more!
|
|
428
427
|
You can issue [queries](${doc_files_1.FlowrWikiBaseRef}/Query-API) to explore the graph, [search](${doc_files_1.FlowrWikiBaseRef}/Search-API) for specific elements, or, for example, request a [static backward slice](#static-backward-slicing).
|
|
429
|
-
Of course, all of these endeavors work not just with the ${ctx.link(shell_1.RShell
|
|
428
|
+
Of course, all of these endeavors work not just with the ${ctx.link(shell_1.RShell)} but also with the [\`tree-sitter\` engine](${doc_files_1.FlowrWikiBaseRef}/Engines).
|
|
430
429
|
|
|
431
430
|
### Static Backward Slicing
|
|
432
431
|
|
|
@@ -38,11 +38,12 @@ const flowr_analyzer_builder_1 = require("../project/flowr-analyzer-builder");
|
|
|
38
38
|
const flowr_analyzer_context_1 = require("../project/context/flowr-analyzer-context");
|
|
39
39
|
const doc_maker_1 = require("./wiki-mk/doc-maker");
|
|
40
40
|
const flowr_analyzer_1 = require("../project/flowr-analyzer");
|
|
41
|
-
const built_in_1 = require("../dataflow/environments/built-in");
|
|
42
41
|
const dfg_1 = require("../util/mermaid/dfg");
|
|
43
42
|
const r_number_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-number");
|
|
44
43
|
const model_1 = require("../r-bridge/lang-4.x/ast/model/model");
|
|
45
44
|
const range_1 = require("../util/range");
|
|
45
|
+
const df_helper_1 = require("../dataflow/graph/df-helper");
|
|
46
|
+
const built_in_proc_name_1 = require("../dataflow/environments/built-in-proc-name");
|
|
46
47
|
async function subExplanation(parser, { description, code, expectedSubgraph }) {
|
|
47
48
|
expectedSubgraph = await (0, doc_dfg_1.verifyExpectedSubgraph)(parser, code, expectedSubgraph);
|
|
48
49
|
const marks = [];
|
|
@@ -170,7 +171,7 @@ ${(0, doc_structure_1.block)({
|
|
|
170
171
|
content: `
|
|
171
172
|
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
|
|
172
173
|
as there are some edge-cases that require special attention.
|
|
173
|
-
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.
|
|
174
|
+
In general, the ${ctx.link(dfg_get_origin_1.getOriginInDfg)} (which is also available as ${ctx.linkO(df_helper_1.Dataflow, 'origin')}) 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.
|
|
174
175
|
`
|
|
175
176
|
})}
|
|
176
177
|
|
|
@@ -196,8 +197,8 @@ ${ctx.hierarchy('FunctionArgument')}
|
|
|
196
197
|
|
|
197
198
|
There is another element of potential interest to you, the \`origin\` property which records how flowR created the respective function call.
|
|
198
199
|
These origins may hold the name of any processor that is part of the ${ctx.link('BuiltInProcName')} enumeration to signal that the respective processor (cf. ${ctx.link('BuiltInProcessorMapper')}) was responsible for creating the vertex.
|
|
199
|
-
The entry \`${
|
|
200
|
-
However, in general, flowR may use any fitting handler as an origin (see the ${ctx.link('BuiltInProcName')} enum for a *complete* list). For example, within a access definition, flowR will correspondingly redefine the meaning of \`:=\` to that of the \`${
|
|
200
|
+
The entry \`${built_in_proc_name_1.BuiltInProcName.Function}\` signals that flowR used a processor for a user-defined function defined within the source code, \`${built_in_proc_name_1.BuiltInProcName.Unnamed}\` signals that the function as an anonymous function definition.
|
|
201
|
+
However, in general, flowR may use any fitting handler as an origin (see the ${ctx.link('BuiltInProcName')} enum for a *complete* list). For example, within a access definition, flowR will correspondingly redefine the meaning of \`:=\` to that of the \`${built_in_proc_name_1.BuiltInProcName.TableAssignment}\`.
|
|
201
202
|
|
|
202
203
|
${(0, doc_structure_1.details)('Example: Simple Function Call (unresolved)', await (async () => {
|
|
203
204
|
const code = 'foo(x,3,y=3,)';
|
|
@@ -367,7 +368,7 @@ ${(0, doc_structure_1.block)({
|
|
|
367
368
|
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?
|
|
368
369
|
|
|
369
370
|
Unnamed functions have an array of signatures which you can use to identify them.
|
|
370
|
-
But in short: the \`origin\` attribute of the ${ctx.link('DataflowGraphVertexFunctionCall')} is \`${
|
|
371
|
+
But in short: the \`origin\` attribute of the ${ctx.link('DataflowGraphVertexFunctionCall')} is \`${built_in_proc_name_1.BuiltInProcName.Unnamed}\`.
|
|
371
372
|
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.
|
|
372
373
|
This name _always_ starts with \`${unnamed_call_handling_1.UnnamedFunctionCallPrefix}\`.
|
|
373
374
|
|
|
@@ -891,7 +892,7 @@ ${await getVertexExplanations(treeSitter, ctx)}
|
|
|
891
892
|
|
|
892
893
|
${(0, doc_structure_1.section)('Edges', 2, 'edges')}
|
|
893
894
|
|
|
894
|
-
1. ${(0, doc_data_dfg_util_1.getAllEdges)().map(([k, v], index) => `[\`${k}\` (${v})](#${index + 1}-${k.toLowerCase().
|
|
895
|
+
1. ${(0, doc_data_dfg_util_1.getAllEdges)().map(([k, v], index) => `[\`${k}\` (${v})](#${index + 1}-${k.toLowerCase().replaceAll(/\s/g, '-')}-edge)`).join('\n1. ')}
|
|
895
896
|
|
|
896
897
|
${await getEdgesExplanations(treeSitter, ctx)}
|
|
897
898
|
|
|
@@ -1052,7 +1053,8 @@ ${await (0, doc_dfg_1.printDfGraphForCode)(treeSitter, 'alias <- unknown\nalias(
|
|
|
1052
1053
|
${(0, doc_structure_1.section)('Working with the Dataflow Graph', 2, 'dfg-working')}
|
|
1053
1054
|
|
|
1054
1055
|
The ${ctx.link('DataflowInformation')} is the core result of _flowR_ and summarizes a lot of information.
|
|
1055
|
-
Depending on what you are interested in, there exists a plethora of functions and queries to help you out, answering the most important questions
|
|
1056
|
+
Depending on what you are interested in, there exists a plethora of functions and queries to help you out, answering the most important questions.
|
|
1057
|
+
Generally, we recommend you check out the ${ctx.link(df_helper_1.Dataflow, undefined, { type: 'variable' })} helper object!
|
|
1056
1058
|
|
|
1057
1059
|
* The **${ctx.linkPage('wiki/Query API')}** provides many functions to query the dataflow graph for specific information (dependencies, calls, slices, clusters, ...)
|
|
1058
1060
|
* The **${ctx.linkPage('wiki/Search API')}** allows you to search for specific vertices or edges in the dataflow graph or the original program
|
|
@@ -1064,9 +1066,9 @@ Depending on what you are interested in, there exists a plethora of functions an
|
|
|
1064
1066
|
|
|
1065
1067
|
FlowR also provides various helper objects (with the same name as the corresponding type) to help you work with the dataflow graph:
|
|
1066
1068
|
|
|
1067
|
-
* ${ctx.link(
|
|
1068
|
-
* ${ctx.link(
|
|
1069
|
-
* ${ctx.link(
|
|
1069
|
+
* ${ctx.link(edge_1.DfEdge, undefined, { type: 'variable' })} to get helpful functions wrt. edges (see [below](#dfg-resolving-values))
|
|
1070
|
+
* ${ctx.link(identifier_1.Identifier, undefined, { type: 'variable' })} to get helpful functions wrt. identifiers
|
|
1071
|
+
* ${ctx.link(graph_1.FunctionArgument, undefined, { type: 'variable' })} to get helpful functions wrt. function arguments
|
|
1070
1072
|
|
|
1071
1073
|
Some of these functions have been explained in their respective wiki pages. However, some are part of the ${ctx.linkPage('wiki/Dataflow Graph', 'Dataflow Graph API')} and so we explain them here.
|
|
1072
1074
|
If you are interested in which features we support and which features are still to be worked on, please refer to our ${ctx.linkPage('wiki/Capabilities', 'capabilities')} page.
|
|
@@ -1107,14 +1109,14 @@ ${await (async () => {
|
|
|
1107
1109
|
}
|
|
1108
1110
|
throw new Error('Could not find edge');
|
|
1109
1111
|
})()}—which is usually not very helpful.
|
|
1110
|
-
You can use ${ctx.
|
|
1111
|
-
${ctx.
|
|
1112
|
+
You can use ${ctx.linkO(edge_1.DfEdge, 'splitTypes')} to get the individual bitmasks of all included types, and
|
|
1113
|
+
${ctx.linkO(edge_1.DfEdge, 'includesType')} to check whether a specific type (or one of a collection of types) is included in the edge.
|
|
1112
1114
|
|
|
1113
1115
|
${(0, doc_structure_1.section)('Handling Origins', 3, 'dfg-handling-origins')}
|
|
1114
1116
|
|
|
1115
1117
|
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
|
|
1116
1118
|
that are called by an invocation, and more.
|
|
1117
|
-
For this, the ${ctx.link(dfg_get_origin_1.getOriginInDfg)} function provides you with a collection of ${ctx.link('Origin')} objects:
|
|
1119
|
+
For this, the ${ctx.link(dfg_get_origin_1.getOriginInDfg)} (this is also accessible with ${ctx.linkO(df_helper_1.Dataflow, 'origin')}) function provides you with a collection of ${ctx.link('Origin')} objects:
|
|
1118
1120
|
|
|
1119
1121
|
${ctx.hierarchy('Origin', { openTop: true })}
|
|
1120
1122
|
|
|
@@ -18,8 +18,8 @@ const flowr_main_options_1 = require("../cli/flowr-main-options");
|
|
|
18
18
|
const doc_issue_1 = require("./doc-util/doc-issue");
|
|
19
19
|
const doc_structure_1 = require("./doc-util/doc-structure");
|
|
20
20
|
const doc_maker_1 = require("./wiki-mk/doc-maker");
|
|
21
|
-
const built_in_1 = require("../dataflow/environments/built-in");
|
|
22
21
|
const doc_writing_code_1 = require("./data/interface/doc-writing-code");
|
|
22
|
+
const built_in_proc_name_1 = require("../dataflow/environments/built-in-proc-name");
|
|
23
23
|
async function explainServer(parser) {
|
|
24
24
|
(0, doc_data_server_messages_1.documentAllServerMessages)();
|
|
25
25
|
return `
|
|
@@ -200,7 +200,7 @@ ${await (0, doc_repl_1.documentReplSession)(parser, [{
|
|
|
200
200
|
For more information on the available queries, please check out the ${ctx.linkPage('wiki/Query API', 'Query API')}.
|
|
201
201
|
`;
|
|
202
202
|
}
|
|
203
|
-
function explainConfigFile() {
|
|
203
|
+
function explainConfigFile(ctx) {
|
|
204
204
|
return `
|
|
205
205
|
|
|
206
206
|
When running _flowR_, you may want to specify some behaviors with a dedicated configuration file.
|
|
@@ -211,6 +211,8 @@ Within the REPL this works by running the following:
|
|
|
211
211
|
|
|
212
212
|
${(0, doc_code_1.codeBlock)('shell', ':query @config')}
|
|
213
213
|
|
|
214
|
+
To work with the ${ctx.link(config_1.FlowrConfig)} you can use the provided helper objects alongside its methods like
|
|
215
|
+
${ctx.linkO(config_1.FlowrConfig, 'amend')}.
|
|
214
216
|
The following summarizes the configuration options:
|
|
215
217
|
|
|
216
218
|
- \`ignoreSourceCalls\`: If set to \`true\`, _flowR_ will ignore source calls when analyzing the code, i.e., ignoring the inclusion of other files.
|
|
@@ -234,7 +236,7 @@ ${(0, doc_code_1.codeBlock)('json', JSON.stringify({
|
|
|
234
236
|
environment: {
|
|
235
237
|
overwriteBuiltIns: {
|
|
236
238
|
definitions: [
|
|
237
|
-
{ type: 'function', names: ['foo'], processor:
|
|
239
|
+
{ type: 'function', names: ['foo'], processor: built_in_proc_name_1.BuiltInProcName.Assignment, config: {} }
|
|
238
240
|
]
|
|
239
241
|
}
|
|
240
242
|
}
|
|
@@ -288,7 +290,7 @@ ${(0, doc_code_1.codeBlock)('json', JSON.stringify({
|
|
|
288
290
|
| Type | Description | Example |
|
|
289
291
|
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
290
292
|
| \`constant\` | Additionally allows for a \`value\` this should resolve to. | \`{ type: 'constant', names: ['NULL', 'NA'], value: null }\` |
|
|
291
|
-
| \`function\` | Is a rather flexible way to define and bind built-in functions. For the time, we do not have extensive documentation to cover all the cases, so please either consult the sources with the \`default-builtin-config.ts\` or open a [new issue](${doc_issue_1.NewIssueUrl}). | \`{ type: 'function', names: ['next'], processor: '${
|
|
293
|
+
| \`function\` | Is a rather flexible way to define and bind built-in functions. For the time, we do not have extensive documentation to cover all the cases, so please either consult the sources with the \`default-builtin-config.ts\` or open a [new issue](${doc_issue_1.NewIssueUrl}). | \`{ type: 'function', names: ['next'], processor: '${built_in_proc_name_1.BuiltInProcName.Default}', config: { cfg: ExitPointType.Next } }\` |
|
|
292
294
|
| \`replacement\` | A comfortable way to specify replacement functions like \`$<-\` or \`names<-\`. \`suffixes\` describes the... suffixes to attach automatically. | \`{ type: 'replacement', suffixes: ['<-', '<<-'], names: ['[', '[['] }\` |
|
|
293
295
|
|
|
294
296
|
|
|
@@ -298,7 +300,7 @@ ${(0, doc_code_1.codeBlock)('json', JSON.stringify({
|
|
|
298
300
|
|
|
299
301
|
<summary style='color:gray'>Full Configuration-File Schema</summary>
|
|
300
302
|
|
|
301
|
-
${(0, schema_1.describeSchema)(config_1.
|
|
303
|
+
${(0, schema_1.describeSchema)(config_1.FlowrConfig.Schema, ansi_1.markdownFormatter)}
|
|
302
304
|
|
|
303
305
|
</details>
|
|
304
306
|
|
|
@@ -331,7 +333,7 @@ ${await explainRepl(treeSitter, ctx)}
|
|
|
331
333
|
<a id='configuring-flowr'></a>
|
|
332
334
|
## ⚙️ Configuring FlowR
|
|
333
335
|
|
|
334
|
-
${explainConfigFile()}
|
|
336
|
+
${explainConfigFile(ctx)}
|
|
335
337
|
|
|
336
338
|
<a id='writing-code'></a>
|
|
337
339
|
## ⚒️ Writing Code
|
|
@@ -46,12 +46,12 @@ function prettyPrintExpectedOutput(expected) {
|
|
|
46
46
|
//
|
|
47
47
|
lines = expected.trim().replace(/^\s*\[+\s*{*/m, '').replace(/\s*}*\s*]+\s*$/, '').split('\n').filter(l => l.trim() !== '');
|
|
48
48
|
/* take the indentation of the last line and remove it from all but the first: */
|
|
49
|
-
const indentation = lines
|
|
49
|
+
const indentation = lines.at(-1)?.match(/^\s*/)?.[0] ?? '';
|
|
50
50
|
return lines.map((line, i) => {
|
|
51
51
|
if (i === 0) {
|
|
52
52
|
return line;
|
|
53
53
|
}
|
|
54
|
-
return line.
|
|
54
|
+
return line.replaceAll(new RegExp('^' + indentation, 'g'), '');
|
|
55
55
|
}).join('\n');
|
|
56
56
|
}
|
|
57
57
|
function buildSamplesFromLinterTestCases(_parser, testFile) {
|
|
@@ -122,6 +122,7 @@ df[6, "value"]
|
|
|
122
122
|
`, tagTypes);
|
|
123
123
|
rule(knownParser, 'dead-code', 'DeadCodeConfig', 'DEAD_CODE', 'lint-dead-code', 'if(TRUE) 1 else 2', tagTypes);
|
|
124
124
|
rule(knownParser, 'useless-loop', 'UselessLoopConfig', 'USELESS_LOOP', 'lint-useless-loop', 'for(i in c(1)) { print(i) }', tagTypes);
|
|
125
|
+
rule(knownParser, 'stop-call', 'StopWithCallConfig', 'STOP_WITH_CALL_ARG', 'lint-stop-call', 'stop(42)', tagTypes);
|
|
125
126
|
function rule(parser, name, configType, ruleType, testfile, example, types) {
|
|
126
127
|
const rule = linter_rules_1.LintingRules[name];
|
|
127
128
|
const tags = rule.info.tags.toSorted((a, b) => {
|
|
@@ -236,7 +237,7 @@ We use tags to categorize linting rules for users. The following tags are availa
|
|
|
236
237
|
| Tag/Badge   | Description |
|
|
237
238
|
| --- | :-- |
|
|
238
239
|
${Object.entries(linter_tags_1.LintingRuleTag).map(([name, tag]) => {
|
|
239
|
-
return `| <a id="${tag}"></a> ${(makeTagBadge(tag, tagTypes.info))} | ${(0, doc_types_1.getDocumentationForType)('LintingRuleTag::' + name, tagTypes.info).replaceAll(
|
|
240
|
+
return `| <a id="${tag}"></a> ${(makeTagBadge(tag, tagTypes.info))} | ${(0, doc_types_1.getDocumentationForType)('LintingRuleTag::' + name, tagTypes.info).replaceAll('\n', ' ')} (rule${getAllLintingRulesWithTag(tag).length === 1 ? '' : 's'}: ${(0, strings_1.joinWithLast)(getAllLintingRulesWithTag(tag).map(l => linkToRule(l))) || '_none_'}) | `;
|
|
240
241
|
}).join('\n')}
|
|
241
242
|
|
|
242
243
|
${(0, doc_structure_1.section)('Certainty', 2, 'certainty')}
|
|
@@ -248,14 +249,14 @@ ${(0, doc_structure_1.section)('Rule Certainty', 3, 'rule-certainty')}
|
|
|
248
249
|
| Rule Certainty | Description |
|
|
249
250
|
| -------------- | :---------- |
|
|
250
251
|
${Object.entries(linter_format_1.LintingRuleCertainty).map(([name, certainty]) => {
|
|
251
|
-
return `| <a id="${certainty}"></a> \`${certainty}\` | ${(0, doc_types_1.getDocumentationForType)('LintingRuleCertainty::' + name, tagTypes.info).replaceAll(
|
|
252
|
+
return `| <a id="${certainty}"></a> \`${certainty}\` | ${(0, doc_types_1.getDocumentationForType)('LintingRuleCertainty::' + name, tagTypes.info).replaceAll('\n', ' ')} (rule${getAllLintingRulesWitCertainty(certainty).length === 1 ? '' : 's'}: ${(0, strings_1.joinWithLast)(getAllLintingRulesWitCertainty(certainty).map(l => linkToRule(l))) || '_none_'}) |`;
|
|
252
253
|
}).join('\n')}
|
|
253
254
|
|
|
254
255
|
${(0, doc_structure_1.section)('Result Certainty', 3, 'result-certainty')}
|
|
255
256
|
|
|
256
257
|
| Result Certainty | Description |
|
|
257
258
|
| ---------------- | :---------- |
|
|
258
|
-
${Object.entries(linter_format_1.LintingResultCertainty).map(([name, certainty]) => `| <a id="${certainty}"></a> \`${certainty}\` | ${(0, doc_types_1.getDocumentationForType)('LintingResultCertainty::' + name, tagTypes.info).replaceAll(
|
|
259
|
+
${Object.entries(linter_format_1.LintingResultCertainty).map(([name, certainty]) => `| <a id="${certainty}"></a> \`${certainty}\` | ${(0, doc_types_1.getDocumentationForType)('LintingResultCertainty::' + name, tagTypes.info).replaceAll('\n', ' ')} |`).join('\n')}
|
|
259
260
|
|
|
260
261
|
`.trim();
|
|
261
262
|
}
|
|
@@ -49,8 +49,7 @@ exports.ConstantWikiLinkInfo = {
|
|
|
49
49
|
*/
|
|
50
50
|
function makeDocContextForTypes(shell, ...rootFolders) {
|
|
51
51
|
if (rootFolders.length === 0) {
|
|
52
|
-
rootFolders.push(path_1.default.resolve(__dirname, '../../../src'));
|
|
53
|
-
rootFolders.push(path_1.default.resolve(__dirname, '../../../test/functionality'));
|
|
52
|
+
rootFolders.push(path_1.default.resolve(__dirname, '../../../src'), path_1.default.resolve(__dirname, '../../../test/functionality'));
|
|
54
53
|
}
|
|
55
54
|
const { info, program } = (0, doc_types_1.getTypesFromFolder)({ rootFolder: rootFolders, typeNameForMermaid: undefined });
|
|
56
55
|
return {
|
|
@@ -108,10 +107,10 @@ function makeDocContextForTypes(shell, ...rootFolders) {
|
|
|
108
107
|
text ??= i.name;
|
|
109
108
|
}
|
|
110
109
|
else {
|
|
111
|
-
link = `${doc_files_1.
|
|
110
|
+
link = `${doc_files_1.FlowrGithubRef}/${pageName.toLowerCase().replaceAll(' ', '-')}`;
|
|
112
111
|
}
|
|
113
112
|
text ??= pageName.split('/').pop() ?? pageName;
|
|
114
|
-
return `[${text}](${link}${segment ?
|
|
113
|
+
return `[${text}](${link}${segment ? '#' + segment : ''})`;
|
|
115
114
|
},
|
|
116
115
|
linkCode(path, lineNumber) {
|
|
117
116
|
const lnk = lineNumber ? `${path.toString()}#L${lineNumber}` : path.toString();
|
|
@@ -16,6 +16,7 @@ const roxygen_parse_1 = require("../r-bridge/roxygen2/roxygen-parse");
|
|
|
16
16
|
const r_binary_op_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-binary-op");
|
|
17
17
|
const model_1 = require("../r-bridge/lang-4.x/ast/model/model");
|
|
18
18
|
const r_project_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-project");
|
|
19
|
+
const r_expression_list_1 = require("../r-bridge/lang-4.x/ast/model/nodes/r-expression-list");
|
|
19
20
|
async function quickNormalizedAstMultipleFiles() {
|
|
20
21
|
const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder()
|
|
21
22
|
.setEngine('tree-sitter')
|
|
@@ -95,8 +96,8 @@ ${await (0, doc_normalized_ast_1.printNormalizedAstForCode)(treeSitter, 'x <- 2
|
|
|
95
96
|
> you can either use the [Visual Studio Code extension](${doc_files_1.FlowrGithubBaseRef}/vscode-flowr) or the ${(0, doc_cli_option_1.getReplCommand)('normalize*')}
|
|
96
97
|
> command in the REPL (see the [Interface wiki page](${doc_files_1.FlowrWikiBaseRef}/Interface) for more information).
|
|
97
98
|
|
|
98
|
-
Indicative of the normalization is the root ${ctx.link(
|
|
99
|
-
and provides the ${ctx.link(
|
|
99
|
+
Indicative of the normalization is the root ${ctx.link(r_project_1.RProject)} node, which is present in every normalized AST
|
|
100
|
+
and provides the ${ctx.link(r_expression_list_1.RExpressionList)} nodes for each file in the project.
|
|
100
101
|
In general, we provide node types for:
|
|
101
102
|
|
|
102
103
|
1. literals (e.g., numbers and strings)
|
|
@@ -112,7 +113,7 @@ In general, we provide node types for:
|
|
|
112
113
|
Every node is a link, which directly refers to the implementation in the source code.
|
|
113
114
|
Grayed-out parts are used for structuring the AST, grouping together related nodes.
|
|
114
115
|
|
|
115
|
-
${(0, doc_code_1.codeBlock)('mermaid', ctx.mermaid(
|
|
116
|
+
${(0, doc_code_1.codeBlock)('mermaid', ctx.mermaid(model_1.RNode))}
|
|
116
117
|
|
|
117
118
|
</details>
|
|
118
119
|
|
|
@@ -123,7 +124,7 @@ Most notably, the \`info\` field holds the \`id\` of the node, which is used to
|
|
|
123
124
|
|
|
124
125
|
In summary, we have the following types:
|
|
125
126
|
|
|
126
|
-
${(0, doc_structure_1.details)('Normalized AST Node Types', ctx.hierarchy(
|
|
127
|
+
${(0, doc_structure_1.details)('Normalized AST Node Types', ctx.hierarchy(model_1.RNode, { collapseFromNesting: Number.MAX_VALUE, ignoredTypes: ['Info', 'LogLevel'] }))}
|
|
127
128
|
|
|
128
129
|
The following segments intend to give you an overview of how to work with the normalized AST:
|
|
129
130
|
|
|
@@ -29,7 +29,6 @@ const vertex_1 = require("../dataflow/graph/vertex");
|
|
|
29
29
|
const control_flow_query_executor_1 = require("../queries/catalog/control-flow-query/control-flow-query-executor");
|
|
30
30
|
const doc_cfg_1 = require("./doc-util/doc-cfg");
|
|
31
31
|
const df_shape_query_executor_1 = require("../queries/catalog/df-shape-query/df-shape-query-executor");
|
|
32
|
-
const _00_slice_1 = require("../core/steps/all/static-slicing/00-slice");
|
|
33
32
|
const doc_repl_1 = require("./doc-util/doc-repl");
|
|
34
33
|
const inspect_higher_order_query_executor_1 = require("../queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor");
|
|
35
34
|
const doc_escape_1 = require("./doc-util/doc-escape");
|
|
@@ -39,6 +38,8 @@ const call_graph_query_executor_1 = require("../queries/catalog/call-graph-query
|
|
|
39
38
|
const inspect_recursion_query_executor_1 = require("../queries/catalog/inspect-recursion-query/inspect-recursion-query-executor");
|
|
40
39
|
const does_call_query_executor_1 = require("../queries/catalog/does-call-query/does-call-query-executor");
|
|
41
40
|
const inspect_exception_query_executor_1 = require("../queries/catalog/inspect-exceptions-query/inspect-exception-query-executor");
|
|
41
|
+
const slice_direction_1 = require("../util/slice-direction");
|
|
42
|
+
const provenance_query_executor_1 = require("../queries/catalog/provenance-query/provenance-query-executor");
|
|
42
43
|
(0, doc_query_1.registerQueryDocumentation)('call-context', {
|
|
43
44
|
name: 'Call-Context Query',
|
|
44
45
|
type: 'active',
|
|
@@ -554,7 +555,7 @@ To specify a variable of interest, you have to present flowR with a [slicing cri
|
|
|
554
555
|
|
|
555
556
|
To exemplify the capabilities, consider the following code:
|
|
556
557
|
${(0, doc_code_1.codeBlock)('r', exampleCode)}
|
|
557
|
-
If you are interested in the parts required for the use of \`x\` in the last line
|
|
558
|
+
If you are interested in the parts required for the use of \`x\` in the last line and \`z\`, you can use the following query:
|
|
558
559
|
|
|
559
560
|
${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
|
|
560
561
|
type: 'static-slice',
|
|
@@ -575,7 +576,7 @@ Likewise, if you want the forward slice for the first use of \`x\`, you can do i
|
|
|
575
576
|
${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
|
|
576
577
|
type: 'static-slice',
|
|
577
578
|
criteria: ['1@x'],
|
|
578
|
-
direction:
|
|
579
|
+
direction: slice_direction_1.SliceDirection.Forward
|
|
579
580
|
}], { showCode: false, shorthand: (0, doc_query_1.sliceQueryShorthand)(['1@x'], (0, doc_escape_1.escapeNewline)(exampleCode), true) })}
|
|
580
581
|
|
|
581
582
|
You can disable [magic comments](${doc_files_1.FlowrWikiBaseRef}/Interface#slice-magic-comments) using the \`noMagicComments\` flag.
|
|
@@ -583,6 +584,30 @@ This query replaces the old [\`request-slice\`](${doc_files_1.FlowrWikiBaseRef}/
|
|
|
583
584
|
`;
|
|
584
585
|
}
|
|
585
586
|
});
|
|
587
|
+
(0, doc_query_1.registerQueryDocumentation)('provenance', {
|
|
588
|
+
name: 'Provenance Query',
|
|
589
|
+
type: 'active',
|
|
590
|
+
shortDescription: 'Calculate the provenance of a given variable, optionally restricted to its enveloping fdef',
|
|
591
|
+
functionName: provenance_query_executor_1.executeProvenanceQuery.name,
|
|
592
|
+
functionFile: '../queries/catalog/provenance-query/provenance-query-executor.ts',
|
|
593
|
+
buildExplanation: async (shell) => {
|
|
594
|
+
const exampleCode = 'x <- 1\ny <- 2\nz <- 3\nx';
|
|
595
|
+
const criterion = '4@x';
|
|
596
|
+
return `
|
|
597
|
+
Given a [slicing criterion](${doc_files_1.FlowrWikiBaseRef}/Terminology#slicing-criterion), flowR will return the provenance
|
|
598
|
+
of the given program element (i.e., all related vertices in a non-interprocedural and non-context sensitive backward slice).
|
|
599
|
+
|
|
600
|
+
To exemplify the capabilities, consider the following code:
|
|
601
|
+
${(0, doc_code_1.codeBlock)('r', exampleCode)}
|
|
602
|
+
If you are interested in the provenance of the \`x\` in the last line you can use:
|
|
603
|
+
|
|
604
|
+
${await (0, doc_query_1.showQuery)(shell, exampleCode, [{
|
|
605
|
+
type: 'provenance',
|
|
606
|
+
criterion
|
|
607
|
+
}], { showCode: false, shorthand: (0, doc_query_1.sliceQueryShorthand)([criterion], (0, doc_escape_1.escapeNewline)(exampleCode)) })}
|
|
608
|
+
`;
|
|
609
|
+
}
|
|
610
|
+
});
|
|
586
611
|
(0, doc_query_1.registerQueryDocumentation)('dependencies', {
|
|
587
612
|
name: 'Dependencies Query',
|
|
588
613
|
type: 'active',
|
package/engines.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FlowrConfig, type KnownEngines } from './config';
|
|
2
2
|
/**
|
|
3
3
|
* Retrieve all requested engine instance.
|
|
4
4
|
* Please make sure that if this includes the R engine, that you properly shut it down again!
|
|
5
5
|
*/
|
|
6
|
-
export declare function retrieveEngineInstances(config:
|
|
6
|
+
export declare function retrieveEngineInstances(config: FlowrConfig, defaultOnly?: boolean): Promise<{
|
|
7
7
|
engines: KnownEngines;
|
|
8
8
|
default: keyof KnownEngines;
|
|
9
9
|
}>;
|
package/engines.js
CHANGED
|
@@ -12,9 +12,9 @@ const log_1 = require("./util/log");
|
|
|
12
12
|
*/
|
|
13
13
|
async function retrieveEngineInstances(config, defaultOnly = false) {
|
|
14
14
|
const engines = {};
|
|
15
|
-
if (
|
|
15
|
+
if (config_1.FlowrConfig.getForEngine(config, 'r-shell') && (!defaultOnly || config.defaultEngine === 'r-shell')) {
|
|
16
16
|
// we keep an active shell session to allow other parse investigations :)
|
|
17
|
-
engines['r-shell'] = new shell_1.RShell(
|
|
17
|
+
engines['r-shell'] = new shell_1.RShell(config_1.FlowrConfig.getForEngine(config, 'r-shell'), {
|
|
18
18
|
revive: 2 /* RShellReviveOptions.Always */,
|
|
19
19
|
onRevive: (code, signal) => {
|
|
20
20
|
const signalText = signal == null ? '' : ` and signal ${signal}`;
|
|
@@ -23,8 +23,8 @@ async function retrieveEngineInstances(config, defaultOnly = false) {
|
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
-
if (
|
|
27
|
-
await tree_sitter_executor_1.TreeSitterExecutor.initTreeSitter(
|
|
26
|
+
if (config_1.FlowrConfig.getForEngine(config, 'tree-sitter') && (!defaultOnly || config.defaultEngine === 'tree-sitter')) {
|
|
27
|
+
await tree_sitter_executor_1.TreeSitterExecutor.initTreeSitter(config_1.FlowrConfig.getForEngine(config, 'tree-sitter'));
|
|
28
28
|
engines['tree-sitter'] = new tree_sitter_executor_1.TreeSitterExecutor();
|
|
29
29
|
}
|
|
30
30
|
let defaultEngine = config.defaultEngine;
|
package/linter/linter-rules.d.ts
CHANGED
|
@@ -277,10 +277,33 @@ export declare const LintingRules: {
|
|
|
277
277
|
readonly certainty: import("./linter-format").LintingRuleCertainty.BestEffort;
|
|
278
278
|
readonly tags: readonly [import("./linter-tags").LintingRuleTag.Smell, import("./linter-tags").LintingRuleTag.Readability];
|
|
279
279
|
readonly defaultConfig: {
|
|
280
|
-
readonly loopyFunctions: Set<import("../dataflow/environments/built-in").BuiltInProcName>;
|
|
280
|
+
readonly loopyFunctions: Set<import("../dataflow/environments/built-in-proc-name").BuiltInProcName>;
|
|
281
281
|
};
|
|
282
282
|
};
|
|
283
283
|
};
|
|
284
|
+
readonly 'stop-call': {
|
|
285
|
+
readonly createSearch: () => import("../search/flowr-search-builder").FlowrSearchBuilder<"get", ["filter"], import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, Promise<import("../search/flowr-search").FlowrSearchElements<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, [] | import("../search/flowr-search").FlowrSearchElement<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>>>;
|
|
286
|
+
readonly processSearchResult: (elements: import("../search/flowr-search").FlowrSearchElements<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../search/flowr-search").FlowrSearchElement<import("../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>, _config: import("../util/objects").MergeableRecord, { dataflow, analyzer }: {
|
|
287
|
+
normalize: import("../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
288
|
+
dataflow: import("../dataflow/info").DataflowInformation;
|
|
289
|
+
cfg: import("../control-flow/control-flow-graph").ControlFlowInformation;
|
|
290
|
+
analyzer: import("../project/flowr-analyzer").ReadonlyFlowrAnalysisProvider;
|
|
291
|
+
}) => {
|
|
292
|
+
results: import("ts-essentials").Writable<import("./rules/stop-with-call-arg").StopWithCallResult>[];
|
|
293
|
+
'.meta': import("./rules/stop-with-call-arg").StopWithCallMetadata;
|
|
294
|
+
};
|
|
295
|
+
readonly prettyPrint: {
|
|
296
|
+
readonly query: (result: import("./rules/stop-with-call-arg").StopWithCallResult) => string;
|
|
297
|
+
readonly full: (result: import("./rules/stop-with-call-arg").StopWithCallResult) => string;
|
|
298
|
+
};
|
|
299
|
+
readonly info: {
|
|
300
|
+
readonly name: "Stop without call.=False argument";
|
|
301
|
+
readonly tags: readonly [import("./linter-tags").LintingRuleTag.Smell];
|
|
302
|
+
readonly certainty: import("./linter-format").LintingRuleCertainty.BestEffort;
|
|
303
|
+
readonly description: "Checks whether stop calls without call. argument set to FALSE are used.";
|
|
304
|
+
readonly defaultConfig: {};
|
|
305
|
+
};
|
|
306
|
+
};
|
|
284
307
|
};
|
|
285
308
|
export type LintingRuleNames = keyof typeof LintingRules;
|
|
286
309
|
export type LintingRuleMetadata<Name extends LintingRuleNames> = typeof LintingRules[Name] extends LintingRule<infer _Result, infer Metadata, infer _Config, infer _Info, infer _Elements> ? Metadata : never;
|
package/linter/linter-rules.js
CHANGED
|
@@ -11,6 +11,7 @@ const naming_convention_1 = require("./rules/naming-convention");
|
|
|
11
11
|
const dataframe_access_validation_1 = require("./rules/dataframe-access-validation");
|
|
12
12
|
const useless_loop_1 = require("./rules/useless-loop");
|
|
13
13
|
const network_functions_1 = require("./rules/network-functions");
|
|
14
|
+
const stop_with_call_arg_1 = require("./rules/stop-with-call-arg");
|
|
14
15
|
/**
|
|
15
16
|
* The registry of currently supported linting rules.
|
|
16
17
|
* A linting rule can be executed on a dataflow pipeline result using {@link executeLintingRule}.
|
|
@@ -25,6 +26,7 @@ exports.LintingRules = {
|
|
|
25
26
|
'network-functions': network_functions_1.NETWORK_FUNCTIONS,
|
|
26
27
|
'dataframe-access-validation': dataframe_access_validation_1.DATA_FRAME_ACCESS_VALIDATION,
|
|
27
28
|
'dead-code': dead_code_1.DEAD_CODE,
|
|
28
|
-
'useless-loop': useless_loop_1.USELESS_LOOP
|
|
29
|
+
'useless-loop': useless_loop_1.USELESS_LOOP,
|
|
30
|
+
'stop-call': stop_with_call_arg_1.STOP_WITH_CALL_ARG
|
|
29
31
|
};
|
|
30
32
|
//# sourceMappingURL=linter-rules.js.map
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DATA_FRAME_ACCESS_VALIDATION = void 0;
|
|
4
4
|
const shape_inference_1 = require("../../abstract-interpretation/data-frame/shape-inference");
|
|
5
5
|
const satisfiable_domain_1 = require("../../abstract-interpretation/domains/satisfiable-domain");
|
|
6
|
-
const config_1 = require("../../config");
|
|
7
6
|
const cfg_kind_1 = require("../../project/cfg-kind");
|
|
8
7
|
const type_1 = require("../../r-bridge/lang-4.x/ast/model/type");
|
|
9
8
|
const flowr_search_builder_1 = require("../../search/flowr-search-builder");
|
|
@@ -13,13 +12,14 @@ const range_1 = require("../../util/range");
|
|
|
13
12
|
const linter_format_1 = require("../linter-format");
|
|
14
13
|
const linter_tags_1 = require("../linter-tags");
|
|
15
14
|
const identifier_1 = require("../../dataflow/environments/identifier");
|
|
15
|
+
const config_1 = require("../../config");
|
|
16
16
|
exports.DATA_FRAME_ACCESS_VALIDATION = {
|
|
17
17
|
createSearch: () => flowr_search_builder_1.Q.all().with(search_enrichers_1.Enrichment.CallTargets, { onlyBuiltin: true }),
|
|
18
18
|
processSearchResult: async (elements, config, data) => {
|
|
19
19
|
let ctx = data.analyzer.inspectContext();
|
|
20
20
|
ctx = {
|
|
21
21
|
...ctx,
|
|
22
|
-
config:
|
|
22
|
+
config: config_1.FlowrConfig.amend(data.analyzer.flowrConfig, flowrConfig => {
|
|
23
23
|
if (config.readLoadedData !== undefined) {
|
|
24
24
|
flowrConfig.abstractInterpretation.dataFrame.readLoadedData.readExternalFiles = config.readLoadedData;
|
|
25
25
|
}
|
|
@@ -61,7 +61,7 @@ exports.DATA_FRAME_ACCESS_VALIDATION = {
|
|
|
61
61
|
.map(({ nodeId, operand, ...accessed }) => ({
|
|
62
62
|
...accessed,
|
|
63
63
|
node: data.normalize.idMap.get(nodeId),
|
|
64
|
-
operand: operand
|
|
64
|
+
operand: operand === undefined ? undefined : data.normalize.idMap.get(operand),
|
|
65
65
|
}))
|
|
66
66
|
.map(({ node, operand, ...accessed }) => ({
|
|
67
67
|
...accessed,
|
|
@@ -76,10 +76,10 @@ exports.DATA_FRAME_ACCESS_VALIDATION = {
|
|
|
76
76
|
prettyPrint: {
|
|
77
77
|
[linter_format_1.LintingPrettyPrintContext.Query]: result => `Access of ${result.type} ` +
|
|
78
78
|
(typeof result.accessed === 'string' ? `"${result.accessed}"` : result.accessed) + ' ' +
|
|
79
|
-
(result.operand
|
|
79
|
+
(result.operand === undefined ? `at \`${result.access}\`` : `of \`${result.operand}\``) + ` at ${range_1.SourceRange.format(result.range)}`,
|
|
80
80
|
[linter_format_1.LintingPrettyPrintContext.Full]: result => `Accessed ${result.type} ` +
|
|
81
81
|
(typeof result.accessed === 'string' ? `"${result.accessed}"` : result.accessed) + ' does not exist ' +
|
|
82
|
-
(result.operand
|
|
82
|
+
(result.operand === undefined ? `at \`${result.access}\`` : `in \`${result.operand}\``) + ` at ${range_1.SourceRange.format(result.range)}`
|
|
83
83
|
},
|
|
84
84
|
info: {
|
|
85
85
|
name: 'Dataframe Access Validation',
|
|
@@ -53,7 +53,7 @@ export declare function getMostUsedCasing(symbols: {
|
|
|
53
53
|
/**
|
|
54
54
|
* Attempts to fix the casing of the given identifier to match the provided convention.
|
|
55
55
|
*/
|
|
56
|
-
export declare function fixCasing(identifier: string, convention: CasingConvention): string | undefined;
|
|
56
|
+
export declare function fixCasing(identifier: string, convention: CasingConvention, ignorePrefix?: string): string | undefined;
|
|
57
57
|
/**
|
|
58
58
|
* Creates quick fixes for renaming all references to the given node to match the provided replacement.
|
|
59
59
|
*/
|
|
@@ -91,11 +91,15 @@ function getMostUsedCasing(symbols) {
|
|
|
91
91
|
/**
|
|
92
92
|
* Attempts to fix the casing of the given identifier to match the provided convention.
|
|
93
93
|
*/
|
|
94
|
-
function fixCasing(identifier, convention) {
|
|
94
|
+
function fixCasing(identifier, convention, ignorePrefix) {
|
|
95
95
|
if (!containsAlpha(identifier)) {
|
|
96
96
|
return undefined;
|
|
97
97
|
}
|
|
98
|
-
|
|
98
|
+
if (ignorePrefix) {
|
|
99
|
+
identifier = identifier.replace(new RegExp(`^(${ignorePrefix})`), '');
|
|
100
|
+
}
|
|
101
|
+
const splitOn = identifier.includes('_') ? /_/ : /(?=[A-Z])/;
|
|
102
|
+
const tokens = identifier.split(splitOn).map(s => s.toLowerCase());
|
|
99
103
|
const firstUp = (s) => {
|
|
100
104
|
if (s.length < 1) {
|
|
101
105
|
return s.toUpperCase();
|
|
@@ -167,7 +171,7 @@ exports.NAMING_CONVENTION = {
|
|
|
167
171
|
const results = symbols
|
|
168
172
|
.filter(m => (m.detectedCasing !== casing) && (!config.ignoreNonAlpha || containsAlpha(m.name)))
|
|
169
173
|
.map(({ id, ...m }) => {
|
|
170
|
-
const fix = fixCasing(m.name, casing);
|
|
174
|
+
const fix = fixCasing(m.name, casing, config.ignorePrefix);
|
|
171
175
|
return {
|
|
172
176
|
...m,
|
|
173
177
|
involvedId: id,
|