@eagleoutice/flowr 2.4.8 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -45
- package/benchmark/slicer.js +1 -1
- package/benchmark/summarizer/second-phase/graph.js +2 -2
- package/cli/flowr.js +3 -29
- package/cli/repl/commands/repl-cfg.d.ts +5 -5
- package/cli/repl/commands/repl-cfg.js +21 -22
- package/cli/repl/commands/repl-commands.d.ts +3 -3
- package/cli/repl/commands/repl-commands.js +2 -0
- package/cli/repl/commands/repl-dataflow.d.ts +5 -5
- package/cli/repl/commands/repl-dataflow.js +27 -30
- package/cli/repl/commands/repl-execute.js +1 -0
- package/cli/repl/commands/repl-lineage.js +1 -0
- package/cli/repl/commands/repl-main.d.ts +34 -3
- package/cli/repl/commands/repl-normalize.d.ts +3 -3
- package/cli/repl/commands/repl-normalize.js +15 -19
- package/cli/repl/commands/repl-parse.d.ts +2 -2
- package/cli/repl/commands/repl-parse.js +13 -8
- package/cli/repl/commands/repl-query.d.ts +3 -3
- package/cli/repl/commands/repl-query.js +29 -19
- package/cli/repl/commands/repl-quit.js +1 -0
- package/cli/repl/commands/repl-version.js +1 -0
- package/cli/repl/core.d.ts +4 -1
- package/cli/repl/core.js +21 -1
- package/cli/repl/server/connection.d.ts +7 -3
- package/cli/repl/server/connection.js +40 -48
- package/cli/repl/server/messages/message-slice.d.ts +1 -1
- package/cli/slicer-app.js +8 -3
- package/config.d.ts +1 -1
- package/config.js +4 -1
- package/control-flow/extract-cfg.d.ts +1 -1
- package/control-flow/extract-cfg.js +1 -1
- package/core/pipeline-executor.d.ts +5 -0
- package/core/pipeline-executor.js +5 -0
- package/core/steps/pipeline/create-pipeline.js +1 -1
- package/core/steps/pipeline/default-pipelines.d.ts +42 -42
- package/core/steps/pipeline/default-pipelines.js +4 -1
- package/dataflow/graph/dataflowgraph-builder.d.ts +11 -12
- package/dataflow/graph/dataflowgraph-builder.js +6 -6
- package/documentation/doc-util/doc-query.d.ts +3 -6
- package/documentation/doc-util/doc-query.js +5 -17
- package/documentation/doc-util/doc-search.js +7 -10
- package/documentation/doc-util/doc-structure.d.ts +4 -0
- package/documentation/doc-util/doc-structure.js +28 -0
- package/documentation/doc-util/doc-types.d.ts +5 -1
- package/documentation/doc-util/doc-types.js +29 -3
- package/documentation/print-analyzer-wiki.d.ts +1 -0
- package/documentation/print-analyzer-wiki.js +137 -0
- package/documentation/print-core-wiki.d.ts +2 -1
- package/documentation/print-core-wiki.js +58 -4
- package/documentation/print-dataflow-graph-wiki.js +15 -22
- package/documentation/print-interface-wiki.js +18 -1
- package/documentation/print-linter-wiki.js +5 -1
- package/documentation/print-linting-and-testing-wiki.js +4 -0
- package/documentation/print-normalized-ast-wiki.js +6 -8
- package/documentation/print-readme.js +6 -0
- package/engines.d.ts +9 -0
- package/engines.js +38 -0
- package/linter/linter-executor.d.ts +2 -8
- package/linter/linter-executor.js +9 -4
- package/linter/linter-format.d.ts +8 -9
- package/linter/linter-rules.d.ts +57 -15
- package/linter/linter-rules.js +2 -0
- package/linter/rules/absolute-path.d.ts +1 -0
- package/linter/rules/dataframe-access-validation.d.ts +4 -3
- package/linter/rules/dataframe-access-validation.js +7 -4
- package/linter/rules/dead-code.d.ts +2 -1
- package/linter/rules/deprecated-functions.d.ts +15 -28
- package/linter/rules/deprecated-functions.js +5 -43
- package/linter/rules/file-path-validity.d.ts +2 -1
- package/linter/rules/file-path-validity.js +1 -1
- package/linter/rules/function-finder-util.d.ts +51 -0
- package/linter/rules/function-finder-util.js +77 -0
- package/linter/rules/naming-convention.d.ts +2 -1
- package/linter/rules/network-functions.d.ts +40 -0
- package/linter/rules/network-functions.js +24 -0
- package/linter/rules/seeded-randomness.d.ts +2 -1
- package/linter/rules/unused-definition.d.ts +2 -1
- package/linter/rules/useless-loop.d.ts +3 -2
- package/linter/rules/useless-loop.js +4 -6
- package/package.json +5 -1
- package/project/cache/flowr-analyzer-cache.d.ts +93 -0
- package/project/cache/flowr-analyzer-cache.js +156 -0
- package/project/cache/flowr-cache.d.ts +28 -0
- package/project/cache/flowr-cache.js +49 -0
- package/project/context/abstract-flowr-analyzer-context.d.ts +35 -0
- package/project/context/abstract-flowr-analyzer-context.js +46 -0
- package/project/context/flowr-analyzer-context.d.ts +48 -0
- package/project/context/flowr-analyzer-context.js +47 -0
- package/project/context/flowr-analyzer-dependencies-context.d.ts +38 -0
- package/project/context/flowr-analyzer-dependencies-context.js +39 -0
- package/project/context/flowr-analyzer-files-context.d.ts +86 -0
- package/project/context/flowr-analyzer-files-context.js +130 -0
- package/project/context/flowr-analyzer-loading-order-context.d.ts +76 -0
- package/project/context/flowr-analyzer-loading-order-context.js +90 -0
- package/project/context/flowr-file.d.ts +89 -0
- package/project/context/flowr-file.js +78 -0
- package/project/flowr-analyzer-builder.d.ts +106 -0
- package/project/flowr-analyzer-builder.js +197 -0
- package/project/flowr-analyzer.d.ts +125 -0
- package/project/flowr-analyzer.js +81 -0
- package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.d.ts +17 -0
- package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.js +28 -0
- package/project/plugins/file-plugins/flowr-analyzer-file-plugin.d.ts +21 -0
- package/project/plugins/file-plugins/flowr-analyzer-file-plugin.js +34 -0
- package/project/plugins/file-plugins/flowr-description-file.d.ts +24 -0
- package/project/plugins/file-plugins/flowr-description-file.js +38 -0
- package/project/plugins/flowr-analyzer-plugin.d.ts +90 -0
- package/project/plugins/flowr-analyzer-plugin.js +82 -0
- package/project/plugins/loading-order-plugins/flowr-analyzer-loading-order-description-file-plugin.d.ts +14 -0
- package/project/plugins/loading-order-plugins/flowr-analyzer-loading-order-description-file-plugin.js +56 -0
- package/project/plugins/loading-order-plugins/flowr-analyzer-loading-order-plugin.d.ts +13 -0
- package/project/plugins/loading-order-plugins/flowr-analyzer-loading-order-plugin.js +33 -0
- package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-description-file-plugin.d.ts +14 -0
- package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-description-file-plugin.js +41 -0
- package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-plugin.d.ts +10 -0
- package/project/plugins/package-version-plugins/flowr-analyzer-package-versions-plugin.js +29 -0
- package/project/plugins/package-version-plugins/package.d.ts +15 -0
- package/project/plugins/package-version-plugins/package.js +56 -0
- package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.d.ts +15 -0
- package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.js +44 -0
- package/queries/base-query-format.d.ts +2 -8
- package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
- package/queries/catalog/call-context-query/call-context-query-executor.js +20 -13
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +2 -3
- package/queries/catalog/call-context-query/call-context-query-format.js +2 -2
- package/queries/catalog/cluster-query/cluster-query-executor.d.ts +1 -1
- package/queries/catalog/cluster-query/cluster-query-executor.js +2 -2
- package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -54
- package/queries/catalog/cluster-query/cluster-query-format.js +2 -2
- package/queries/catalog/config-query/config-query-executor.d.ts +1 -1
- package/queries/catalog/config-query/config-query-executor.js +5 -5
- package/queries/catalog/config-query/config-query-format.d.ts +1 -1
- package/queries/catalog/config-query/config-query-format.js +1 -1
- package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +1 -1
- package/queries/catalog/control-flow-query/control-flow-query-executor.js +2 -3
- package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +1 -54
- package/queries/catalog/control-flow-query/control-flow-query-format.js +2 -2
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-executor.d.ts +1 -1
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-executor.js +2 -2
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -54
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.js +1 -1
- package/queries/catalog/dataflow-query/dataflow-query-executor.d.ts +1 -1
- package/queries/catalog/dataflow-query/dataflow-query-executor.js +2 -2
- package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -54
- package/queries/catalog/dataflow-query/dataflow-query-format.js +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.d.ts +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +19 -12
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +7 -56
- package/queries/catalog/dependencies-query/dependencies-query-format.js +7 -4
- package/queries/catalog/df-shape-query/df-shape-query-executor.d.ts +1 -1
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +4 -4
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +1 -54
- package/queries/catalog/df-shape-query/df-shape-query-format.js +1 -1
- package/queries/catalog/happens-before-query/happens-before-query-executor.d.ts +1 -1
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -1
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -54
- package/queries/catalog/happens-before-query/happens-before-query-format.js +1 -1
- package/queries/catalog/id-map-query/id-map-query-executor.d.ts +1 -1
- package/queries/catalog/id-map-query/id-map-query-executor.js +2 -2
- package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -54
- package/queries/catalog/id-map-query/id-map-query-format.js +2 -2
- package/queries/catalog/lineage-query/lineage-query-executor.d.ts +1 -1
- package/queries/catalog/lineage-query/lineage-query-executor.js +2 -2
- package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -54
- package/queries/catalog/lineage-query/lineage-query-format.js +1 -1
- package/queries/catalog/linter-query/linter-query-executor.d.ts +1 -1
- package/queries/catalog/linter-query/linter-query-executor.js +2 -3
- package/queries/catalog/linter-query/linter-query-format.d.ts +1 -54
- package/queries/catalog/linter-query/linter-query-format.js +1 -1
- package/queries/catalog/location-map-query/location-map-query-executor.d.ts +1 -1
- package/queries/catalog/location-map-query/location-map-query-executor.js +3 -2
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +1 -1
- package/queries/catalog/location-map-query/location-map-query-format.js +1 -1
- package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.d.ts +1 -1
- package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.js +2 -2
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -54
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +1 -1
- package/queries/catalog/origin-query/origin-query-executor.d.ts +2 -2
- package/queries/catalog/origin-query/origin-query-executor.js +3 -3
- package/queries/catalog/origin-query/origin-query-format.d.ts +1 -54
- package/queries/catalog/origin-query/origin-query-format.js +1 -1
- package/queries/catalog/project-query/project-query-executor.d.ts +1 -1
- package/queries/catalog/project-query/project-query-executor.js +2 -2
- package/queries/catalog/project-query/project-query-format.d.ts +1 -54
- package/queries/catalog/project-query/project-query-format.js +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +4 -2
- package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +1 -54
- package/queries/catalog/resolve-value-query/resolve-value-query-format.js +1 -1
- package/queries/catalog/search-query/search-query-executor.d.ts +1 -1
- package/queries/catalog/search-query/search-query-executor.js +3 -3
- package/queries/catalog/search-query/search-query-format.d.ts +1 -54
- package/queries/catalog/search-query/search-query-format.js +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +3 -3
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -54
- package/queries/catalog/static-slice-query/static-slice-query-format.js +1 -1
- package/queries/query-print.d.ts +4 -4
- package/queries/query-print.js +12 -12
- package/queries/query.d.ts +29 -885
- package/queries/query.js +1 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +1 -1
- package/r-bridge/retriever.d.ts +15 -2
- package/r-bridge/retriever.js +15 -5
- package/search/flowr-search-executor.d.ts +3 -5
- package/search/flowr-search-executor.js +6 -4
- package/search/flowr-search-filters.d.ts +12 -6
- package/search/flowr-search-filters.js +1 -1
- package/search/flowr-search.d.ts +5 -16
- package/search/flowr-search.js +14 -5
- package/search/search-executor/search-enrichers.d.ts +37 -36
- package/search/search-executor/search-enrichers.js +4 -4
- package/search/search-executor/search-generators.d.ts +12 -12
- package/search/search-executor/search-generators.js +27 -19
- package/search/search-executor/search-mappers.d.ts +5 -5
- package/search/search-executor/search-transformer.d.ts +17 -17
- package/search/search-executor/search-transformer.js +14 -7
- package/util/collections/arrays.d.ts +1 -0
- package/util/collections/arrays.js +15 -0
- package/util/collections/objectmap.d.ts +17 -0
- package/util/collections/objectmap.js +28 -0
- package/util/containers.d.ts +0 -1
- package/util/containers.js +0 -1
- package/util/files.d.ts +17 -0
- package/util/files.js +65 -0
- package/util/formats/adapter-format.d.ts +6 -0
- package/util/formats/adapter-format.js +3 -0
- package/util/formats/adapter.d.ts +18 -0
- package/util/formats/adapter.js +49 -0
- package/util/formats/adapters/r-adapter.d.ts +4 -0
- package/util/formats/adapters/r-adapter.js +7 -0
- package/util/formats/adapters/rmd-adapter.d.ts +26 -0
- package/util/formats/adapters/rmd-adapter.js +91 -0
- package/util/version.js +1 -1
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import type { RShell } from '../../r-bridge/shell';
|
|
2
|
-
import type { Queries,
|
|
3
|
-
import { DEFAULT_DATAFLOW_PIPELINE } from '../../core/steps/pipeline/default-pipelines';
|
|
2
|
+
import type { Queries, SupportedQueryTypes } from '../../queries/query';
|
|
4
3
|
import type { SupportedVirtualQueryTypes } from '../../queries/virtual-query/virtual-queries';
|
|
5
4
|
import type { VirtualCompoundConstraint } from '../../queries/virtual-query/compound-query';
|
|
6
|
-
|
|
7
|
-
export interface ShowQueryOptions<Base extends SupportedQueryTypes> {
|
|
5
|
+
export interface ShowQueryOptions {
|
|
8
6
|
readonly showCode?: boolean;
|
|
9
7
|
readonly collapseResult?: boolean;
|
|
10
8
|
readonly collapseQuery?: boolean;
|
|
11
|
-
readonly addOutput?: (result: QueryResults<Base>, pipeline: PipelineOutput<typeof DEFAULT_DATAFLOW_PIPELINE>) => string;
|
|
12
9
|
}
|
|
13
|
-
export declare function showQuery<Base extends SupportedQueryTypes, VirtualArguments extends VirtualCompoundConstraint<Base> = VirtualCompoundConstraint<Base>>(shell: RShell, code: string, queries: Queries<Base, VirtualArguments>, { showCode, collapseResult, collapseQuery
|
|
10
|
+
export declare function showQuery<Base extends SupportedQueryTypes, VirtualArguments extends VirtualCompoundConstraint<Base> = VirtualCompoundConstraint<Base>>(shell: RShell, code: string, queries: Queries<Base, VirtualArguments>, { showCode, collapseResult, collapseQuery }?: ShowQueryOptions): Promise<string>;
|
|
14
11
|
export interface QueryDocumentation {
|
|
15
12
|
readonly name: string;
|
|
16
13
|
readonly type: 'virtual' | 'active';
|
|
@@ -6,9 +6,6 @@ exports.registerQueryDocumentation = registerQueryDocumentation;
|
|
|
6
6
|
exports.linkToQueryOfName = linkToQueryOfName;
|
|
7
7
|
exports.tocForQueryType = tocForQueryType;
|
|
8
8
|
exports.explainQueries = explainQueries;
|
|
9
|
-
const query_1 = require("../../queries/query");
|
|
10
|
-
const pipeline_executor_1 = require("../../core/pipeline-executor");
|
|
11
|
-
const default_pipelines_1 = require("../../core/steps/pipeline/default-pipelines");
|
|
12
9
|
const retriever_1 = require("../../r-bridge/retriever");
|
|
13
10
|
const json_1 = require("../../util/json");
|
|
14
11
|
const ansi_1 = require("../../util/text/ansi");
|
|
@@ -17,19 +14,12 @@ const doc_dfg_1 = require("./doc-dfg");
|
|
|
17
14
|
const doc_code_1 = require("./doc-code");
|
|
18
15
|
const time_1 = require("../../util/text/time");
|
|
19
16
|
const query_print_1 = require("../../queries/query-print");
|
|
17
|
+
const flowr_analyzer_builder_1 = require("../../project/flowr-analyzer-builder");
|
|
20
18
|
const doc_cli_option_1 = require("./doc-cli-option");
|
|
21
|
-
|
|
22
|
-
async function showQuery(shell, code, queries, { showCode, collapseResult, collapseQuery, addOutput = () => '' } = {}) {
|
|
19
|
+
async function showQuery(shell, code, queries, { showCode, collapseResult, collapseQuery } = {}) {
|
|
23
20
|
const now = performance.now();
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
request: (0, retriever_1.requestFromInput)(code)
|
|
27
|
-
}, config_1.defaultConfigOptions).allRemainingSteps();
|
|
28
|
-
const results = await Promise.resolve((0, query_1.executeQueries)({
|
|
29
|
-
dataflow: analysis.dataflow,
|
|
30
|
-
ast: analysis.normalize,
|
|
31
|
-
config: (0, config_1.cloneConfig)(config_1.defaultConfigOptions)
|
|
32
|
-
}, queries));
|
|
21
|
+
const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder((0, retriever_1.requestFromInput)(code)).setParser(shell).build();
|
|
22
|
+
const results = await analyzer.query(queries);
|
|
33
23
|
const duration = performance.now() - now;
|
|
34
24
|
const metaInfo = `
|
|
35
25
|
The analysis required _${(0, time_1.printAsMs)(duration)}_ (including parsing and normalization and the query) within the generation environment.
|
|
@@ -52,7 +42,7 @@ ${collapseResult ? ' <details> <summary style="color:gray">Show Results</summary
|
|
|
52
42
|
|
|
53
43
|
_Results (prettified and summarized):_
|
|
54
44
|
|
|
55
|
-
${(0, query_print_1.asciiSummaryOfQueryResult)(ansi_1.markdownFormatter, duration, results,
|
|
45
|
+
${await (0, query_print_1.asciiSummaryOfQueryResult)(ansi_1.markdownFormatter, duration, results, analyzer, queries)}
|
|
56
46
|
|
|
57
47
|
<details> <summary style="color:gray">Show Detailed Results as Json</summary>
|
|
58
48
|
|
|
@@ -75,8 +65,6 @@ ${await (0, doc_dfg_1.printDfGraphForCode)(shell, code, { switchCodeAndGraph: tr
|
|
|
75
65
|
|
|
76
66
|
${collapseResult ? '</details>' : ''}
|
|
77
67
|
|
|
78
|
-
${addOutput(results, analysis)}
|
|
79
|
-
|
|
80
68
|
`;
|
|
81
69
|
}
|
|
82
70
|
exports.RegisteredQueries = {
|
|
@@ -6,29 +6,26 @@ exports.registerQueryDocumentation = registerQueryDocumentation;
|
|
|
6
6
|
exports.linkToQueryOfName = linkToQueryOfName;
|
|
7
7
|
exports.tocForQueryType = tocForQueryType;
|
|
8
8
|
exports.explainQueries = explainQueries;
|
|
9
|
-
const pipeline_executor_1 = require("../../core/pipeline-executor");
|
|
10
|
-
const default_pipelines_1 = require("../../core/steps/pipeline/default-pipelines");
|
|
11
9
|
const retriever_1 = require("../../r-bridge/retriever");
|
|
12
10
|
const doc_files_1 = require("./doc-files");
|
|
13
11
|
const doc_dfg_1 = require("./doc-dfg");
|
|
14
12
|
const doc_code_1 = require("./doc-code");
|
|
15
13
|
const time_1 = require("../../util/text/time");
|
|
16
|
-
const flowr_search_executor_1 = require("../../search/flowr-search-executor");
|
|
17
14
|
const flowr_search_printer_1 = require("../../search/flowr-search-printer");
|
|
18
15
|
const node_id_1 = require("../../r-bridge/lang-4.x/ast/model/processing/node-id");
|
|
19
16
|
const dfg_1 = require("../../util/mermaid/dfg");
|
|
20
|
-
const
|
|
17
|
+
const flowr_analyzer_builder_1 = require("../../project/flowr-analyzer-builder");
|
|
21
18
|
async function showSearch(shell, code, search, { collapseResult = true } = {}) {
|
|
22
19
|
const now = performance.now();
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const result = (0, flowr_search_executor_1.runSearch)(search, { ...analysis, config: config_1.defaultConfigOptions });
|
|
20
|
+
const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder((0, retriever_1.requestFromInput)(code))
|
|
21
|
+
.setParser(shell)
|
|
22
|
+
.build();
|
|
23
|
+
const result = await analyzer.runSearch(search);
|
|
28
24
|
const duration = performance.now() - now;
|
|
29
25
|
const metaInfo = `
|
|
30
26
|
The search required _${(0, time_1.printAsMs)(duration)}_ (including parsing and normalization and the query) within the generation environment.
|
|
31
27
|
`.trim();
|
|
28
|
+
const dataflow = await analyzer.dataflow();
|
|
32
29
|
return `
|
|
33
30
|
|
|
34
31
|
${(0, doc_code_1.codeBlock)('ts', (0, flowr_search_printer_1.flowrSearchToCode)(search))}
|
|
@@ -53,7 +50,7 @@ ${(0, doc_code_1.codeBlock)('json', JSON.stringify(search, null, 2))}
|
|
|
53
50
|
${collapseResult ? ' <details> <summary style="color:gray">Show Results</summary>' : ''}
|
|
54
51
|
|
|
55
52
|
The query returns the following vetices (all references to \`x\` in the code):
|
|
56
|
-
${result.getElements().map(({ node }) => `<b>${node.info.id} ('${(0, node_id_1.recoverContent)(node.info.id,
|
|
53
|
+
${result.getElements().map(({ node }) => `<b>${node.info.id} ('${(0, node_id_1.recoverContent)(node.info.id, dataflow.graph)}')</b> at L${(0, dfg_1.formatRange)(node.location)}`).join(', ')}
|
|
57
54
|
|
|
58
55
|
${metaInfo}
|
|
59
56
|
|
|
@@ -11,3 +11,7 @@ export interface BlockOptions {
|
|
|
11
11
|
}
|
|
12
12
|
export declare function block({ type, content }: BlockOptions): string;
|
|
13
13
|
export declare function section(title: string, depth?: 1 | 2 | 3 | 4 | 5 | 6, anchor?: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Supported pattern: `Name@link`
|
|
16
|
+
*/
|
|
17
|
+
export declare function collapsibleToc(content: Record<string, Record<string, Record<string, undefined> | undefined> | undefined>): string;
|
|
@@ -3,8 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.details = details;
|
|
4
4
|
exports.block = block;
|
|
5
5
|
exports.section = section;
|
|
6
|
+
exports.collapsibleToc = collapsibleToc;
|
|
6
7
|
const doc_general_1 = require("./doc-general");
|
|
7
8
|
const mermaid_1 = require("../../util/mermaid/mermaid");
|
|
9
|
+
const strings_1 = require("../../util/text/strings");
|
|
8
10
|
function details(title, content, { color, open = false, hideIfEmpty = true, prefixInit = '' } = {}) {
|
|
9
11
|
return hideIfEmpty && content.trim().length === 0 ? '' : `
|
|
10
12
|
${prefixInit}<details${open ? ' open' : ''}><summary style="${color ? 'color:' + color : ''}">${title}</summary>
|
|
@@ -23,4 +25,30 @@ ${(0, doc_general_1.prefixLines)(content, '> ')}
|
|
|
23
25
|
function section(title, depth = 2, anchor = (0, mermaid_1.escapeId)(title)) {
|
|
24
26
|
return `<h${depth} id="${anchor}">${title}</h${depth}>`;
|
|
25
27
|
}
|
|
28
|
+
function strToLink(str) {
|
|
29
|
+
const match = str.match(/^(.*?)@(.*)$/);
|
|
30
|
+
if (match) {
|
|
31
|
+
const [, name, link] = match;
|
|
32
|
+
return `[${name}](${link})`;
|
|
33
|
+
}
|
|
34
|
+
return `[${str}](#${(0, mermaid_1.escapeId)(str)})`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Supported pattern: `Name@link`
|
|
38
|
+
*/
|
|
39
|
+
function collapsibleToc(content) {
|
|
40
|
+
let output = '';
|
|
41
|
+
for (const [section, subsections] of Object.entries(content)) {
|
|
42
|
+
output += `- ${strToLink(section)}\n`;
|
|
43
|
+
if (subsections) {
|
|
44
|
+
for (const [subsection, items] of Object.entries(subsections)) {
|
|
45
|
+
output += ` - ${strToLink(subsection)} \n`;
|
|
46
|
+
if (items) {
|
|
47
|
+
output += ` ${(0, strings_1.joinWithLast)(Object.keys(items).map(strToLink))}\n`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return output;
|
|
53
|
+
}
|
|
26
54
|
//# sourceMappingURL=doc-structure.js.map
|
|
@@ -62,8 +62,12 @@ export declare function printHierarchy({ program, info, root, collapseFromNestin
|
|
|
62
62
|
interface FnInfo {
|
|
63
63
|
info: TypeElementInSource[];
|
|
64
64
|
program: ts.Program;
|
|
65
|
+
dropLinesStart?: number;
|
|
66
|
+
dropLinesEnd?: number;
|
|
67
|
+
doNotAutoGobble?: boolean;
|
|
68
|
+
hideDefinedAt?: boolean;
|
|
65
69
|
}
|
|
66
|
-
export declare function printCodeOfElement({ program, info }: FnInfo, name: string): string;
|
|
70
|
+
export declare function printCodeOfElement({ program, info, dropLinesEnd, dropLinesStart, doNotAutoGobble, hideDefinedAt }: FnInfo, name: string): string;
|
|
67
71
|
/**
|
|
68
72
|
* Create a short link to a type in the documentation
|
|
69
73
|
* @param name - The name of the type, e.g. `MyType`, may include a container, e.g.,`MyContainer::MyType` (this works with function nestings too)
|
|
@@ -387,14 +387,40 @@ function printHierarchy({ program, info, root, collapseFromNesting = 1, initialN
|
|
|
387
387
|
return thisLine + (out ? '\n' + out : '');
|
|
388
388
|
}
|
|
389
389
|
}
|
|
390
|
-
function printCodeOfElement({ program, info }, name) {
|
|
390
|
+
function printCodeOfElement({ program, info, dropLinesEnd = 0, dropLinesStart = 0, doNotAutoGobble, hideDefinedAt }, name) {
|
|
391
391
|
const node = info.find(e => e.name === name);
|
|
392
392
|
if (!node) {
|
|
393
393
|
console.error(`Could not find node ${name} when resolving function!`);
|
|
394
394
|
return '';
|
|
395
395
|
}
|
|
396
|
-
|
|
397
|
-
|
|
396
|
+
let code = node.node.getFullText(program.getSourceFile(node.node.getSourceFile().fileName)).trim();
|
|
397
|
+
if (dropLinesStart > 0 || dropLinesEnd > 0) {
|
|
398
|
+
const lines = code.split(/\n/g);
|
|
399
|
+
if (dropLinesStart + dropLinesEnd >= lines.length) {
|
|
400
|
+
return '';
|
|
401
|
+
}
|
|
402
|
+
code = lines.slice(dropLinesStart, lines.length - dropLinesEnd).join('\n');
|
|
403
|
+
}
|
|
404
|
+
if (!doNotAutoGobble) {
|
|
405
|
+
// gobble leading spaces
|
|
406
|
+
const lines = code.replaceAll('\t', ' ').split(/\n/g);
|
|
407
|
+
let gobble = Number.POSITIVE_INFINITY;
|
|
408
|
+
for (const line of lines) {
|
|
409
|
+
const match = line.match(/^(\s+)\S+/);
|
|
410
|
+
if (match) {
|
|
411
|
+
gobble = Math.min(gobble, match[1].length);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
if (gobble !== Number.POSITIVE_INFINITY && gobble > 0) {
|
|
415
|
+
code = lines.map(line => line.startsWith(' '.repeat(gobble)) ? line.slice(gobble) : line).join('\n');
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (hideDefinedAt) {
|
|
419
|
+
return (0, doc_code_1.codeBlock)('ts', code);
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
return `${(0, doc_code_1.codeBlock)('ts', code)}\n<i>Defined at <a href="${getTypePathLink(node)}">${getTypePathLink(node, '.')}</a></i>\n`;
|
|
423
|
+
}
|
|
398
424
|
}
|
|
399
425
|
function fuzzyCompare(a, b) {
|
|
400
426
|
const aStr = a.toLowerCase().replace(/[^a-z0-9]/g, '-').trim();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const shell_1 = require("../r-bridge/shell");
|
|
7
|
+
const log_1 = require("../../test/functionality/_helper/log");
|
|
8
|
+
const doc_auto_gen_1 = require("./doc-util/doc-auto-gen");
|
|
9
|
+
const doc_types_1 = require("./doc-util/doc-types");
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const flowr_analyzer_1 = require("../project/flowr-analyzer");
|
|
12
|
+
const flowr_analyzer_builder_1 = require("../project/flowr-analyzer-builder");
|
|
13
|
+
const doc_structure_1 = require("./doc-util/doc-structure");
|
|
14
|
+
const doc_files_1 = require("./doc-util/doc-files");
|
|
15
|
+
async function analyzerQuickExample() {
|
|
16
|
+
const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder()
|
|
17
|
+
.addRequestFromInput('x <- 1; print(x)')
|
|
18
|
+
.setEngine('tree-sitter')
|
|
19
|
+
.build();
|
|
20
|
+
// get the dataflow
|
|
21
|
+
const df = await analyzer.dataflow();
|
|
22
|
+
// obtain the identified loading order
|
|
23
|
+
console.log(analyzer.inspectContext().files.loadingOrder.getLoadingOrder());
|
|
24
|
+
// run a dependency query
|
|
25
|
+
const results = await analyzer.query([{ type: 'dependencies' }]);
|
|
26
|
+
return { analyzer, df, results };
|
|
27
|
+
}
|
|
28
|
+
async function getText(shell) {
|
|
29
|
+
const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
|
|
30
|
+
const types = (0, doc_types_1.getTypesFromFolder)({
|
|
31
|
+
rootFolder: path_1.default.resolve('src/'),
|
|
32
|
+
inlineTypes: doc_types_1.mermaidHide
|
|
33
|
+
});
|
|
34
|
+
return `${(0, doc_auto_gen_1.autoGenHeader)({ filename: module.filename, purpose: 'analyzer', rVersion: rversion })}
|
|
35
|
+
|
|
36
|
+
We are currently working on documenting the capabilities of the analyzer (with the plugins, their loading order, etc.). In general, the code documentation
|
|
37
|
+
starting with the ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, types.info)} and the ${(0, doc_types_1.shortLink)(flowr_analyzer_builder_1.FlowrAnalyzerBuilder.name, types.info)}
|
|
38
|
+
should be the best starting point.
|
|
39
|
+
|
|
40
|
+
${(0, doc_structure_1.collapsibleToc)({
|
|
41
|
+
'Overview': undefined,
|
|
42
|
+
'Builder Configuration': undefined,
|
|
43
|
+
'Plugins': {
|
|
44
|
+
'Plugin Types': {
|
|
45
|
+
'Dependency Identification': undefined,
|
|
46
|
+
'Project Discovery': undefined,
|
|
47
|
+
'File Loading': undefined,
|
|
48
|
+
'Loading Order': undefined
|
|
49
|
+
},
|
|
50
|
+
'How to add a new plugin': undefined,
|
|
51
|
+
'How to add a new plugin type': undefined
|
|
52
|
+
},
|
|
53
|
+
'Context Information': {
|
|
54
|
+
'Files Context': undefined,
|
|
55
|
+
'Loading Order Context': undefined,
|
|
56
|
+
'Dependencies Context': undefined
|
|
57
|
+
},
|
|
58
|
+
'Analyzer Internals': undefined
|
|
59
|
+
})}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
${(0, doc_structure_1.section)('Overview', 2)}
|
|
63
|
+
|
|
64
|
+
No matter whether you want to analyze a single R script, a couple of R notebooks, or a complete project,
|
|
65
|
+
your journey starts with the ${(0, doc_types_1.shortLink)(flowr_analyzer_builder_1.FlowrAnalyzerBuilder.name, types.info)} (further described in [Builder Configuration](#builder-configuration) below).
|
|
66
|
+
This builder allows you to configure the analysis in many different ways, for example, by specifying which files to analyze, which plugins to use, or
|
|
67
|
+
what [Engine](${doc_files_1.FlowrWikiBaseRef}/Engines) to use for the analysis.
|
|
68
|
+
|
|
69
|
+
${(0, doc_structure_1.block)({
|
|
70
|
+
type: 'NOTE',
|
|
71
|
+
content: `If you want to quickly try out the analyzer, you can use the following code snippet that analyzes a simple R expression:
|
|
72
|
+
|
|
73
|
+
${(0, doc_types_1.printCodeOfElement)({ program: types.program, info: types.info, dropLinesStart: 1, dropLinesEnd: 2, hideDefinedAt: true }, analyzerQuickExample.name)}
|
|
74
|
+
`
|
|
75
|
+
})}
|
|
76
|
+
|
|
77
|
+
**TODO**: mention [Context](#Context_Information)
|
|
78
|
+
|
|
79
|
+
${(0, doc_structure_1.section)('Builder Configuration', 2)}
|
|
80
|
+
|
|
81
|
+
**TODO** also explain buildSync and that TreeSitter has to be initialized for this
|
|
82
|
+
|
|
83
|
+
${(0, doc_structure_1.section)('Plugins', 2)}
|
|
84
|
+
|
|
85
|
+
${(0, doc_structure_1.section)('Plugin Types', 3)}
|
|
86
|
+
|
|
87
|
+
During the construction of a new ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, types.info)}, plugins of different types are applied at different stages of the analysis.
|
|
88
|
+
These plugins are grouped by their ${(0, doc_types_1.shortLink)('PluginType', types.info)} and are applied in the following order (as shown in the documentation of the ${(0, doc_types_1.shortLink)('PluginType', types.info)}):
|
|
89
|
+
|
|
90
|
+
${(() => {
|
|
91
|
+
const doc = (0, doc_types_1.getDocumentationForType)('PluginType', types.info);
|
|
92
|
+
// skip until the first ```text
|
|
93
|
+
const lines = doc.split('\n');
|
|
94
|
+
const start = lines.findIndex(l => l.trim().startsWith('```text'));
|
|
95
|
+
const end = lines.findIndex((l, i) => i > start && l.trim().startsWith('```'));
|
|
96
|
+
// github rendering pls fix xD
|
|
97
|
+
return start >= 0 && end > start ? '```text\n' + lines.slice(start + 1, end).join('\n').replaceAll('▶', '>') + '\n```' : doc;
|
|
98
|
+
})()}
|
|
99
|
+
|
|
100
|
+
We describe the different plugin types in more detail below.
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
${(0, doc_structure_1.section)('Project Discovery', 4)}
|
|
104
|
+
|
|
105
|
+
${(0, doc_structure_1.section)('File Loading', 4)}
|
|
106
|
+
|
|
107
|
+
${(0, doc_structure_1.section)('Dependency Identification', 4)}
|
|
108
|
+
|
|
109
|
+
${(0, doc_structure_1.section)('Loading Order', 4)}
|
|
110
|
+
|
|
111
|
+
${(0, doc_structure_1.section)('How to add a new plugin', 3)}
|
|
112
|
+
|
|
113
|
+
${(0, doc_structure_1.section)('How to add a new plugin type', 3)}
|
|
114
|
+
|
|
115
|
+
${(0, doc_structure_1.section)('Context Information', 2)}
|
|
116
|
+
|
|
117
|
+
${(0, doc_structure_1.section)('Files Context', 3)}
|
|
118
|
+
|
|
119
|
+
${(0, doc_structure_1.section)('Loading Order Context', 3)}
|
|
120
|
+
|
|
121
|
+
${(0, doc_structure_1.section)('Dependencies Context', 3)}
|
|
122
|
+
|
|
123
|
+
${(0, doc_structure_1.section)('Analyzer Internals', 2)}
|
|
124
|
+
|
|
125
|
+
`;
|
|
126
|
+
}
|
|
127
|
+
/** if we run this script, we want a Markdown representation of the capabilities */
|
|
128
|
+
if (require.main === module) {
|
|
129
|
+
(0, log_1.setMinLevelOfAllLogs)(6 /* LogLevel.Fatal */);
|
|
130
|
+
const shell = new shell_1.RShell();
|
|
131
|
+
void getText(shell).then(str => {
|
|
132
|
+
console.log(str);
|
|
133
|
+
}).finally(() => {
|
|
134
|
+
shell.close();
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=print-analyzer-wiki.js.map
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { FlowrAnalyzer } from '../project/flowr-analyzer';
|
|
2
|
+
export declare function inspectContextExample(analyzer: FlowrAnalyzer): void;
|
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.inspectContextExample = inspectContextExample;
|
|
6
7
|
const shell_1 = require("../r-bridge/shell");
|
|
7
8
|
const log_1 = require("../../test/functionality/_helper/log");
|
|
8
9
|
const log_2 = require("../util/log");
|
|
@@ -43,6 +44,36 @@ const pipeline_executor_1 = require("../core/pipeline-executor");
|
|
|
43
44
|
const pipeline_1 = require("../core/steps/pipeline/pipeline");
|
|
44
45
|
const static_slicer_1 = require("../slicing/static/static-slicer");
|
|
45
46
|
const config_1 = require("../config");
|
|
47
|
+
const flowr_analyzer_builder_1 = require("../project/flowr-analyzer-builder");
|
|
48
|
+
const flowr_analyzer_1 = require("../project/flowr-analyzer");
|
|
49
|
+
async function makeAnalyzerExample() {
|
|
50
|
+
const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder()
|
|
51
|
+
.addRequestFromInput('x <- 1; y <- x; print(y);')
|
|
52
|
+
.amendConfig(c => {
|
|
53
|
+
c.ignoreSourceCalls = true;
|
|
54
|
+
})
|
|
55
|
+
.setEngine('tree-sitter')
|
|
56
|
+
.build();
|
|
57
|
+
return analyzer;
|
|
58
|
+
}
|
|
59
|
+
async function extractStepsExample(analyzer) {
|
|
60
|
+
const normalizedAst = await analyzer.normalize();
|
|
61
|
+
const dataflow = await analyzer.dataflow();
|
|
62
|
+
const cfg = await analyzer.controlflow();
|
|
63
|
+
return { normalizedAst, dataflow, cfg };
|
|
64
|
+
}
|
|
65
|
+
async function sliceQueryExample(analyzer) {
|
|
66
|
+
const result = await analyzer.query([{
|
|
67
|
+
type: 'static-slice',
|
|
68
|
+
criteria: ['1@y']
|
|
69
|
+
}]);
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
function inspectContextExample(analyzer) {
|
|
73
|
+
const ctx = analyzer.inspectContext();
|
|
74
|
+
console.log('dplyr version', ctx.deps.getDependency('dplyr'));
|
|
75
|
+
console.log('loading order', ctx.files.loadingOrder.getLoadingOrder());
|
|
76
|
+
}
|
|
46
77
|
async function getText(shell) {
|
|
47
78
|
const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
|
|
48
79
|
const sampleCode = 'x <- 1; print(x)';
|
|
@@ -80,6 +111,7 @@ See the [Getting flowR to Talk](#getting-flowr-to-talk) section below for more i
|
|
|
80
111
|
`
|
|
81
112
|
})}
|
|
82
113
|
|
|
114
|
+
* [Creating and Using a flowR Analyzer Instance](#creating-and-using-a-flowr-analyzer-instance)
|
|
83
115
|
* [Pipelines and their Execution](#pipelines-and-their-execution)
|
|
84
116
|
* [How flowR Produces Dataflow Graphs](#how-flowr-produces-dataflow-graphs)
|
|
85
117
|
* [Overview](#overview)
|
|
@@ -89,10 +121,33 @@ See the [Getting flowR to Talk](#getting-flowr-to-talk) section below for more i
|
|
|
89
121
|
* [Beyond the Dataflow Graph](#beyond-the-dataflow-graph)
|
|
90
122
|
* [Static Backward Slicing](#static-backward-slicing)
|
|
91
123
|
* [Getting flowR to Talk](#getting-flowr-to-talk)
|
|
92
|
-
|
|
124
|
+
|
|
125
|
+
## Creating and Using a flowR Analyzer Instance
|
|
126
|
+
|
|
127
|
+
The ${(0, doc_types_1.shortLink)(flowr_analyzer_builder_1.FlowrAnalyzerBuilder.name, info)} class should be used as a starting point to create analyses in _flowR_.
|
|
128
|
+
It provides a fluent interface for the configuration and creation of a ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, info)} instance:
|
|
129
|
+
|
|
130
|
+
${(0, doc_types_1.printCodeOfElement)({ program, info, dropLinesStart: 1, dropLinesEnd: 2, hideDefinedAt: true }, makeAnalyzerExample.name)}
|
|
131
|
+
|
|
132
|
+
Have a look at the [Engine](${doc_files_1.FlowrWikiBaseRef}/Engines) wiki page to understand the different engines and parsers you can use.
|
|
133
|
+
|
|
134
|
+
The analyzer instance can then be used to access analysis results like the [normalized AST](${doc_files_1.FlowrWikiBaseRef}/Normalized-AST),
|
|
135
|
+
the [dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow-Graph), and the [controlflow graph](${doc_files_1.FlowrWikiBaseRef}/Control-Flow-Graph):
|
|
136
|
+
|
|
137
|
+
${(0, doc_types_1.printCodeOfElement)({ program, info, dropLinesStart: 1, dropLinesEnd: 2, hideDefinedAt: true }, extractStepsExample.name)}
|
|
138
|
+
|
|
139
|
+
The underlying ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, info)} instance will take care of caching, updates, and running the appropriate steps.
|
|
140
|
+
It also exposes the [query API](${doc_files_1.FlowrWikiBaseRef}/Query-API):
|
|
141
|
+
|
|
142
|
+
${(0, doc_types_1.printCodeOfElement)({ program, info, dropLinesStart: 1, dropLinesEnd: 2, hideDefinedAt: true }, sliceQueryExample.name)}
|
|
143
|
+
|
|
144
|
+
One of the additional advantages of using the ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, info)} is that it provides you with context information about the analyzed files:
|
|
145
|
+
|
|
146
|
+
${(0, doc_types_1.printCodeOfElement)({ program, info, dropLinesStart: 1, dropLinesEnd: 1, hideDefinedAt: true }, inspectContextExample.name)}
|
|
147
|
+
|
|
93
148
|
## Pipelines and their Execution
|
|
94
149
|
|
|
95
|
-
At the core of every analysis
|
|
150
|
+
At the core of every analysis done via a ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, info)} is the ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, info)} class which takes a sequence of analysis steps (in the form of a ${(0, doc_types_1.shortLink)('Pipeline', info)}) and executes it
|
|
96
151
|
on a given input. In general, these pipeline steps are analysis agnostic and may use arbitrary input and ordering. However, two important and predefined pipelines,
|
|
97
152
|
the ${(0, doc_types_1.shortLink)('DEFAULT_DATAFLOW_PIPELINE', info)} and the ${(0, doc_types_1.shortLink)('TREE_SITTER_DATAFLOW_PIPELINE', info)} adequately cover the most common analysis steps
|
|
98
153
|
(differentiated only by the [Engine](${doc_files_1.FlowrWikiBaseRef}/Engines) used).
|
|
@@ -115,10 +170,9 @@ const executor = new PipelineExecutor(TREE_SITTER_DATAFLOW_PIPELINE, {
|
|
|
115
170
|
const result = await executor.allRemainingSteps();
|
|
116
171
|
`)}
|
|
117
172
|
|
|
118
|
-
This is, roughly, what the ${(0, doc_types_1.shortLink)('
|
|
173
|
+
This is, roughly, what the ${(0, doc_types_1.shortLink)('dataflow', info)} function does when using the [\`tree-sitter\` engine](${doc_files_1.FlowrWikiBaseRef}/Engines).
|
|
119
174
|
We create a new ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, info)} with the ${(0, doc_types_1.shortLink)('TREE_SITTER_DATAFLOW_PIPELINE', info)} and then use ${(0, doc_types_1.shortLink)(`${pipeline_executor_1.PipelineExecutor.name}::${new pipeline_executor_1.PipelineExecutor(default_pipelines_1.TREE_SITTER_PARSE_PIPELINE, { parser: new tree_sitter_executor_1.TreeSitterExecutor(), request: (0, retriever_1.requestFromInput)('') }, config_1.defaultConfigOptions).allRemainingSteps.name}`, info)}
|
|
120
175
|
to cause the execution of all contained steps (in general, pipelines can be executed step-by-step, but this is usually not required if you just want the result).
|
|
121
|
-
${(0, doc_types_1.shortLink)(retriever_1.requestFromInput.name, info)} is merely a convenience function to create a request object from a code string.
|
|
122
176
|
|
|
123
177
|
In general, however, most flowR-internal functions which are tasked with generating dataflow prefer the use of ${(0, doc_types_1.shortLink)(default_pipelines_1.createDataflowPipeline.name, info)} as this function
|
|
124
178
|
automatically selects the correct pipeline based on the engine used.
|
|
@@ -11,7 +11,6 @@ const dataflowgraph_builder_1 = require("../dataflow/graph/dataflowgraph-builder
|
|
|
11
11
|
const assert_1 = require("../util/assert");
|
|
12
12
|
const doc_dfg_1 = require("./doc-util/doc-dfg");
|
|
13
13
|
const doc_files_1 = require("./doc-util/doc-files");
|
|
14
|
-
const pipeline_executor_1 = require("../core/pipeline-executor");
|
|
15
14
|
const retriever_1 = require("../r-bridge/retriever");
|
|
16
15
|
const json_1 = require("../util/json");
|
|
17
16
|
const doc_env_1 = require("./doc-util/doc-env");
|
|
@@ -39,6 +38,7 @@ const doc_issue_1 = require("./doc-util/doc-issue");
|
|
|
39
38
|
const unnamed_call_handling_1 = require("../dataflow/internal/process/functions/call/unnamed-call-handling");
|
|
40
39
|
const environment_builder_1 = require("../../test/functionality/_helper/dataflow/environment-builder");
|
|
41
40
|
const config_1 = require("../config");
|
|
41
|
+
const flowr_analyzer_builder_1 = require("../project/flowr-analyzer-builder");
|
|
42
42
|
async function subExplanation(shell, { description, code, expectedSubgraph }) {
|
|
43
43
|
expectedSubgraph = await (0, doc_dfg_1.verifyExpectedSubgraph)(shell, code, expectedSubgraph);
|
|
44
44
|
const marks = [];
|
|
@@ -742,12 +742,9 @@ ${(0, doc_structure_1.details)('Example: While-Loop Body', await (0, doc_dfg_1.p
|
|
|
742
742
|
return results.join('\n');
|
|
743
743
|
}
|
|
744
744
|
async function dummyDataflow() {
|
|
745
|
-
const
|
|
746
|
-
const result = await
|
|
747
|
-
|
|
748
|
-
request: (0, retriever_1.requestFromInput)('x <- 1\nx + 1')
|
|
749
|
-
}, config_1.defaultConfigOptions).allRemainingSteps();
|
|
750
|
-
shell.close();
|
|
745
|
+
const analyzer = await new flowr_analyzer_builder_1.FlowrAnalyzerBuilder((0, retriever_1.requestFromInput)('x <- 1\nx + 1')).build();
|
|
746
|
+
const result = await analyzer.dataflow();
|
|
747
|
+
analyzer.close();
|
|
751
748
|
return result;
|
|
752
749
|
}
|
|
753
750
|
async function getText(shell) {
|
|
@@ -879,16 +876,12 @@ ${(0, doc_structure_1.details)('Example: Nested Conditionals', await (0, doc_dfg
|
|
|
879
876
|
|
|
880
877
|
${(0, doc_structure_1.section)('Dataflow Information', 2, 'dataflow-information')}
|
|
881
878
|
|
|
882
|
-
Using _flowR's_ code interface (see the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface) wiki page for more), you can generate the dataflow information
|
|
883
|
-
for a given piece of R code (in this case \`x <- 1; x + 1\`) as follows
|
|
879
|
+
Using _flowR's_ code interface (see the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface#creating-flowr-analyses) wiki page for more), you can generate the dataflow information
|
|
880
|
+
for a given piece of R code (in this case \`x <- 1; x + 1\`) as follows:
|
|
884
881
|
|
|
885
882
|
${(0, doc_code_1.codeBlock)('ts', `
|
|
886
|
-
const
|
|
887
|
-
const result = await
|
|
888
|
-
shell,
|
|
889
|
-
request: ${retriever_1.requestFromInput.name}('x <- 1; x + 1')
|
|
890
|
-
}).allRemainingSteps();
|
|
891
|
-
shell.close();
|
|
883
|
+
const analyzer = await new FlowrAnalyzerBuilder(requestFromInput('x <- 1\nx + 1')).build();
|
|
884
|
+
const result = await analyzer.dataflow();
|
|
892
885
|
`)}
|
|
893
886
|
|
|
894
887
|
<details>
|
|
@@ -906,7 +899,7 @@ Now, you can find the dataflow _information_ with \`result.dataflow\`. More spec
|
|
|
906
899
|
|
|
907
900
|
${await (async () => {
|
|
908
901
|
const result = await dummyDataflow();
|
|
909
|
-
const dfGraphString = (0, doc_dfg_1.printDfGraph)(result.
|
|
902
|
+
const dfGraphString = (0, doc_dfg_1.printDfGraph)(result.graph);
|
|
910
903
|
return `
|
|
911
904
|
${dfGraphString}
|
|
912
905
|
|
|
@@ -917,7 +910,7 @@ However, the dataflow information contains more, quite a lot of information in f
|
|
|
917
910
|
<summary style="color:gray">Dataflow Information as Json</summary>
|
|
918
911
|
|
|
919
912
|
_As the information is pretty long, we inhibit pretty printing and syntax highlighting:_
|
|
920
|
-
${(0, doc_code_1.codeBlock)('text', JSON.stringify(result
|
|
913
|
+
${(0, doc_code_1.codeBlock)('text', JSON.stringify(result, json_1.jsonReplacer))}
|
|
921
914
|
|
|
922
915
|
</details>
|
|
923
916
|
|
|
@@ -925,16 +918,16 @@ You may be interested in its implementation:
|
|
|
925
918
|
|
|
926
919
|
${(0, doc_types_1.printHierarchy)({ program: vertexType.program, info: vertexType.info, root: 'DataflowInformation' })}
|
|
927
920
|
|
|
928
|
-
Let's start by looking at the properties of the dataflow information object: ${Object.keys(result
|
|
921
|
+
Let's start by looking at the properties of the dataflow information object: ${Object.keys(result).map(k => `\`${k}\``).join(', ')}.
|
|
929
922
|
|
|
930
923
|
${(() => {
|
|
931
924
|
/* this includes the meta field for timing */
|
|
932
|
-
(0, assert_1.guard)(Object.keys(result
|
|
925
|
+
(0, assert_1.guard)(Object.keys(result).length === 8, () => 'Update Dataflow Documentation!');
|
|
933
926
|
return '';
|
|
934
927
|
})()}
|
|
935
928
|
|
|
936
929
|
There are three sets of references.
|
|
937
|
-
**in** (ids: ${JSON.stringify(new Set(result.
|
|
930
|
+
**in** (ids: ${JSON.stringify(new Set(result.in.map(n => n.nodeId)), json_1.jsonReplacer)}) and **out** (ids: ${JSON.stringify(new Set(result.out.map(n => n.nodeId)), json_1.jsonReplacer)}) contain the
|
|
938
931
|
ingoing and outgoing references of the subgraph at hand (in this case, the whole code, as we are at the end of the dataflow analysis).
|
|
939
932
|
Besides the Ids, they also contain important meta-information (e.g., what is to be read).
|
|
940
933
|
The third set, **unknownReferences**, contains all references that are not yet identified as read or written
|
|
@@ -944,12 +937,12 @@ The **environment** property contains the active environment information of the
|
|
|
944
937
|
In other words, this is a linked list of tables (scopes), mapping identifiers to their respective definitions.
|
|
945
938
|
A summarized version of the produced environment looks like this:
|
|
946
939
|
|
|
947
|
-
${(0, doc_env_1.printEnvironmentToMarkdown)(result.
|
|
940
|
+
${(0, doc_env_1.printEnvironmentToMarkdown)(result.environment.current)}
|
|
948
941
|
|
|
949
942
|
This shows us that the local environment contains a single definition for \`x\` (with id 0) and that the parent environment is the built-in environment.
|
|
950
943
|
Additionally, we get the information that the node with the id 2 was responsible for the definition of \`x\`.
|
|
951
944
|
|
|
952
|
-
Last but not least, the information contains the single **entry point** (${JSON.stringify(result.
|
|
945
|
+
Last but not least, the information contains the single **entry point** (${JSON.stringify(result.entryPoint)}) and a set of **exit points** (${JSON.stringify(result.exitPoints.map(e => e.nodeId))}).
|
|
953
946
|
Besides marking potential exits, the exit points also provide information about why the exit occurs and which control dependencies affect the exit.
|
|
954
947
|
|
|
955
948
|
### Unknown Side Effects
|
|
@@ -25,6 +25,7 @@ const doc_structure_1 = require("./doc-util/doc-structure");
|
|
|
25
25
|
const doc_types_1 = require("./doc-util/doc-types");
|
|
26
26
|
const path_1 = __importDefault(require("path"));
|
|
27
27
|
const tree_sitter_executor_1 = require("../r-bridge/lang-4.x/tree-sitter/tree-sitter-executor");
|
|
28
|
+
const flowr_analyzer_1 = require("../project/flowr-analyzer");
|
|
28
29
|
async function explainServer(shell) {
|
|
29
30
|
(0, doc_data_server_messages_1.documentAllServerMessages)();
|
|
30
31
|
return `
|
|
@@ -295,13 +296,29 @@ ${(0, doc_types_1.shortLink)(shell_1.RShell.name + '::' + shell.sendCommandWithO
|
|
|
295
296
|
|
|
296
297
|
Besides that, the command ${(0, doc_types_1.shortLink)(shell_1.RShell.name + '::' + shell.tryToInjectHomeLibPath.name, types.info)} may be of interest, as it enables all libraries available on the host system.
|
|
297
298
|
|
|
299
|
+
### Creating _flowR_ analyses
|
|
300
|
+
|
|
301
|
+
Nowadays, instances of ${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, types.info)} should be used as central frontend to get analysis results from _flowR_.
|
|
302
|
+
For example, a program slice can be created like this:
|
|
303
|
+
|
|
304
|
+
${(0, doc_code_1.codeBlock)('ts', `
|
|
305
|
+
const analyzer = await new FlowrAnalyzerBuilder(requestFromInput('x <- 1\\ny <- x\\nx')).build();
|
|
306
|
+
const result = await analyzer.query([
|
|
307
|
+
{
|
|
308
|
+
type: 'static-slice',
|
|
309
|
+
criteria: ['3@x']
|
|
310
|
+
}
|
|
311
|
+
]);
|
|
312
|
+
//console.log(result['static-slice']);
|
|
313
|
+
`)}
|
|
314
|
+
|
|
298
315
|
### The Pipeline Executor
|
|
299
316
|
|
|
300
317
|
Once, in the beginning, _flowR_ was meant to produce a dataflow graph merely to provide *program slices*.
|
|
301
318
|
However, with continuous updates, the [dataflow graph](${doc_files_1.FlowrWikiBaseRef}/Dataflow%20Graph) repeatedly proves to be the more interesting part.
|
|
302
319
|
With this, we restructured _flowR_'s originally *hardcoded* pipeline to be far more flexible.
|
|
303
320
|
Now, it can be theoretically extended or replaced with arbitrary steps, optional steps, and what we call 'decorations' of these steps.
|
|
304
|
-
In short,
|
|
321
|
+
In short, a slicing pipeline using the ${(0, doc_types_1.shortLink)(pipeline_executor_1.PipelineExecutor.name, types.info)} looks like this:
|
|
305
322
|
|
|
306
323
|
${(0, doc_code_1.codeBlock)('ts', `
|
|
307
324
|
const slicer = new ${pipeline_executor_1.PipelineExecutor.name}(DEFAULT_SLICING_PIPELINE, {
|
|
@@ -87,10 +87,14 @@ See [here](${(0, doc_types_1.getTypePathLink)({ filePath: report.source.fileName
|
|
|
87
87
|
}
|
|
88
88
|
function registerRules(rVersion, shell, tagTypes, format = 'short') {
|
|
89
89
|
const ruleExplanations = new Map();
|
|
90
|
-
rule(shell, 'deprecated-functions', '
|
|
90
|
+
rule(shell, 'deprecated-functions', 'FunctionsToDetectConfig', 'DEPRECATED_FUNCTIONS', 'lint-deprecated-functions', `
|
|
91
91
|
first <- data.frame(x = c(1, 2, 3), y = c(1, 2, 3))
|
|
92
92
|
second <- data.frame(x = c(1, 3, 2), y = c(1, 3, 2))
|
|
93
93
|
dplyr::all_equal(first, second)
|
|
94
|
+
`, tagTypes);
|
|
95
|
+
rule(shell, 'network-functions', 'NetworkFunctionsConfig', 'NETWORK_FUNCTIONS', 'lint-network-functions', `
|
|
96
|
+
read.csv("https://example.com/data.csv")
|
|
97
|
+
download.file("https://foo.bar")
|
|
94
98
|
`, tagTypes);
|
|
95
99
|
rule(shell, 'file-path-validity', 'FilePathValidityConfig', 'FILE_PATH_VALIDITY', 'lint-file-path-validity', `
|
|
96
100
|
my_data <- read.csv("C:/Users/me/Documents/My R Scripts/Reproducible.csv")
|