@eagleoutice/flowr 2.5.0 → 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 +57 -42
- 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 +1 -1
- 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-normalized-ast-wiki.js +6 -8
- 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 +2 -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/retriever.d.ts +6 -5
- package/r-bridge/retriever.js +9 -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.d.ts +4 -2
- package/util/formats/adapter.js +11 -4
- package/util/version.js +1 -1
|
@@ -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")
|
|
@@ -20,6 +20,7 @@ const visitor_1 = require("../r-bridge/lang-4.x/ast/model/processing/visitor");
|
|
|
20
20
|
const collect_1 = require("../r-bridge/lang-4.x/ast/model/collect");
|
|
21
21
|
const normalized_ast_fold_1 = require("../abstract-interpretation/normalized-ast-fold");
|
|
22
22
|
const default_pipelines_1 = require("../core/steps/pipeline/default-pipelines");
|
|
23
|
+
const flowr_analyzer_1 = require("../project/flowr-analyzer");
|
|
23
24
|
async function getText(shell) {
|
|
24
25
|
const rversion = (await shell.usedRVersion())?.format() ?? 'unknown';
|
|
25
26
|
const now = performance.now();
|
|
@@ -91,17 +92,14 @@ The following segments intend to give you an overview of how to work with the no
|
|
|
91
92
|
|
|
92
93
|
## How to Get a Normalized AST
|
|
93
94
|
|
|
94
|
-
As explained alongside the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface#
|
|
95
|
-
${(0, doc_types_1.shortLink)(
|
|
96
|
-
a pipeline like the ${(0, doc_types_1.shortLink)('DEFAULT_NORMALIZE_PIPELINE', types.info)} suffices:
|
|
95
|
+
As explained alongside the [Interface](${doc_files_1.FlowrWikiBaseRef}/Interface#creating-flowr-analyses) wiki page, you can use an instance of
|
|
96
|
+
${(0, doc_types_1.shortLink)(flowr_analyzer_1.FlowrAnalyzer.name, types.info)} to get the ${(0, doc_types_1.shortLink)('NormalizedAst', types.info)}:
|
|
97
97
|
|
|
98
98
|
${(0, doc_code_1.codeBlock)('ts', `
|
|
99
99
|
async function getAst(code: string): Promise<RNode> {
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}).allRemainingSteps();
|
|
104
|
-
return result.normalize.ast;
|
|
100
|
+
const analyzer = await new FlowrAnalyzerBuilder(${retriever_1.requestFromInput.name}(code.trim())).build();
|
|
101
|
+
const result = analyzer.normalizedAst();
|
|
102
|
+
return result.ast;
|
|
105
103
|
}`)}
|
|
106
104
|
|
|
107
105
|
From the REPL, you can use the ${(0, doc_cli_option_1.getReplCommand)('normalize')} command.
|
package/engines.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FlowrConfigOptions, KnownEngines } from './config';
|
|
2
|
+
/**
|
|
3
|
+
* Retrieve all requested engine instance.
|
|
4
|
+
* Please make sure that if this includes the R engine, that you properly shut it down again!
|
|
5
|
+
*/
|
|
6
|
+
export declare function retrieveEngineInstances(config: FlowrConfigOptions, defaultOnly?: boolean): Promise<{
|
|
7
|
+
engines: KnownEngines;
|
|
8
|
+
default: keyof KnownEngines;
|
|
9
|
+
}>;
|
package/engines.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.retrieveEngineInstances = retrieveEngineInstances;
|
|
4
|
+
const config_1 = require("./config");
|
|
5
|
+
const shell_1 = require("./r-bridge/shell");
|
|
6
|
+
const ansi_1 = require("./util/text/ansi");
|
|
7
|
+
const tree_sitter_executor_1 = require("./r-bridge/lang-4.x/tree-sitter/tree-sitter-executor");
|
|
8
|
+
const log_1 = require("./util/log");
|
|
9
|
+
/**
|
|
10
|
+
* Retrieve all requested engine instance.
|
|
11
|
+
* Please make sure that if this includes the R engine, that you properly shut it down again!
|
|
12
|
+
*/
|
|
13
|
+
async function retrieveEngineInstances(config, defaultOnly = false) {
|
|
14
|
+
const engines = {};
|
|
15
|
+
if ((0, config_1.getEngineConfig)(config, 'r-shell') && (!defaultOnly || config.defaultEngine === 'r-shell')) {
|
|
16
|
+
// we keep an active shell session to allow other parse investigations :)
|
|
17
|
+
engines['r-shell'] = new shell_1.RShell((0, config_1.getEngineConfig)(config, 'r-shell'), {
|
|
18
|
+
revive: 2 /* RShellReviveOptions.Always */,
|
|
19
|
+
onRevive: (code, signal) => {
|
|
20
|
+
const signalText = signal == null ? '' : ` and signal ${signal}`;
|
|
21
|
+
console.log(ansi_1.formatter.format(`R process exited with code ${code}${signalText}. Restarting...`, { color: 5 /* Colors.Magenta */, effect: ansi_1.ColorEffect.Foreground }));
|
|
22
|
+
console.log((0, ansi_1.italic)(`If you want to exit, press either Ctrl+C twice, or enter ${(0, ansi_1.bold)(':quit')}`));
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if ((0, config_1.getEngineConfig)(config, 'tree-sitter') && (!defaultOnly || config.defaultEngine === 'tree-sitter')) {
|
|
27
|
+
await tree_sitter_executor_1.TreeSitterExecutor.initTreeSitter((0, config_1.getEngineConfig)(config, 'tree-sitter'));
|
|
28
|
+
engines['tree-sitter'] = new tree_sitter_executor_1.TreeSitterExecutor();
|
|
29
|
+
}
|
|
30
|
+
let defaultEngine = config.defaultEngine;
|
|
31
|
+
if (!defaultEngine || !engines[defaultEngine]) {
|
|
32
|
+
// if a default engine isn't specified, we just take the first one we have
|
|
33
|
+
defaultEngine = Object.keys(engines)[0];
|
|
34
|
+
}
|
|
35
|
+
log_1.log.info(`Using engines ${Object.keys(engines).join(', ')} with default ${defaultEngine}`);
|
|
36
|
+
return { engines, default: defaultEngine };
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=engines.js.map
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import type { LintingRuleConfig, LintingRuleNames } from './linter-rules';
|
|
2
|
-
import type { NormalizedAst } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
3
|
-
import type { DataflowInformation } from '../dataflow/info';
|
|
4
2
|
import type { LintingResults } from './linter-format';
|
|
5
3
|
import type { DeepPartial } from 'ts-essentials';
|
|
6
|
-
import type {
|
|
7
|
-
export declare function executeLintingRule<Name extends LintingRuleNames>(ruleName: Name, input:
|
|
8
|
-
normalize: NormalizedAst;
|
|
9
|
-
dataflow: DataflowInformation;
|
|
10
|
-
config: FlowrConfigOptions;
|
|
11
|
-
}, lintingRuleConfig?: DeepPartial<LintingRuleConfig<Name>>): LintingResults<Name>;
|
|
4
|
+
import type { FlowrAnalysisProvider } from '../project/flowr-analyzer';
|
|
5
|
+
export declare function executeLintingRule<Name extends LintingRuleNames>(ruleName: Name, input: FlowrAnalysisProvider, lintingRuleConfig?: DeepPartial<LintingRuleConfig<Name>>): Promise<LintingResults<Name>>;
|
|
@@ -4,16 +4,21 @@ exports.executeLintingRule = executeLintingRule;
|
|
|
4
4
|
const linter_rules_1 = require("./linter-rules");
|
|
5
5
|
const flowr_search_executor_1 = require("../search/flowr-search-executor");
|
|
6
6
|
const objects_1 = require("../util/objects");
|
|
7
|
-
function executeLintingRule(ruleName, input, lintingRuleConfig) {
|
|
7
|
+
async function executeLintingRule(ruleName, input, lintingRuleConfig) {
|
|
8
8
|
try {
|
|
9
9
|
const rule = linter_rules_1.LintingRules[ruleName];
|
|
10
10
|
const fullConfig = (0, objects_1.deepMergeObject)(rule.info.defaultConfig, lintingRuleConfig);
|
|
11
|
-
const ruleSearch = rule.createSearch(fullConfig
|
|
11
|
+
const ruleSearch = rule.createSearch(fullConfig);
|
|
12
12
|
const searchStart = Date.now();
|
|
13
|
-
const searchResult = (0, flowr_search_executor_1.runSearch)(ruleSearch, input);
|
|
13
|
+
const searchResult = await (0, flowr_search_executor_1.runSearch)(ruleSearch, input);
|
|
14
14
|
const searchTime = Date.now() - searchStart;
|
|
15
15
|
const processStart = Date.now();
|
|
16
|
-
const result = rule.processSearchResult(searchResult, fullConfig,
|
|
16
|
+
const result = await rule.processSearchResult(searchResult, fullConfig, {
|
|
17
|
+
normalize: await input.normalize(),
|
|
18
|
+
dataflow: await input.dataflow(),
|
|
19
|
+
cfg: await input.controlflow(),
|
|
20
|
+
config: input.flowrConfig,
|
|
21
|
+
});
|
|
17
22
|
const processTime = Date.now() - processStart;
|
|
18
23
|
return {
|
|
19
24
|
...result,
|
|
@@ -5,11 +5,12 @@ import type { GeneratorNames } from '../search/search-executor/search-generators
|
|
|
5
5
|
import type { TransformerNames } from '../search/search-executor/search-transformer';
|
|
6
6
|
import type { NormalizedAst, ParentInformation } from '../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
7
7
|
import type { LintingRuleConfig, LintingRuleMetadata, LintingRuleNames, LintingRuleResult } from './linter-rules';
|
|
8
|
-
import type {
|
|
9
|
-
import type { FlowrConfigOptions } from '../config';
|
|
10
|
-
import type { DeepPartial, DeepReadonly } from 'ts-essentials';
|
|
8
|
+
import type { AsyncOrSync, DeepPartial, DeepReadonly } from 'ts-essentials';
|
|
11
9
|
import type { LintingRuleTag } from './linter-tags';
|
|
12
10
|
import type { SourceRange } from '../util/range';
|
|
11
|
+
import type { DataflowInformation } from '../dataflow/info';
|
|
12
|
+
import type { FlowrConfigOptions } from '../config';
|
|
13
|
+
import type { ControlFlowInformation } from '../control-flow/control-flow-graph';
|
|
13
14
|
export interface LinterRuleInformation<Config extends MergeableRecord = never> {
|
|
14
15
|
/** Human-Readable name of the linting rule. */
|
|
15
16
|
readonly name: string;
|
|
@@ -41,10 +42,7 @@ export interface LintingRule<Result extends LintingResult, Metadata extends Merg
|
|
|
41
42
|
* Creates a flowR search that will then be executed and whose results will be passed to {@link processSearchResult}.
|
|
42
43
|
* In the future, additional optimizations and transformations may be applied to the search between this function and {@link processSearchResult}.
|
|
43
44
|
*/
|
|
44
|
-
readonly createSearch: (config: Config,
|
|
45
|
-
normalize: NormalizedAst;
|
|
46
|
-
dataflow: DataflowInformation;
|
|
47
|
-
}) => FlowrSearchLike<Info, GeneratorNames, TransformerNames[], FlowrSearchElements<Info, Elements>>;
|
|
45
|
+
readonly createSearch: (config: Config) => FlowrSearchLike<Info, GeneratorNames, TransformerNames[], FlowrSearchElements<Info, Elements>>;
|
|
48
46
|
/**
|
|
49
47
|
* Processes the search results of the search created through {@link createSearch}.
|
|
50
48
|
* This function is expected to return the linting results from this rule for the given search, ie usually the given script file.
|
|
@@ -52,11 +50,12 @@ export interface LintingRule<Result extends LintingResult, Metadata extends Merg
|
|
|
52
50
|
readonly processSearchResult: (elements: FlowrSearchElements<Info, Elements>, config: Config, data: {
|
|
53
51
|
normalize: NormalizedAst;
|
|
54
52
|
dataflow: DataflowInformation;
|
|
53
|
+
cfg: ControlFlowInformation;
|
|
55
54
|
config: FlowrConfigOptions;
|
|
56
|
-
}) => {
|
|
55
|
+
}) => AsyncOrSync<{
|
|
57
56
|
results: Result[];
|
|
58
57
|
'.meta': Metadata;
|
|
59
|
-
}
|
|
58
|
+
}>;
|
|
60
59
|
/**
|
|
61
60
|
* A set of functions used to pretty-print the given linting result.
|
|
62
61
|
* By default, the {@link LintingResult#certainty} and whether any {@link LintingResult#quickFix} values are available is automatically printed alongside this information.
|