@eagleoutice/flowr 2.2.2 → 2.2.4
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 +412 -39
- package/benchmark/slicer.js +0 -1
- package/benchmark/summarizer/first-phase/process.js +18 -8
- package/benchmark/summarizer/summarizer.d.ts +1 -1
- package/benchmark/summarizer/summarizer.js +1 -1
- package/cli/benchmark-app.js +1 -1
- package/cli/common/script.js +0 -1
- package/cli/repl/commands/repl-cfg.js +38 -8
- package/cli/repl/commands/repl-commands.js +1 -1
- package/cli/repl/commands/repl-dataflow.js +45 -12
- package/cli/repl/commands/repl-normalize.js +38 -8
- package/cli/repl/commands/repl-parse.js +43 -2
- package/cli/repl/commands/repl-query.js +2 -2
- package/cli/repl/core.js +17 -8
- package/cli/repl/print-version.d.ts +1 -0
- package/cli/repl/print-version.js +8 -2
- package/cli/repl/server/connection.js +27 -15
- package/cli/repl/server/messages/all-messages.js +17 -7
- package/cli/repl/server/messages/message-repl.js +17 -7
- package/cli/repl/server/messages/message-slice.js +17 -7
- package/cli/script-core/statistics-helper-core.js +0 -1
- package/core/pipeline-executor.d.ts +6 -0
- package/core/pipeline-executor.js +8 -0
- package/core/print/dataflow-printer.js +3 -0
- package/core/print/normalize-printer.js +0 -1
- package/core/steps/all/core/01-parse-tree-sitter.d.ts +7 -0
- package/core/steps/pipeline/default-pipelines.d.ts +57 -47
- package/core/steps/pipeline/default-pipelines.js +23 -2
- package/core/steps/pipeline/pipeline.d.ts +1 -1
- package/core/steps/pipeline/pipeline.js +1 -1
- package/core/steps/pipeline-step.d.ts +1 -3
- package/dataflow/environments/resolve-by-name.d.ts +5 -2
- package/dataflow/environments/resolve-by-name.js +6 -4
- package/dataflow/extractor.d.ts +10 -0
- package/dataflow/extractor.js +10 -0
- package/dataflow/graph/resolve-graph.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +20 -4
- package/documentation/data/server/doc-data-server-messages.js +1 -2
- package/documentation/doc-util/doc-auto-gen.d.ts +1 -0
- package/documentation/doc-util/doc-auto-gen.js +5 -1
- package/documentation/doc-util/doc-benchmarks.d.ts +23 -0
- package/documentation/doc-util/doc-benchmarks.js +76 -0
- package/documentation/doc-util/doc-code.d.ts +1 -0
- package/documentation/doc-util/doc-code.js +4 -0
- package/documentation/doc-util/doc-dfg.d.ts +5 -3
- package/documentation/doc-util/doc-dfg.js +10 -8
- package/documentation/doc-util/doc-files.d.ts +2 -1
- package/documentation/doc-util/doc-files.js +3 -2
- package/documentation/doc-util/doc-normalized-ast.d.ts +2 -1
- package/documentation/doc-util/doc-normalized-ast.js +4 -5
- package/documentation/doc-util/doc-repl.d.ts +6 -2
- package/documentation/doc-util/doc-repl.js +10 -6
- package/documentation/doc-util/doc-server-message.js +1 -1
- package/documentation/doc-util/doc-structure.d.ts +1 -1
- package/documentation/doc-util/doc-structure.js +2 -2
- package/documentation/doc-util/doc-types.d.ts +8 -5
- package/documentation/doc-util/doc-types.js +31 -18
- package/documentation/index.d.ts +9 -0
- package/documentation/index.js +26 -0
- package/documentation/print-capabilities-markdown.js +105 -19
- package/documentation/print-core-wiki.d.ts +1 -0
- package/documentation/print-core-wiki.js +413 -0
- package/documentation/print-dataflow-graph-wiki.js +27 -27
- package/documentation/print-interface-wiki.js +22 -16
- package/documentation/print-linting-and-testing-wiki.js +29 -9
- package/documentation/print-normalized-ast-wiki.js +22 -17
- package/documentation/print-query-wiki.js +7 -7
- package/documentation/print-readme.d.ts +1 -0
- package/documentation/print-readme.js +160 -0
- package/documentation/print-search-wiki.js +2 -1
- package/package.json +30 -41
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +77 -45
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +3 -0
- package/queries/catalog/dependencies-query/dependencies-query-format.js +3 -2
- package/queries/catalog/happens-before-query/happens-before-query-format.js +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-format.js +1 -1
- package/queries/catalog/search-query/search-query-format.js +1 -1
- package/r-bridge/data/data.d.ts +48 -7
- package/r-bridge/data/data.js +62 -8
- package/r-bridge/data/types.d.ts +7 -1
- package/r-bridge/lang-4.x/ast/model/model.d.ts +2 -3
- package/r-bridge/lang-4.x/ast/model/processing/decorate.d.ts +2 -0
- package/r-bridge/lang-4.x/ast/model/processing/node-id.js +2 -5
- package/r-bridge/lang-4.x/ast/parser/json/format.d.ts +6 -0
- package/r-bridge/lang-4.x/ast/parser/json/format.js +6 -0
- package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +13 -2
- package/r-bridge/lang-4.x/ast/parser/json/parser.js +19 -3
- package/r-bridge/lang-4.x/ast/parser/main/internal/structure/normalize-root.d.ts +3 -0
- package/r-bridge/lang-4.x/ast/parser/main/internal/structure/normalize-root.js +3 -0
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +1 -0
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +3 -0
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +6 -1
- package/r-bridge/parser.d.ts +10 -0
- package/r-bridge/parser.js +26 -2
- package/r-bridge/shell.js +18 -8
- package/search/flowr-search-builder.d.ts +1 -2
- package/search/flowr-search-builder.js +1 -3
- package/statistics/features/supported/comments/comments.js +17 -7
- package/statistics/features/supported/used-functions/post-process.js +0 -1
- package/statistics/features/supported/used-packages/used-packages.js +17 -7
- package/statistics/features/supported/values/values.js +17 -7
- package/statistics/summarizer/summarizer.js +1 -2
- package/util/files.js +17 -7
- package/util/json.js +0 -2
- package/util/mermaid/dfg.d.ts +3 -0
- package/util/mermaid/dfg.js +24 -8
- package/util/numbers.d.ts +1 -0
- package/util/numbers.js +5 -0
- package/util/parallel.js +17 -7
- package/util/quads.js +3 -3
- package/util/strings.d.ts +9 -0
- package/util/strings.js +14 -0
- package/util/version.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eagleoutice/flowr",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.4",
|
|
4
4
|
"description": "Static Dataflow Analyzer and Program Slicer for the R Programming Language",
|
|
5
5
|
"types": "dist/src/index.d.ts",
|
|
6
6
|
"repository": {
|
|
@@ -28,10 +28,12 @@
|
|
|
28
28
|
"wiki:df-graph": "ts-node src/documentation/print-dataflow-graph-wiki.ts",
|
|
29
29
|
"wiki:normalized-ast": "ts-node src/documentation/print-normalized-ast-wiki.ts",
|
|
30
30
|
"wiki:query-api": "ts-node src/documentation/print-query-wiki.ts",
|
|
31
|
+
"wiki:core": "ts-node src/documentation/print-core-wiki.ts",
|
|
31
32
|
"wiki:engines": "ts-node src/documentation/print-engines-wiki.ts",
|
|
32
33
|
"wiki:search-api": "ts-node src/documentation/print-search-wiki.ts",
|
|
33
34
|
"wiki:linting-and-testing": "ts-node src/documentation/print-linting-and-testing-wiki.ts",
|
|
34
35
|
"wiki:interface": "ts-node src/documentation/print-interface-wiki.ts",
|
|
36
|
+
"gen:readme": "ts-node src/documentation/print-readme.ts",
|
|
35
37
|
"build": "tsc --project .",
|
|
36
38
|
"build-dev": "npm run build && npm run build:copy-wasm",
|
|
37
39
|
"build:bundle-flowr": "npm run build && esbuild --bundle dist/src/cli/flowr.js --platform=node --bundle --minify --external:clipboardy --target=node22 --outfile=dist/src/cli/flowr.min.js && npm run build:copy-wasm-min",
|
|
@@ -47,7 +49,7 @@
|
|
|
47
49
|
"performance-test": "func() { cd test/performance/ && bash run-all-suites.sh $1 $2 $3 $4; cd ../../; }; func",
|
|
48
50
|
"test-full": "npm run test:coverage -- --no-watch -- --make-summary --test-installation",
|
|
49
51
|
"detect-circular-deps": "npx madge --extensions ts,tsx --circular src/",
|
|
50
|
-
"checkup": "npm run flowr -- --execute \":version\" && npm run lint && npm run test-full -- --allowOnly=false && npm run test:system -- --no-watch && docker build -t test-flowr -f scripts/Dockerfile . && npm run doc && npm-run-all wiki:*"
|
|
52
|
+
"checkup": "npm run flowr -- --execute \":version\" && npm run lint && npm run test-full -- --allowOnly=false && npm run test:system -- --no-watch && docker build -t test-flowr -f scripts/Dockerfile . && npm run doc && npm run gen:readme && npm-run-all wiki:*"
|
|
51
53
|
},
|
|
52
54
|
"keywords": [
|
|
53
55
|
"static code analysis",
|
|
@@ -59,21 +61,6 @@
|
|
|
59
61
|
],
|
|
60
62
|
"author": "Florian Sihler",
|
|
61
63
|
"license": "ISC",
|
|
62
|
-
"eslintConfig": {
|
|
63
|
-
"settings": {
|
|
64
|
-
"import/resolver": {
|
|
65
|
-
"node": {
|
|
66
|
-
"extensions": [
|
|
67
|
-
".ts"
|
|
68
|
-
]
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
"extends": [
|
|
73
|
-
"@eagleoutice/eslint-config-flowr"
|
|
74
|
-
],
|
|
75
|
-
"rules": {}
|
|
76
|
-
},
|
|
77
64
|
"typedocOptions": {
|
|
78
65
|
"includeVersion": true,
|
|
79
66
|
"plugin": [
|
|
@@ -182,48 +169,50 @@
|
|
|
182
169
|
}
|
|
183
170
|
},
|
|
184
171
|
"devDependencies": {
|
|
185
|
-
"@commitlint/cli": "^19.
|
|
186
|
-
"@commitlint/config-angular": "^19.
|
|
187
|
-
"@eagleoutice/eslint-config-flowr": "^1.0.
|
|
188
|
-
"@
|
|
172
|
+
"@commitlint/cli": "^19.7.1",
|
|
173
|
+
"@commitlint/config-angular": "^19.7.1",
|
|
174
|
+
"@eagleoutice/eslint-config-flowr": "^1.0.17",
|
|
175
|
+
"@eslint/eslintrc": "^3.2.0",
|
|
176
|
+
"@eslint/js": "^9.20.0",
|
|
177
|
+
"@j-ulrich/release-it-regex-bumper": "^5.2.0",
|
|
189
178
|
"@types/command-line-args": "^5.2.3",
|
|
190
179
|
"@types/command-line-usage": "^5.0.4",
|
|
191
180
|
"@types/n-readlines": "^1.0.6",
|
|
192
|
-
"@types/n3": "^1.
|
|
181
|
+
"@types/n3": "^1.21.1",
|
|
193
182
|
"@types/object-hash": "^3.0.6",
|
|
194
|
-
"@types/semver": "^7.5.
|
|
183
|
+
"@types/semver": "^7.5.8",
|
|
195
184
|
"@types/tmp": "^0.2.6",
|
|
196
|
-
"@types/ws": "^8.5.
|
|
197
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
198
|
-
"@vitest/coverage-v8": "^
|
|
199
|
-
"esbuild": "^0.
|
|
200
|
-
"eslint": "^
|
|
185
|
+
"@types/ws": "^8.5.14",
|
|
186
|
+
"@typescript-eslint/eslint-plugin": "^8.24.0",
|
|
187
|
+
"@vitest/coverage-v8": "^3.0.5",
|
|
188
|
+
"esbuild": "^0.25.0",
|
|
189
|
+
"eslint": "^9.20.1",
|
|
201
190
|
"license-checker": "^25.0.1",
|
|
202
191
|
"npm-run-all": "^4.1.5",
|
|
203
|
-
"release-it": "^
|
|
192
|
+
"release-it": "^18.1.2",
|
|
204
193
|
"ts-node": "^10.9.2",
|
|
205
|
-
"typedoc": "^0.
|
|
206
|
-
"typedoc-plugin-missing-exports": "^3.
|
|
207
|
-
"typedoc-theme-hierarchy": "^5.0.
|
|
208
|
-
"typedoc-umlclass": "^0.10.
|
|
209
|
-
"typescript": "^5.
|
|
210
|
-
"vitest": "^
|
|
194
|
+
"typedoc": "^0.27.7",
|
|
195
|
+
"typedoc-plugin-missing-exports": "^3.1.0",
|
|
196
|
+
"typedoc-theme-hierarchy": "^5.0.4",
|
|
197
|
+
"typedoc-umlclass": "^0.10.1",
|
|
198
|
+
"typescript": "^5.7.3",
|
|
199
|
+
"vitest": "^3.0.5"
|
|
211
200
|
},
|
|
212
201
|
"dependencies": {
|
|
213
|
-
"@xmldom/xmldom": "^0.9.
|
|
202
|
+
"@xmldom/xmldom": "^0.9.7",
|
|
214
203
|
"clipboardy": "^4.0.0",
|
|
215
|
-
"command-line-args": "^6.0.
|
|
204
|
+
"command-line-args": "^6.0.1",
|
|
216
205
|
"command-line-usage": "^7.0.3",
|
|
217
206
|
"joi": "^17.13.3",
|
|
218
207
|
"n-readlines": "^1.0.1",
|
|
219
|
-
"n3": "^1.
|
|
208
|
+
"n3": "^1.23.1",
|
|
220
209
|
"object-hash": "^3.0.0",
|
|
221
210
|
"object-sizeof": "^2.6.5",
|
|
222
|
-
"rotating-file-stream": "^3.2.
|
|
223
|
-
"semver": "^7.
|
|
211
|
+
"rotating-file-stream": "^3.2.6",
|
|
212
|
+
"semver": "^7.7.1",
|
|
224
213
|
"tar": "^7.4.3",
|
|
225
214
|
"tmp": "^0.2.3",
|
|
226
|
-
"ts-essentials": "^10.0.
|
|
215
|
+
"ts-essentials": "^10.0.4",
|
|
227
216
|
"tslog": "^4.9.3",
|
|
228
217
|
"web-tree-sitter": "^0.24.7",
|
|
229
218
|
"ws": "^8.18.0",
|
|
@@ -12,7 +12,6 @@ const visitor_1 = require("../../../r-bridge/lang-4.x/ast/model/processing/visit
|
|
|
12
12
|
const assert_1 = require("../../../util/assert");
|
|
13
13
|
const objects_1 = require("../../../util/objects");
|
|
14
14
|
const SupportedVertexTypes = [type_1.RType.String, type_1.RType.Logical, type_1.RType.Number];
|
|
15
|
-
const Unknown = 'unknown';
|
|
16
15
|
function executeDependenciesQuery(data, queries) {
|
|
17
16
|
if (queries.length !== 1) {
|
|
18
17
|
log_1.log.warn('Dependencies query expects only up to one query, but got ', queries.length, 'only using the first query');
|
|
@@ -26,10 +25,24 @@ function executeDependenciesQuery(data, queries) {
|
|
|
26
25
|
const writeFunctions = getFunctionsToCheck(query.writeFunctions, ignoreDefault, dependencies_query_format_1.WriteFunctions);
|
|
27
26
|
const numberOfFunctions = libraryFunctions.length + sourceFunctions.length + readFunctions.length + writeFunctions.length;
|
|
28
27
|
const results = numberOfFunctions === 0 ? { kinds: {}, '.meta': { timing: 0 } } : (0, query_1.executeQueriesOfSameType)(data, ...makeCallContextQuery(libraryFunctions, 'library'), ...makeCallContextQuery(sourceFunctions, 'source'), ...makeCallContextQuery(readFunctions, 'read'), ...makeCallContextQuery(writeFunctions, 'write'));
|
|
29
|
-
const
|
|
28
|
+
const getLexeme = (argument, id) => {
|
|
29
|
+
if ((argument && argument !== dependencies_query_format_1.Unknown) || !id) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
let get = data.ast.idMap.get(id);
|
|
33
|
+
if (!get) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
if (get.type === type_1.RType.Argument) {
|
|
37
|
+
get = get.value;
|
|
38
|
+
}
|
|
39
|
+
return get?.info.fullLexeme ?? get?.lexeme;
|
|
40
|
+
};
|
|
41
|
+
const libraries = getResults(data, results, 'library', libraryFunctions, (id, vertex, argId, argument) => ({
|
|
30
42
|
nodeId: id,
|
|
31
43
|
functionName: vertex.name,
|
|
32
|
-
|
|
44
|
+
lexemeOfArgument: getLexeme(argument, argId),
|
|
45
|
+
libraryName: argument ?? dependencies_query_format_1.Unknown
|
|
33
46
|
}), [type_1.RType.Symbol]);
|
|
34
47
|
if (!ignoreDefault) {
|
|
35
48
|
/* for libraries, we have to additionally track all uses of `::` and `:::`, for this we currently simply traverse all uses */
|
|
@@ -44,24 +57,27 @@ function executeDependenciesQuery(data, queries) {
|
|
|
44
57
|
}
|
|
45
58
|
});
|
|
46
59
|
}
|
|
47
|
-
const sourcedFiles = getResults(data, results, 'source', sourceFunctions, (id, vertex, argument, linkedIds) => ({
|
|
60
|
+
const sourcedFiles = getResults(data, results, 'source', sourceFunctions, (id, vertex, argId, argument, linkedIds) => ({
|
|
48
61
|
nodeId: id,
|
|
49
62
|
functionName: vertex.name,
|
|
50
|
-
file: argument ?? Unknown,
|
|
51
|
-
|
|
63
|
+
file: argument ?? dependencies_query_format_1.Unknown,
|
|
64
|
+
lexemeOfArgument: getLexeme(argument, argId),
|
|
65
|
+
linkedIds: linkedIds?.length ? linkedIds : undefined
|
|
52
66
|
}));
|
|
53
|
-
const readData = getResults(data, results, 'read', readFunctions, (id, vertex, argument, linkedIds) => ({
|
|
67
|
+
const readData = getResults(data, results, 'read', readFunctions, (id, vertex, argId, argument, linkedIds) => ({
|
|
54
68
|
nodeId: id,
|
|
55
69
|
functionName: vertex.name,
|
|
56
|
-
source: argument ?? Unknown,
|
|
57
|
-
|
|
70
|
+
source: argument ?? dependencies_query_format_1.Unknown,
|
|
71
|
+
lexemeOfArgument: getLexeme(argument, argId),
|
|
72
|
+
linkedIds: linkedIds?.length ? linkedIds : undefined
|
|
58
73
|
}));
|
|
59
|
-
const writtenData = getResults(data, results, 'write', writeFunctions, (id, vertex, argument, linkedIds) => ({
|
|
74
|
+
const writtenData = getResults(data, results, 'write', writeFunctions, (id, vertex, argId, argument, linkedIds) => ({
|
|
60
75
|
nodeId: id,
|
|
61
76
|
functionName: vertex.name,
|
|
62
77
|
// write functions that don't have argIndex are assumed to write to stdout
|
|
63
|
-
destination: argument ?? (
|
|
64
|
-
|
|
78
|
+
destination: argument ?? (linkedIds?.length ? dependencies_query_format_1.Unknown : 'stdout'),
|
|
79
|
+
lexemeOfArgument: getLexeme(argument, argId),
|
|
80
|
+
linkedIds: linkedIds?.length ? linkedIds : undefined
|
|
65
81
|
}));
|
|
66
82
|
return {
|
|
67
83
|
'.meta': {
|
|
@@ -82,7 +98,8 @@ function makeCallContextQuery(functions, kind) {
|
|
|
82
98
|
}));
|
|
83
99
|
}
|
|
84
100
|
function getResults(data, results, kind, functions, makeInfo, additionalAllowedTypes) {
|
|
85
|
-
|
|
101
|
+
const kindEntries = Object.entries(results?.kinds[kind]?.subkinds ?? {});
|
|
102
|
+
return kindEntries.flatMap(([name, results]) => results.flatMap(({ id, linkedIds }) => {
|
|
86
103
|
const vertex = data.dataflow.graph.getVertex(id);
|
|
87
104
|
const info = functions.find(f => f.name === name);
|
|
88
105
|
let index = info.argIdx;
|
|
@@ -94,43 +111,58 @@ function getResults(data, results, kind, functions, makeInfo, additionalAllowedT
|
|
|
94
111
|
}
|
|
95
112
|
const args = index !== undefined ? getArgumentValue(data, vertex, index, additionalAllowedTypes) : undefined;
|
|
96
113
|
if (!args) {
|
|
97
|
-
|
|
114
|
+
const record = (0, objects_1.compactRecord)(makeInfo(id, vertex, undefined, undefined, linkedIds));
|
|
115
|
+
return record ? [record] : [];
|
|
98
116
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
// return all unnamed arguments
|
|
106
|
-
const references = vertex.args.filter(arg => arg !== r_function_call_1.EmptyArgument && !arg.name).map(graph_1.getReferenceOfArgument);
|
|
107
|
-
return references.map(ref => {
|
|
108
|
-
if (!ref) {
|
|
109
|
-
return undefined;
|
|
110
|
-
}
|
|
111
|
-
let valueNode = graph.idMap?.get(ref);
|
|
112
|
-
if (valueNode?.type === type_1.RType.Argument) {
|
|
113
|
-
valueNode = valueNode.value;
|
|
114
|
-
}
|
|
115
|
-
if (valueNode) {
|
|
116
|
-
const allowedTypes = [...SupportedVertexTypes, ...additionalAllowedTypes ?? []];
|
|
117
|
-
return allowedTypes.includes(valueNode.type) ? (0, retriever_1.removeRQuotes)(valueNode.lexeme) : Unknown;
|
|
117
|
+
const results = [];
|
|
118
|
+
for (const [arg, values] of args.entries()) {
|
|
119
|
+
for (const value of values) {
|
|
120
|
+
const result = (0, objects_1.compactRecord)(makeInfo(id, vertex, arg, value, linkedIds));
|
|
121
|
+
if (result) {
|
|
122
|
+
results.push(result);
|
|
118
123
|
}
|
|
119
|
-
}
|
|
124
|
+
}
|
|
120
125
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
return results;
|
|
127
|
+
})) ?? [];
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get the values of all arguments matching the criteria.
|
|
131
|
+
*/
|
|
132
|
+
function getArgumentValue({ dataflow: { graph } }, vertex, argumentIndex, additionalAllowedTypes) {
|
|
133
|
+
if (!vertex) {
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
if (argumentIndex === 'unnamed') {
|
|
137
|
+
// return all unnamed arguments
|
|
138
|
+
const references = vertex.args.filter(arg => arg !== r_function_call_1.EmptyArgument && !arg.name).map(graph_1.getReferenceOfArgument).filter(assert_1.isNotUndefined);
|
|
139
|
+
const map = new Map();
|
|
140
|
+
for (const ref of references) {
|
|
141
|
+
let valueNode = graph.idMap?.get(ref);
|
|
142
|
+
if (valueNode?.type === type_1.RType.Argument) {
|
|
143
|
+
valueNode = valueNode.value;
|
|
144
|
+
}
|
|
145
|
+
if (valueNode) {
|
|
146
|
+
const allowedTypes = [...SupportedVertexTypes, ...additionalAllowedTypes ?? []];
|
|
147
|
+
const value = allowedTypes.includes(valueNode.type) ? (0, retriever_1.removeRQuotes)(valueNode.lexeme) : dependencies_query_format_1.Unknown;
|
|
148
|
+
map.set(ref, new Set([value]));
|
|
132
149
|
}
|
|
133
150
|
}
|
|
151
|
+
return map;
|
|
152
|
+
}
|
|
153
|
+
if (vertex.args.length > argumentIndex) {
|
|
154
|
+
const arg = (0, graph_1.getReferenceOfArgument)(vertex.args[argumentIndex]);
|
|
155
|
+
if (!arg) {
|
|
156
|
+
return undefined;
|
|
157
|
+
}
|
|
158
|
+
let valueNode = graph.idMap?.get(arg);
|
|
159
|
+
if (valueNode?.type === type_1.RType.Argument) {
|
|
160
|
+
valueNode = valueNode.value;
|
|
161
|
+
}
|
|
162
|
+
if (valueNode) {
|
|
163
|
+
const allowedTypes = [...SupportedVertexTypes, ...additionalAllowedTypes ?? []];
|
|
164
|
+
return new Map([[arg, new Set([allowedTypes.includes(valueNode.type) ? (0, retriever_1.removeRQuotes)(valueNode.lexeme) : dependencies_query_format_1.Unknown])]]);
|
|
165
|
+
}
|
|
134
166
|
}
|
|
135
167
|
return undefined;
|
|
136
168
|
}
|
|
@@ -2,6 +2,7 @@ import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
|
|
|
2
2
|
import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
3
3
|
import Joi from 'joi';
|
|
4
4
|
import { executeDependenciesQuery } from './dependencies-query-executor';
|
|
5
|
+
export declare const Unknown = "unknown";
|
|
5
6
|
export declare const LibraryFunctions: FunctionInfo[];
|
|
6
7
|
export declare const SourceFunctions: FunctionInfo[];
|
|
7
8
|
export declare const ReadFunctions: FunctionInfo[];
|
|
@@ -30,6 +31,8 @@ export interface DependencyInfo extends Record<string, unknown> {
|
|
|
30
31
|
nodeId: NodeId;
|
|
31
32
|
functionName: string;
|
|
32
33
|
linkedIds?: readonly NodeId[];
|
|
34
|
+
/** the lexeme is presented whenever the specific info is of {@link Unknown} */
|
|
35
|
+
lexemeOfArgument?: string;
|
|
33
36
|
}
|
|
34
37
|
export type LibraryInfo = (DependencyInfo & {
|
|
35
38
|
libraryName: 'unknown' | string;
|
|
@@ -3,11 +3,12 @@ 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.DependenciesQueryDefinition = exports.WriteFunctions = exports.ReadFunctions = exports.SourceFunctions = exports.LibraryFunctions = void 0;
|
|
6
|
+
exports.DependenciesQueryDefinition = exports.WriteFunctions = exports.ReadFunctions = exports.SourceFunctions = exports.LibraryFunctions = exports.Unknown = void 0;
|
|
7
7
|
const ansi_1 = require("../../../util/ansi");
|
|
8
8
|
const time_1 = require("../../../util/time");
|
|
9
9
|
const joi_1 = __importDefault(require("joi"));
|
|
10
10
|
const dependencies_query_executor_1 = require("./dependencies-query-executor");
|
|
11
|
+
exports.Unknown = 'unknown';
|
|
11
12
|
// these lists are originally based on https://github.com/duncantl/CodeDepends/blob/7fd96dfee16b252e5f642c77a7ababf48e9326f8/R/codeTypes.R
|
|
12
13
|
exports.LibraryFunctions = [
|
|
13
14
|
{ name: 'library', argIdx: 0, argName: 'package' },
|
|
@@ -87,7 +88,7 @@ exports.ReadFunctions = [
|
|
|
87
88
|
{ name: 'Import', argIdx: 0, argName: 'file' },
|
|
88
89
|
];
|
|
89
90
|
exports.WriteFunctions = [
|
|
90
|
-
{ name: 'save', argIdx:
|
|
91
|
+
{ name: 'save', argIdx: 2, argName: 'file' },
|
|
91
92
|
{ name: 'save.image', argIdx: 0, argName: 'file' },
|
|
92
93
|
{ name: 'write', argIdx: 1, argName: 'file' },
|
|
93
94
|
{ name: 'dput', argIdx: 1, argName: 'file' },
|
|
@@ -22,6 +22,6 @@ exports.HappensBeforeQueryDefinition = {
|
|
|
22
22
|
type: joi_1.default.string().valid('happens-before').required().description('The type of the query.'),
|
|
23
23
|
a: joi_1.default.string().required().description('The first slicing criterion.'),
|
|
24
24
|
b: joi_1.default.string().required().description('The second slicing criterion.')
|
|
25
|
-
}).description('
|
|
25
|
+
}).description('Happens-Before tracks whether a always happens before b.')
|
|
26
26
|
};
|
|
27
27
|
//# sourceMappingURL=happens-before-query-format.js.map
|
|
@@ -19,7 +19,7 @@ function executeResolveValueQuery({ dataflow: { graph, environment }, ast }, que
|
|
|
19
19
|
}
|
|
20
20
|
const values = query.criteria
|
|
21
21
|
.map(criteria => (0, node_id_1.recoverName)((0, parse_1.slicingCriterionToId)(criteria, ast.idMap), ast.idMap))
|
|
22
|
-
.flatMap(ident => (0, resolve_by_name_1.resolveToValues)(ident, environment, graph));
|
|
22
|
+
.flatMap(ident => (0, resolve_by_name_1.resolveToValues)(ident, environment, graph.idMap ?? ast.idMap));
|
|
23
23
|
results[key] = {
|
|
24
24
|
values: [...new Set(values)]
|
|
25
25
|
};
|
|
@@ -44,6 +44,6 @@ exports.ResolveValueQueryDefinition = {
|
|
|
44
44
|
schema: joi_1.default.object({
|
|
45
45
|
type: joi_1.default.string().valid('resolve-value').required().description('The type of the query.'),
|
|
46
46
|
criteria: joi_1.default.array().items(joi_1.default.string()).min(1).required().description('The slicing criteria to use.'),
|
|
47
|
-
}).description('
|
|
47
|
+
}).description('The resolve value query used to get definitions of an identifier')
|
|
48
48
|
};
|
|
49
49
|
//# sourceMappingURL=resolve-value-query-format.js.map
|
|
@@ -24,6 +24,6 @@ exports.SearchQueryDefinition = {
|
|
|
24
24
|
schema: joi_1.default.object({
|
|
25
25
|
type: joi_1.default.string().valid('search').required().description('The type of the query.'),
|
|
26
26
|
search: joi_1.default.object().required().description('The search query to execute.')
|
|
27
|
-
}).description('The
|
|
27
|
+
}).description('The search query searches the normalized AST and dataflow graph for nodes that match the given search query.')
|
|
28
28
|
};
|
|
29
29
|
//# sourceMappingURL=search-query-format.js.map
|
package/r-bridge/data/data.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export declare const flowrCapabilities: {
|
|
2
2
|
readonly name: "Capabilities of flowR";
|
|
3
3
|
readonly description: "This is an evolving representation of what started with #636 to formulate capabilities in a structured format.";
|
|
4
|
-
readonly version: "0.0.
|
|
4
|
+
readonly version: "0.0.2";
|
|
5
5
|
readonly capabilities: readonly [{
|
|
6
6
|
readonly name: "Names and Identifiers";
|
|
7
7
|
readonly id: "names-and-identifiers";
|
|
8
|
+
readonly description: "The recognition of syntactical and non-syntactical names, including their resolutions to corresponding definitions.";
|
|
9
|
+
readonly example: (parser: import("../parser").KnownParser) => Promise<string>;
|
|
8
10
|
readonly capabilities: readonly [{
|
|
9
11
|
readonly name: "Form";
|
|
10
12
|
readonly id: "form";
|
|
@@ -12,17 +14,41 @@ export declare const flowrCapabilities: {
|
|
|
12
14
|
readonly name: "Normal";
|
|
13
15
|
readonly id: "name-normal";
|
|
14
16
|
readonly supported: "fully";
|
|
15
|
-
readonly description: "_Recognize
|
|
17
|
+
readonly description: "_Recognize symbol uses like `a`, `plot`, ..._ (i.e., \"normal variables or function calls\").";
|
|
18
|
+
readonly url: [{
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly href: "https://adv-r.hadley.nz/names-values.html#binding-basics";
|
|
21
|
+
}, {
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly href: "https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Identifiers-1";
|
|
24
|
+
}];
|
|
16
25
|
}, {
|
|
17
26
|
readonly name: "Quoted";
|
|
18
27
|
readonly id: "name-quoted";
|
|
19
28
|
readonly supported: "fully";
|
|
20
|
-
readonly description: "_Recognize `\"a\"`, `'plot'`, ..._";
|
|
29
|
+
readonly description: "_Recognize `\"a\"`, `'plot'`, ..._ In general, R allows to envelop names in quotations to allow for special characters such as spaces in variable names. However, this only works in the context of definitions. To access these names as variables, one has to either use function such as `get` or escape the name with backticks.";
|
|
30
|
+
readonly url: [{
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly href: "https://adv-r.hadley.nz/names-values.html#non-syntactic";
|
|
33
|
+
}];
|
|
21
34
|
}, {
|
|
22
35
|
readonly name: "Escaped";
|
|
23
36
|
readonly id: "name-escaped";
|
|
24
37
|
readonly supported: "fully";
|
|
25
38
|
readonly description: "_Recognize `` `a` ``, `` `plot` ``, ..._";
|
|
39
|
+
readonly url: [{
|
|
40
|
+
readonly name: string;
|
|
41
|
+
readonly href: "https://adv-r.hadley.nz/names-values.html#non-syntactic";
|
|
42
|
+
}];
|
|
43
|
+
}, {
|
|
44
|
+
readonly name: "Created";
|
|
45
|
+
readonly id: "name-created";
|
|
46
|
+
readonly supported: "partially";
|
|
47
|
+
readonly description: "_Recognize functions which resolve strings as identifiers, such as `get`, ..._";
|
|
48
|
+
readonly url: [{
|
|
49
|
+
readonly name: "flowr#633";
|
|
50
|
+
readonly href: string;
|
|
51
|
+
}];
|
|
26
52
|
}];
|
|
27
53
|
}, {
|
|
28
54
|
readonly name: "Resolution";
|
|
@@ -538,25 +564,40 @@ export declare const flowrCapabilities: {
|
|
|
538
564
|
readonly capabilities: readonly [{
|
|
539
565
|
readonly name: "S3";
|
|
540
566
|
readonly id: "oop-s3";
|
|
541
|
-
readonly
|
|
567
|
+
readonly url: [{
|
|
568
|
+
readonly name: string;
|
|
569
|
+
readonly href: "https://adv-r.hadley.nz/s3.html";
|
|
570
|
+
}];
|
|
542
571
|
readonly supported: "not";
|
|
543
572
|
readonly description: "_Handle S3 classes and methods as one unit (with attributes etc.). Including Dispatch and Inheritance._ We do not support typing currently and do not handle objects of these classes \"as units.\"";
|
|
544
573
|
}, {
|
|
545
574
|
readonly name: "S4";
|
|
546
575
|
readonly id: "oop-s4";
|
|
547
|
-
readonly
|
|
576
|
+
readonly url: [{
|
|
577
|
+
readonly name: string;
|
|
578
|
+
readonly href: "https://adv-r.hadley.nz/s4.html";
|
|
579
|
+
}];
|
|
548
580
|
readonly supported: "not";
|
|
549
581
|
readonly description: "_Handle S4 classes and methods as one unit. Including Dispatch and Inheritance_ We do not support typing currently and do not handle objects of these classes \"as units.\"";
|
|
550
582
|
}, {
|
|
551
583
|
readonly name: "R6";
|
|
552
584
|
readonly id: "oop-r6";
|
|
553
|
-
readonly
|
|
585
|
+
readonly url: [{
|
|
586
|
+
readonly name: string;
|
|
587
|
+
readonly href: "https://adv-r.hadley.nz/r6.html";
|
|
588
|
+
}];
|
|
554
589
|
readonly supported: "not";
|
|
555
590
|
readonly description: "_Handle R6 classes and methods as one unit. Including Dispatch and Inheritance, as well as its Reference Semantics, Access Control, Finalizers, and Introspection._ We do not support typing currently and do not handle objects of these classes \"as units.\"";
|
|
556
591
|
}, {
|
|
557
592
|
readonly name: "R7/S7";
|
|
558
593
|
readonly id: "r7-s7";
|
|
559
|
-
readonly
|
|
594
|
+
readonly url: [{
|
|
595
|
+
readonly name: "R7";
|
|
596
|
+
readonly href: "https://www.r-bloggers.com/2022/12/what-is-r7-a-new-oop-system-for-r/";
|
|
597
|
+
}, {
|
|
598
|
+
readonly name: "S7";
|
|
599
|
+
readonly href: "https://cran.r-project.org/web/packages/S7/index.html";
|
|
600
|
+
}];
|
|
560
601
|
readonly supported: "not";
|
|
561
602
|
readonly description: "_Handle R7 classes and methods as one unit. Including Dispatch and Inheritance, as well as its Reference Semantics, Validators, ..._ We do not support typing currently and do not handle objects of these classes \"as units.\"";
|
|
562
603
|
}];
|
package/r-bridge/data/data.js
CHANGED
|
@@ -1,14 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.flowrCapabilities = void 0;
|
|
4
|
+
const doc_files_1 = require("../../documentation/doc-util/doc-files");
|
|
5
|
+
const doc_code_1 = require("../../documentation/doc-util/doc-code");
|
|
6
|
+
const doc_dfg_1 = require("../../documentation/doc-util/doc-dfg");
|
|
7
|
+
const Joiner = '/';
|
|
8
|
+
const AdvancedR = (subname) => 'Advanced R' + Joiner + subname;
|
|
9
|
+
const RLang = (subname) => 'R Definition' + Joiner + subname;
|
|
10
|
+
const Issue = (num) => `${doc_files_1.FlowrGithubBaseRef}/flowr/issues/${num}`;
|
|
11
|
+
const LinkTo = (id, label = id) => `[${label}](#${id})`;
|
|
4
12
|
exports.flowrCapabilities = {
|
|
5
13
|
name: 'Capabilities of flowR',
|
|
6
14
|
description: 'This is an evolving representation of what started with #636 to formulate capabilities in a structured format.',
|
|
7
|
-
version: '0.0.
|
|
15
|
+
version: '0.0.2',
|
|
8
16
|
capabilities: [
|
|
9
17
|
{
|
|
10
18
|
name: 'Names and Identifiers',
|
|
11
19
|
id: 'names-and-identifiers',
|
|
20
|
+
description: 'The recognition of syntactical and non-syntactical names, including their resolutions to corresponding definitions.',
|
|
21
|
+
example: async (parser) => {
|
|
22
|
+
const code = '"f" <- function(x) { get("x") } \n`y x` <- 2\nprint(`y x` + f(3))';
|
|
23
|
+
return `
|
|
24
|
+
Consider the following R code:
|
|
25
|
+
${(0, doc_code_1.codeBlock)('r', code)}
|
|
26
|
+
Identifiers of interest are:
|
|
27
|
+
|
|
28
|
+
- The symbols \`x\` (${LinkTo('name-normal')}), \`f\` (${LinkTo('name-quoted')}), and \`\` \`y x\` \`\` (${LinkTo('name-escaped')}).
|
|
29
|
+
- The function calls \`<-\`, \`function\`, \`{\`, \`get\`, \`+\`, and \`print\` (${LinkTo('function-calls')}, all given with ${LinkTo('name-normal')}).
|
|
30
|
+
Especially \`{\` is identified as a ${LinkTo('grouping')} of the ${LinkTo('function-definitions', 'function-definitions\'')} body.
|
|
31
|
+
- The quoted name created by a function call \`get\` (${LinkTo('name-created')}).
|
|
32
|
+
|
|
33
|
+
Besides the parameter \`x\`, which is resolved in its ${LinkTo('lexicographic-scope')}, the other identifiers are resolved in the ${LinkTo('global-scope')}.
|
|
34
|
+
|
|
35
|
+
${await (0, doc_dfg_1.printDfGraphForCode)(parser, code, { simplified: true })}
|
|
36
|
+
`;
|
|
37
|
+
},
|
|
12
38
|
capabilities: [
|
|
13
39
|
{
|
|
14
40
|
name: 'Form',
|
|
@@ -18,19 +44,38 @@ exports.flowrCapabilities = {
|
|
|
18
44
|
name: 'Normal',
|
|
19
45
|
id: 'name-normal',
|
|
20
46
|
supported: 'fully',
|
|
21
|
-
description: '_Recognize
|
|
47
|
+
description: '_Recognize symbol uses like `a`, `plot`, ..._ (i.e., "normal variables or function calls").',
|
|
48
|
+
url: [
|
|
49
|
+
{ name: AdvancedR('Bindings'), href: 'https://adv-r.hadley.nz/names-values.html#binding-basics' },
|
|
50
|
+
{ name: RLang('Identifiers'), href: 'https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Identifiers-1' }
|
|
51
|
+
]
|
|
22
52
|
},
|
|
23
53
|
{
|
|
24
54
|
name: 'Quoted',
|
|
25
55
|
id: 'name-quoted',
|
|
26
56
|
supported: 'fully',
|
|
27
|
-
description: "_Recognize `\"a\"`, `'plot'`, ..._"
|
|
57
|
+
description: "_Recognize `\"a\"`, `'plot'`, ..._ In general, R allows to envelop names in quotations to allow for special characters such as spaces in variable names. However, this only works in the context of definitions. To access these names as variables, one has to either use function such as `get` or escape the name with backticks.",
|
|
58
|
+
url: [
|
|
59
|
+
{ name: AdvancedR('Non-Syntactic Names'), href: 'https://adv-r.hadley.nz/names-values.html#non-syntactic' }
|
|
60
|
+
]
|
|
28
61
|
},
|
|
29
62
|
{
|
|
30
63
|
name: 'Escaped',
|
|
31
64
|
id: 'name-escaped',
|
|
32
65
|
supported: 'fully',
|
|
33
|
-
description: '_Recognize `` `a` ``, `` `plot` ``, ..._'
|
|
66
|
+
description: '_Recognize `` `a` ``, `` `plot` ``, ..._',
|
|
67
|
+
url: [
|
|
68
|
+
{ name: AdvancedR('Non-Syntactic Names'), href: 'https://adv-r.hadley.nz/names-values.html#non-syntactic' }
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'Created',
|
|
73
|
+
id: 'name-created',
|
|
74
|
+
supported: 'partially',
|
|
75
|
+
description: '_Recognize functions which resolve strings as identifiers, such as `get`, ..._',
|
|
76
|
+
url: [
|
|
77
|
+
{ name: 'flowr#633', href: Issue(633) }
|
|
78
|
+
]
|
|
34
79
|
}
|
|
35
80
|
]
|
|
36
81
|
},
|
|
@@ -671,28 +716,37 @@ exports.flowrCapabilities = {
|
|
|
671
716
|
{
|
|
672
717
|
name: 'S3',
|
|
673
718
|
id: 'oop-s3',
|
|
674
|
-
|
|
719
|
+
url: [
|
|
720
|
+
{ name: AdvancedR('S3'), href: 'https://adv-r.hadley.nz/s3.html' }
|
|
721
|
+
],
|
|
675
722
|
supported: 'not',
|
|
676
723
|
description: '_Handle S3 classes and methods as one unit (with attributes etc.). Including Dispatch and Inheritance._ We do not support typing currently and do not handle objects of these classes "as units."'
|
|
677
724
|
},
|
|
678
725
|
{
|
|
679
726
|
name: 'S4',
|
|
680
727
|
id: 'oop-s4',
|
|
681
|
-
|
|
728
|
+
url: [
|
|
729
|
+
{ name: AdvancedR('S4'), href: 'https://adv-r.hadley.nz/s4.html' }
|
|
730
|
+
],
|
|
682
731
|
supported: 'not',
|
|
683
732
|
description: '_Handle S4 classes and methods as one unit. Including Dispatch and Inheritance_ We do not support typing currently and do not handle objects of these classes "as units."'
|
|
684
733
|
},
|
|
685
734
|
{
|
|
686
735
|
name: 'R6',
|
|
687
736
|
id: 'oop-r6',
|
|
688
|
-
|
|
737
|
+
url: [
|
|
738
|
+
{ name: AdvancedR('R6'), href: 'https://adv-r.hadley.nz/r6.html' }
|
|
739
|
+
],
|
|
689
740
|
supported: 'not',
|
|
690
741
|
description: '_Handle R6 classes and methods as one unit. Including Dispatch and Inheritance, as well as its Reference Semantics, Access Control, Finalizers, and Introspection._ We do not support typing currently and do not handle objects of these classes "as units."'
|
|
691
742
|
},
|
|
692
743
|
{
|
|
693
744
|
name: 'R7/S7',
|
|
694
745
|
id: 'r7-s7',
|
|
695
|
-
|
|
746
|
+
url: [
|
|
747
|
+
{ name: 'R7', href: 'https://www.r-bloggers.com/2022/12/what-is-r7-a-new-oop-system-for-r/' },
|
|
748
|
+
{ name: 'S7', href: 'https://cran.r-project.org/web/packages/S7/index.html' }
|
|
749
|
+
],
|
|
696
750
|
supported: 'not',
|
|
697
751
|
description: '_Handle R7 classes and methods as one unit. Including Dispatch and Inheritance, as well as its Reference Semantics, Validators, ..._ We do not support typing currently and do not handle objects of these classes "as units."'
|
|
698
752
|
}
|
package/r-bridge/data/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { KnownParser } from '../parser';
|
|
1
2
|
declare const enum RequiredFeature {
|
|
2
3
|
/** https://github.com/flowr-analysis/flowr/labels/typing */
|
|
3
4
|
Typing = 0,
|
|
@@ -15,7 +16,12 @@ export interface FlowrCapability {
|
|
|
15
16
|
/** A list of features that are required for the capability, extend at need. */
|
|
16
17
|
readonly needs?: RequiredFeature[];
|
|
17
18
|
readonly description?: string;
|
|
18
|
-
readonly
|
|
19
|
+
readonly example?: string | ((parser: KnownParser) => Promise<string>);
|
|
20
|
+
/** A list of URLs that provide additional information about the capability */
|
|
21
|
+
readonly url?: {
|
|
22
|
+
name: string;
|
|
23
|
+
href: string;
|
|
24
|
+
}[];
|
|
19
25
|
/** The level of support for the capability, undefined if it is a meta-capability that does not need such an attribute */
|
|
20
26
|
readonly supported?: 'not' | 'partially' | 'fully';
|
|
21
27
|
readonly capabilities?: readonly FlowrCapability[];
|