@eagleoutice/flowr 2.10.1 → 2.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -16
- package/abstract-interpretation/absint-visitor.d.ts +13 -8
- package/abstract-interpretation/absint-visitor.js +35 -26
- package/abstract-interpretation/data-frame/dataframe-domain.d.ts +1 -2
- package/abstract-interpretation/data-frame/dataframe-domain.js +14 -15
- package/abstract-interpretation/data-frame/mappers/access-mapper.js +2 -15
- package/abstract-interpretation/data-frame/mappers/arguments.d.ts +11 -17
- package/abstract-interpretation/data-frame/mappers/arguments.js +18 -18
- package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +41 -15
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +74 -48
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +2 -1
- package/abstract-interpretation/data-frame/semantics.d.ts +1 -1
- package/abstract-interpretation/data-frame/semantics.js +31 -35
- package/abstract-interpretation/data-frame/shape-inference.js +1 -1
- package/abstract-interpretation/domains/interval-domain.d.ts +1 -0
- package/abstract-interpretation/domains/interval-domain.js +3 -0
- package/abstract-interpretation/domains/product-domain.d.ts +9 -0
- package/abstract-interpretation/domains/product-domain.js +26 -6
- package/abstract-interpretation/domains/state-abstract-domain.d.ts +36 -22
- package/abstract-interpretation/domains/state-abstract-domain.js +169 -62
- package/abstract-interpretation/unsupported-functions.d.ts +10 -0
- package/abstract-interpretation/unsupported-functions.js +45 -0
- package/benchmark/slicer.js +10 -13
- package/cli/flowr.js +1 -1
- package/control-flow/control-flow-graph.js +13 -9
- package/control-flow/semantic-cfg-guided-visitor.d.ts +6 -0
- package/control-flow/semantic-cfg-guided-visitor.js +6 -0
- package/dataflow/environments/built-in-proc-name.d.ts +6 -0
- package/dataflow/environments/built-in-proc-name.js +6 -0
- package/dataflow/environments/built-in.d.ts +7 -5
- package/dataflow/environments/built-in.js +2 -0
- package/dataflow/environments/default-builtin-config.d.ts +442 -6
- package/dataflow/environments/default-builtin-config.js +158 -3
- package/dataflow/environments/overwrite.js +2 -5
- package/dataflow/graph/df-helper.d.ts +14 -4
- package/dataflow/graph/df-helper.js +36 -6
- package/dataflow/graph/graph.d.ts +10 -0
- package/dataflow/graph/graph.js +12 -0
- package/dataflow/instrument/instrument-dataflow-count.d.ts +10 -0
- package/dataflow/instrument/instrument-dataflow-count.js +10 -0
- package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +4 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-access.d.ts +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +6 -17
- package/dataflow/internal/process/functions/call/built-in/built-in-get.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-library.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-list.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-local.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.d.ts +23 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +80 -12
- package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.d.ts +41 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-purrr-formula.js +179 -0
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.d.ts +7 -4
- package/dataflow/internal/process/functions/call/built-in/built-in-quote.js +62 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-recall.d.ts +7 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-recall.js +15 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-rm.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-dispatch.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-special-bin-op.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-stop-if-not.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-try-catch.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.d.ts +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.d.ts +2 -2
- package/dataflow/internal/process/functions/call/common.d.ts +2 -2
- package/dataflow/internal/process/functions/call/common.js +4 -3
- package/dataflow/internal/process/functions/call/known-call-handling.d.ts +2 -2
- package/dataflow/internal/process/functions/call/named-call-handling.d.ts +2 -2
- package/documentation/wiki-absint.js +6 -5
- package/documentation/wiki-analyzer.js +0 -2
- package/documentation/wiki-linter.js +1 -0
- package/documentation/wiki-normalized-ast.js +7 -7
- package/linter/linter-rules.d.ts +24 -1
- package/linter/linter-rules.js +3 -1
- package/linter/rules/dataframe-access-validation.d.ts +1 -1
- package/linter/rules/dataframe-access-validation.js +3 -4
- package/linter/rules/roxygen-arguments.d.ts +35 -0
- package/linter/rules/roxygen-arguments.js +100 -0
- package/package.json +2 -3
- package/project/context/flowr-analyzer-context.d.ts +1 -8
- package/project/context/flowr-analyzer-context.js +1 -7
- package/project/context/flowr-analyzer-environment-context.d.ts +5 -0
- package/project/context/flowr-analyzer-environment-context.js +6 -0
- package/project/context/flowr-analyzer-files-context.d.ts +6 -0
- package/project/context/flowr-analyzer-files-context.js +4 -2
- package/project/flowr-analyzer-builder.js +1 -4
- 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 +10 -5
- package/queries/catalog/call-context-query/call-context-query-format.d.ts +1 -1
- package/queries/catalog/dependencies-query/function-info/library-functions.js +2 -0
- package/queries/catalog/df-shape-query/df-shape-query-format.js +7 -2
- package/queries/catalog/files-query/files-query-executor.js +0 -1
- package/queries/catalog/input-sources-query/simple-input-classifier.d.ts +2 -0
- package/queries/catalog/input-sources-query/simple-input-classifier.js +2 -0
- package/r-bridge/data/data.d.ts +2 -2
- package/r-bridge/data/data.js +2 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +13 -5
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +14 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +3 -3
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +9 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +13 -0
- package/r-bridge/lang-4.x/ast/model/versions.d.ts +2 -0
- package/r-bridge/lang-4.x/ast/model/versions.js +3 -1
- package/r-bridge/roxygen2/documentation-provider.js +15 -6
- package/r-bridge/roxygen2/roxygen-ast.d.ts +3 -1
- package/search/flowr-search-builder.js +3 -2
- package/util/mermaid/ast.js +2 -1
- package/util/record.d.ts +23 -0
- package/util/record.js +33 -0
- package/util/version.js +1 -1
- package/abstract-interpretation/domains/mapped-abstract-domain.d.ts +0 -41
- package/abstract-interpretation/domains/mapped-abstract-domain.js +0 -213
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ROXYGEN_ARGS = void 0;
|
|
4
|
+
const linter_format_1 = require("../linter-format");
|
|
5
|
+
const range_1 = require("../../util/range");
|
|
6
|
+
const flowr_search_builder_1 = require("../../search/flowr-search-builder");
|
|
7
|
+
const linter_tags_1 = require("../linter-tags");
|
|
8
|
+
const assert_1 = require("../../util/assert");
|
|
9
|
+
const vertex_1 = require("../../dataflow/graph/vertex");
|
|
10
|
+
const roxygen_ast_1 = require("../../r-bridge/roxygen2/roxygen-ast");
|
|
11
|
+
const r_function_definition_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-definition");
|
|
12
|
+
const documentation_provider_1 = require("../../r-bridge/roxygen2/documentation-provider");
|
|
13
|
+
function getDocumentation(id, idMap) {
|
|
14
|
+
const comment = (0, documentation_provider_1.getDocumentationOf)(id, idMap);
|
|
15
|
+
if (comment === undefined) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
return Array.isArray(comment) ? comment : [comment];
|
|
19
|
+
}
|
|
20
|
+
function calculateArgumentDiff(inheritedParams, functionParam, roxygenParam) {
|
|
21
|
+
//match documented against existing params
|
|
22
|
+
let underDocumented = new Set(functionParam);
|
|
23
|
+
const notOverDocumented = underDocumented.has('...');
|
|
24
|
+
let overDocumented = new Set(roxygenParam);
|
|
25
|
+
const commonParams = underDocumented.intersection(overDocumented);
|
|
26
|
+
underDocumented = underDocumented.difference(commonParams);
|
|
27
|
+
overDocumented = overDocumented.difference(commonParams);
|
|
28
|
+
//case: '...', overdocumentation not possible
|
|
29
|
+
if (notOverDocumented) {
|
|
30
|
+
//if still remaining overdocumented parameters, "..." doesn't need to be documented
|
|
31
|
+
if (overDocumented.size > 0) {
|
|
32
|
+
underDocumented.delete('...');
|
|
33
|
+
}
|
|
34
|
+
//can't be overdocumented
|
|
35
|
+
overDocumented.clear();
|
|
36
|
+
}
|
|
37
|
+
//inherited params removed from list of overdocumented params
|
|
38
|
+
overDocumented = overDocumented.difference(new Set(inheritedParams));
|
|
39
|
+
return underDocumented.size === 0 && overDocumented.size === 0 ? false : { under: Array.from(underDocumented), over: Array.from(overDocumented) };
|
|
40
|
+
}
|
|
41
|
+
exports.ROXYGEN_ARGS = {
|
|
42
|
+
createSearch: () => flowr_search_builder_1.Q.all().filter(vertex_1.VertexType.FunctionDefinition),
|
|
43
|
+
processSearchResult: (elements, _config, { normalize }) => {
|
|
44
|
+
return {
|
|
45
|
+
results: elements.getElements()
|
|
46
|
+
.map(element => ({
|
|
47
|
+
element,
|
|
48
|
+
underDocumented: [],
|
|
49
|
+
overDocumented: []
|
|
50
|
+
}))
|
|
51
|
+
.filter(({ element: { node }, underDocumented, overDocumented }) => {
|
|
52
|
+
const comments = getDocumentation(node.info.id, normalize.idMap);
|
|
53
|
+
if (!comments) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
const parameters = getParameters(node);
|
|
57
|
+
//get parameter names
|
|
58
|
+
const functionParamNames = parameters.map(p => p.name.content.toString());
|
|
59
|
+
const inheritedParams = comments.filter(tag => (tag?.inherited && tag.type === roxygen_ast_1.KnownRoxygenTags.Param)).map(tag => (tag.value.name));
|
|
60
|
+
const roxygenParamNames = comments
|
|
61
|
+
.filter(tag => tag.type === roxygen_ast_1.KnownRoxygenTags.Param)
|
|
62
|
+
.map(tag => tag.value.name);
|
|
63
|
+
if (functionParamNames === null || roxygenParamNames == null) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const result = calculateArgumentDiff(inheritedParams, functionParamNames, roxygenParamNames);
|
|
67
|
+
if (result === false) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
underDocumented.push(...result.under);
|
|
71
|
+
overDocumented.push(...result.over);
|
|
72
|
+
return true;
|
|
73
|
+
})
|
|
74
|
+
.map(({ element, overDocumented, underDocumented }) => ({
|
|
75
|
+
certainty: linter_format_1.LintingResultCertainty.Uncertain,
|
|
76
|
+
involvedId: element.node.info.id,
|
|
77
|
+
loc: range_1.SourceLocation.fromNode(element.node),
|
|
78
|
+
underDocumented: underDocumented,
|
|
79
|
+
overDocumented: overDocumented
|
|
80
|
+
}))
|
|
81
|
+
.filter(element => (0, assert_1.isNotUndefined)(element.loc)),
|
|
82
|
+
'.meta': {}
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
prettyPrint: {
|
|
86
|
+
[linter_format_1.LintingPrettyPrintContext.Query]: result => `Code at ${range_1.SourceLocation.format(result.loc)}`,
|
|
87
|
+
[linter_format_1.LintingPrettyPrintContext.Full]: result => `Code at ${range_1.SourceLocation.format(result.loc)} has undocumented parameters: ${result.underDocumented?.join()} and overdocumented parameters: ${result.overDocumented?.join()}`
|
|
88
|
+
},
|
|
89
|
+
info: {
|
|
90
|
+
name: 'Roxygen Arguments',
|
|
91
|
+
tags: [linter_tags_1.LintingRuleTag.Smell, linter_tags_1.LintingRuleTag.Documentation, linter_tags_1.LintingRuleTag.Style],
|
|
92
|
+
certainty: linter_format_1.LintingRuleCertainty.BestEffort,
|
|
93
|
+
description: 'Checks whether a function has undocumented or overdocumented parameters',
|
|
94
|
+
defaultConfig: {}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
function getParameters(node) {
|
|
98
|
+
return r_function_definition_1.RFunctionDefinition.is(node) ? node.parameters : [];
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=roxygen-arguments.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eagleoutice/flowr",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.2",
|
|
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": {
|
|
@@ -175,7 +175,6 @@
|
|
|
175
175
|
"@types/command-line-usage": "^5.0.4",
|
|
176
176
|
"@types/commonmark": "^0.27.10",
|
|
177
177
|
"@types/dagre": "^0.7.53",
|
|
178
|
-
"@types/n-readlines": "^1.0.6",
|
|
179
178
|
"@types/n3": "^1.26.0",
|
|
180
179
|
"@types/object-hash": "^3.0.6",
|
|
181
180
|
"@types/object-path": "^0.11.4",
|
|
@@ -210,7 +209,7 @@
|
|
|
210
209
|
"gray-matter": "^4.0.3",
|
|
211
210
|
"joi": "^18.0.1",
|
|
212
211
|
"lz-string": "^1.5.0",
|
|
213
|
-
"n-readlines": "^
|
|
212
|
+
"n-readlines": "^3.4.1",
|
|
214
213
|
"n3": "^1.26.0",
|
|
215
214
|
"object-hash": "^3.0.0",
|
|
216
215
|
"object-path": "^0.11.8",
|
|
@@ -35,17 +35,12 @@ export interface ReadOnlyFlowrAnalyzerContext {
|
|
|
35
35
|
* The configuration options used by the analyzer.
|
|
36
36
|
*/
|
|
37
37
|
readonly config: FlowrConfig;
|
|
38
|
-
/**
|
|
39
|
-
* Run all resolution steps that can be done before the main analysis run.
|
|
40
|
-
*/
|
|
41
|
-
readonly resolvePreAnalysis: () => void;
|
|
42
38
|
}
|
|
43
39
|
/**
|
|
44
40
|
* This summarizes the other context layers used by the {@link FlowrAnalyzer}.
|
|
45
41
|
* Have a look at the attributes and layers listed below (e.g., {@link files} and {@link deps})
|
|
46
42
|
* to get an idea of the capabilities provided by this context.
|
|
47
|
-
* Besides these, this layer only orchestrates the different steps and layers, providing a collection of convenience methods
|
|
48
|
-
* {@link resolvePreAnalysis} method that conducts all the steps that can be done before the main analysis run.
|
|
43
|
+
* Besides these, this layer only orchestrates the different steps and layers, providing a collection of convenience methods.
|
|
49
44
|
* In general, you do not have to worry about these details, as the {@link FlowrAnalyzerBuilder} and {@link FlowrAnalyzer} take care of them.
|
|
50
45
|
*
|
|
51
46
|
* To inspect, e.g., the loading order, you can do so via {@link files.loadingOrder.getLoadingOrder}. To get information on a specific library, use
|
|
@@ -71,8 +66,6 @@ export declare class FlowrAnalyzerContext implements ReadOnlyFlowrAnalyzerContex
|
|
|
71
66
|
addRequests(requests: readonly RAnalysisRequest[]): void;
|
|
72
67
|
addFile(f: string | FlowrFileProvider | RParseRequestFromFile): void;
|
|
73
68
|
addFiles(f: (string | FlowrFileProvider | RParseRequestFromFile)[]): void;
|
|
74
|
-
/** this conducts all the step that can be done before the main analysis run */
|
|
75
|
-
resolvePreAnalysis(): void;
|
|
76
69
|
/**
|
|
77
70
|
* Get a read-only version of this context.
|
|
78
71
|
* This is useful if you want to pass the context to a place where you do not want it to be modified or just to reduce
|
|
@@ -18,8 +18,7 @@ const flowr_analyzer_meta_context_1 = require("./flowr-analyzer-meta-context");
|
|
|
18
18
|
* This summarizes the other context layers used by the {@link FlowrAnalyzer}.
|
|
19
19
|
* Have a look at the attributes and layers listed below (e.g., {@link files} and {@link deps})
|
|
20
20
|
* to get an idea of the capabilities provided by this context.
|
|
21
|
-
* Besides these, this layer only orchestrates the different steps and layers, providing a collection of convenience methods
|
|
22
|
-
* {@link resolvePreAnalysis} method that conducts all the steps that can be done before the main analysis run.
|
|
21
|
+
* Besides these, this layer only orchestrates the different steps and layers, providing a collection of convenience methods.
|
|
23
22
|
* In general, you do not have to worry about these details, as the {@link FlowrAnalyzerBuilder} and {@link FlowrAnalyzer} take care of them.
|
|
24
23
|
*
|
|
25
24
|
* To inspect, e.g., the loading order, you can do so via {@link files.loadingOrder.getLoadingOrder}. To get information on a specific library, use
|
|
@@ -63,11 +62,6 @@ class FlowrAnalyzerContext {
|
|
|
63
62
|
addFiles(f) {
|
|
64
63
|
this.files.addFiles(f);
|
|
65
64
|
}
|
|
66
|
-
/** this conducts all the step that can be done before the main analysis run */
|
|
67
|
-
resolvePreAnalysis() {
|
|
68
|
-
this.files.computeLoadingOrder();
|
|
69
|
-
this.deps.resolveStaticDependencies();
|
|
70
|
-
}
|
|
71
65
|
/**
|
|
72
66
|
* Get a read-only version of this context.
|
|
73
67
|
* This is useful if you want to pass the context to a place where you do not want it to be modified or just to reduce
|
|
@@ -28,6 +28,10 @@ export interface ReadOnlyFlowrAnalyzerEnvironmentContext {
|
|
|
28
28
|
* Create a new {@link REnvironmentInformation|environment} with an empty built-in environment as base.
|
|
29
29
|
*/
|
|
30
30
|
makeCleanEnvWithEmptyBuiltIns(): REnvironmentInformation;
|
|
31
|
+
/**
|
|
32
|
+
* A completely empty {@link REnvironmentInformation|environment}.
|
|
33
|
+
*/
|
|
34
|
+
makeEmptyEnv(): REnvironmentInformation;
|
|
31
35
|
}
|
|
32
36
|
/**
|
|
33
37
|
* This context is responsible for providing the built-in environment.
|
|
@@ -44,4 +48,5 @@ export declare class FlowrAnalyzerEnvironmentContext implements ReadOnlyFlowrAna
|
|
|
44
48
|
makeCleanEnv(): REnvironmentInformation;
|
|
45
49
|
getCleanEnvFingerprint(): Fingerprint;
|
|
46
50
|
makeCleanEnvWithEmptyBuiltIns(): REnvironmentInformation;
|
|
51
|
+
makeEmptyEnv(): REnvironmentInformation;
|
|
47
52
|
}
|
|
@@ -45,6 +45,12 @@ class FlowrAnalyzerEnvironmentContext {
|
|
|
45
45
|
level: 0
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
|
+
makeEmptyEnv() {
|
|
49
|
+
return {
|
|
50
|
+
current: new environment_1.Environment(undefined, true),
|
|
51
|
+
level: 0
|
|
52
|
+
};
|
|
53
|
+
}
|
|
48
54
|
}
|
|
49
55
|
exports.FlowrAnalyzerEnvironmentContext = FlowrAnalyzerEnvironmentContext;
|
|
50
56
|
//# sourceMappingURL=flowr-analyzer-environment-context.js.map
|
|
@@ -56,6 +56,11 @@ export interface ReadOnlyFlowrAnalyzerFilesContext {
|
|
|
56
56
|
* @returns An array of all files.
|
|
57
57
|
*/
|
|
58
58
|
getAllFiles(): FlowrFileProvider[];
|
|
59
|
+
/**
|
|
60
|
+
* Check if the context has a cached file with the given path.
|
|
61
|
+
* @param path - The path to the file.
|
|
62
|
+
*/
|
|
63
|
+
hasCached(path: string): boolean;
|
|
59
64
|
/**
|
|
60
65
|
* Check if the context has a file with the given path.
|
|
61
66
|
* Please note, that this may also check the file system, depending on the configuration
|
|
@@ -130,6 +135,7 @@ export declare class FlowrAnalyzerFilesContext extends AbstractFlowrAnalyzerCont
|
|
|
130
135
|
addFile(file: string | FlowrFileProvider | RParseRequestFromFile, roles?: readonly FileRole[]): FlowrFileProvider<{
|
|
131
136
|
toString(): string;
|
|
132
137
|
}>;
|
|
138
|
+
hasCached(path: string): boolean;
|
|
133
139
|
hasFile(path: string): boolean;
|
|
134
140
|
exists(p: string, ignoreCase: boolean): string | undefined;
|
|
135
141
|
private fileLoadPlugins;
|
|
@@ -120,9 +120,11 @@ class FlowrAnalyzerFilesContext extends abstract_flowr_analyzer_context_1.Abstra
|
|
|
120
120
|
}
|
|
121
121
|
return f;
|
|
122
122
|
}
|
|
123
|
+
hasCached(path) {
|
|
124
|
+
return this.files.has(path);
|
|
125
|
+
}
|
|
123
126
|
hasFile(path) {
|
|
124
|
-
return this.
|
|
125
|
-
|| (this.ctx.config.project.resolveUnknownPathsOnDisk && fs_1.default.existsSync(path));
|
|
127
|
+
return this.hasCached(path) || (this.ctx.config.project.resolveUnknownPathsOnDisk && fs_1.default.existsSync(path));
|
|
126
128
|
}
|
|
127
129
|
exists(p, ignoreCase) {
|
|
128
130
|
try {
|
|
@@ -157,10 +157,7 @@ class FlowrAnalyzerBuilder {
|
|
|
157
157
|
context,
|
|
158
158
|
...(this.input ?? {})
|
|
159
159
|
});
|
|
160
|
-
|
|
161
|
-
// we do it here to save time later if the analyzer is to be duplicated
|
|
162
|
-
context.resolvePreAnalysis();
|
|
163
|
-
return analyzer;
|
|
160
|
+
return new flowr_analyzer_1.FlowrAnalyzer(this.parser, context, cache);
|
|
164
161
|
}
|
|
165
162
|
}
|
|
166
163
|
exports.FlowrAnalyzerBuilder = FlowrAnalyzerBuilder;
|
|
@@ -2,7 +2,7 @@ import type { CallContextQuery, CallContextQueryResult, CallNameTypes, LinkTo }
|
|
|
2
2
|
import type { BasicQueryData } from '../../base-query-format';
|
|
3
3
|
export type PromotedCallTest = (t: string) => boolean;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Convert a name to a predicate that checks whether an input conforms to this name.
|
|
6
6
|
*/
|
|
7
7
|
export declare function promoteCallName(callName: CallNameTypes, exact?: boolean): PromotedCallTest;
|
|
8
8
|
export type PromotedLinkTo<LT = LinkTo> = Omit<LT, 'callName'> & {
|
|
@@ -44,19 +44,24 @@ function isSubCallQuery(query) {
|
|
|
44
44
|
return 'linkTo' in query && query.linkTo !== undefined;
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
47
|
+
* Convert a name to a predicate that checks whether an input conforms to this name.
|
|
48
48
|
*/
|
|
49
49
|
function promoteCallName(callName, exact = false) {
|
|
50
50
|
if (Array.isArray(callName)) {
|
|
51
51
|
const s = new Set(callName);
|
|
52
52
|
return (t) => s.has(t);
|
|
53
53
|
}
|
|
54
|
-
else if (
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
else if (typeof callName === 'string') {
|
|
55
|
+
if (exact) {
|
|
56
|
+
return (t) => t === callName;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
const r = new RegExp(callName);
|
|
60
|
+
return (t) => r.test(t);
|
|
61
|
+
}
|
|
57
62
|
}
|
|
58
63
|
else {
|
|
59
|
-
const r = new RegExp(callName);
|
|
64
|
+
const r = new RegExp(exact ? '^' + callName.source + '$' : callName.source);
|
|
60
65
|
return (t) => r.test(t);
|
|
61
66
|
}
|
|
62
67
|
}
|
|
@@ -24,7 +24,7 @@ export interface DefaultCallContextQueryFormat<RegexType extends CallNameTypes>
|
|
|
24
24
|
readonly type: 'call-context';
|
|
25
25
|
/** Regex regarding the function name, please note that strings will be interpreted as regular expressions too! */
|
|
26
26
|
readonly callName: RegexType;
|
|
27
|
-
/** Should we automatically add the `^` and `$` anchors to the regex to make it an exact match? */
|
|
27
|
+
/** Should we automatically add the `^` and `$` anchors to the regex to make it an exact match, we now also allow '.' etc. to have their conventional meaning if you pass in the regex as a string? */
|
|
28
28
|
readonly callNameExact?: boolean;
|
|
29
29
|
/** kind may be a step or anything that you attach to the call, this can be used to group calls together (e.g., linking `ggplot` to `visualize`). Defaults to `.` */
|
|
30
30
|
readonly kind?: string;
|
|
@@ -7,6 +7,7 @@ exports.LibraryFunctions = [
|
|
|
7
7
|
{ package: 'base', name: 'loadNamespace', argIdx: 0, argName: 'package', resolveValue: true },
|
|
8
8
|
{ package: 'base', name: 'attachNamespace', argIdx: 0, argName: 'ns', resolveValue: true },
|
|
9
9
|
{ package: 'base', name: 'attach', argIdx: 0, argName: 'what', resolveValue: true },
|
|
10
|
+
{ package: 'base', name: 'use', argIdx: 0, argName: 'package', resolveValue: 'library' },
|
|
10
11
|
{ package: 'groundhog', name: 'groundhog.library', argIdx: 0, argName: 'pkg', resolveValue: true },
|
|
11
12
|
{ package: 'pacman', name: 'p_load', argIdx: 'unnamed', resolveValue: 'library' },
|
|
12
13
|
{ package: 'pacman', name: 'p_load_gh', argIdx: 'unnamed', resolveValue: 'library' },
|
|
@@ -15,5 +16,6 @@ exports.LibraryFunctions = [
|
|
|
15
16
|
{ package: 'librarian', name: 'shelf', argIdx: 'unnamed', resolveValue: true },
|
|
16
17
|
{ package: 'devtools', name: 'load_all', argIdx: 0, argName: 'path', resolveValue: true, defaultValue: '.' },
|
|
17
18
|
{ package: 'devtools', name: 'load_code', argIdx: 0, argName: 'path', resolveValue: true, defaultValue: '.' },
|
|
19
|
+
{ package: 'import', name: 'from', argIdx: 0, argName: 'package', resolveValue: true }
|
|
18
20
|
];
|
|
19
21
|
//# sourceMappingURL=library-functions.js.map
|
|
@@ -5,11 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.DfShapeQueryDefinition = void 0;
|
|
7
7
|
const joi_1 = __importDefault(require("joi"));
|
|
8
|
+
const abstract_domain_1 = require("../../../abstract-interpretation/domains/abstract-domain");
|
|
9
|
+
const lattice_1 = require("../../../abstract-interpretation/domains/lattice");
|
|
8
10
|
const slice_query_parser_1 = require("../../../cli/repl/parser/slice-query-parser");
|
|
9
11
|
const ansi_1 = require("../../../util/text/ansi");
|
|
10
12
|
const time_1 = require("../../../util/text/time");
|
|
11
13
|
const df_shape_query_executor_1 = require("./df-shape-query-executor");
|
|
12
|
-
const abstract_domain_1 = require("../../../abstract-interpretation/domains/abstract-domain");
|
|
13
14
|
function dfShapeQueryLineParser(_output, line, _config) {
|
|
14
15
|
const criterion = (0, slice_query_parser_1.sliceCriterionParser)(line[0]);
|
|
15
16
|
return {
|
|
@@ -26,6 +27,10 @@ exports.DfShapeQueryDefinition = {
|
|
|
26
27
|
const out = queryResults;
|
|
27
28
|
const domains = out.domains instanceof abstract_domain_1.AbstractDomain ? out.domains.value : out.domains;
|
|
28
29
|
result.push(`Query: ${(0, ansi_1.bold)('df-shape', formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
|
|
30
|
+
if (domains === lattice_1.Bottom) {
|
|
31
|
+
result.push(` ╰ state: ${lattice_1.BottomSymbol}`);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
29
34
|
result.push(...domains.entries().take(20).map(([key, domain]) => {
|
|
30
35
|
return ` ╰ ${key}: ${domain?.toString()}`;
|
|
31
36
|
}));
|
|
@@ -37,7 +42,7 @@ exports.DfShapeQueryDefinition = {
|
|
|
37
42
|
jsonFormatter: (queryResults) => {
|
|
38
43
|
const { domains, ...out } = queryResults;
|
|
39
44
|
const state = domains instanceof abstract_domain_1.AbstractDomain ? domains.value : domains;
|
|
40
|
-
const json = Object.fromEntries(state.entries().map(([key, domain]) => [key, domain?.toJson() ?? null]));
|
|
45
|
+
const json = state === lattice_1.Bottom ? state.description : Object.fromEntries(state.entries().map(([key, domain]) => [key, domain?.toJson() ?? null]));
|
|
41
46
|
const result = { domains: json, ...out };
|
|
42
47
|
return result;
|
|
43
48
|
},
|
|
@@ -6,7 +6,6 @@ exports.executeFileQuery = executeFileQuery;
|
|
|
6
6
|
*/
|
|
7
7
|
function executeFileQuery({ analyzer }, queries) {
|
|
8
8
|
const start = Date.now();
|
|
9
|
-
analyzer.inspectContext().resolvePreAnalysis();
|
|
10
9
|
const base = analyzer.inspectContext().files.getAllFiles();
|
|
11
10
|
let files = [];
|
|
12
11
|
const foundFingerprints = new Set();
|
|
@@ -4,6 +4,8 @@ import type { MergeableRecord } from '../../../util/objects';
|
|
|
4
4
|
import { Identifier } from '../../../dataflow/environments/identifier';
|
|
5
5
|
/**
|
|
6
6
|
* Lattice flattening until we have a taint engine :)
|
|
7
|
+
* Please note that the classifier considers this basis with a set-lift,
|
|
8
|
+
* joining differing lattice elements.
|
|
7
9
|
*
|
|
8
10
|
*```
|
|
9
11
|
* [ Unknown ]
|
package/r-bridge/data/data.d.ts
CHANGED
|
@@ -422,9 +422,9 @@ export declare const flowrCapabilities: {
|
|
|
422
422
|
readonly description: "_Handle `&&`, `||`, ..._";
|
|
423
423
|
}, {
|
|
424
424
|
readonly name: "Pipe and Pipe-Bind";
|
|
425
|
-
readonly id: "
|
|
425
|
+
readonly id: "pipe-and-pipe-bind";
|
|
426
426
|
readonly supported: "partially";
|
|
427
|
-
readonly description: "_Handle the [new (4.1) pipe and pipe-bind syntax](https://www.r-bloggers.com/2021/05/the-new-r-pipe/): `|>`, and `=>`._
|
|
427
|
+
readonly description: "_Handle the [new (4.1) pipe and pipe-bind syntax](https://www.r-bloggers.com/2021/05/the-new-r-pipe/): `|>`, and `=>`._; Similarly support the other pipe binds";
|
|
428
428
|
}, {
|
|
429
429
|
readonly name: "Sequencing";
|
|
430
430
|
readonly id: "built-in-sequencing";
|
package/r-bridge/data/data.js
CHANGED
|
@@ -537,9 +537,9 @@ ${await (0, doc_dfg_1.printDfGraphForCode)(parser, code, { simplified: true })}
|
|
|
537
537
|
},
|
|
538
538
|
{
|
|
539
539
|
name: 'Pipe and Pipe-Bind',
|
|
540
|
-
id: '
|
|
540
|
+
id: 'pipe-and-pipe-bind',
|
|
541
541
|
supported: 'partially',
|
|
542
|
-
description: '_Handle the [new (4.1) pipe and pipe-bind syntax](https://www.r-bloggers.com/2021/05/the-new-r-pipe/): `|>`, and `=>`._
|
|
542
|
+
description: '_Handle the [new (4.1) pipe and pipe-bind syntax](https://www.r-bloggers.com/2021/05/the-new-r-pipe/): `|>`, and `=>`._; Similarly support the other pipe binds'
|
|
543
543
|
},
|
|
544
544
|
{
|
|
545
545
|
name: 'Sequencing',
|
|
@@ -4,7 +4,7 @@ import { RType } from '../type';
|
|
|
4
4
|
import type { RSymbol } from './r-symbol';
|
|
5
5
|
import type { ParentInformation } from '../processing/decorate';
|
|
6
6
|
import type { NodeId } from '../processing/node-id';
|
|
7
|
-
import type {
|
|
7
|
+
import type { PotentiallyEmptyRArgument } from './r-function-call';
|
|
8
8
|
import { EmptyArgument } from './r-function-call';
|
|
9
9
|
import type { BrandedIdentifier } from '../../../../../dataflow/environments/identifier';
|
|
10
10
|
/**
|
|
@@ -33,27 +33,35 @@ export declare const RArgument: {
|
|
|
33
33
|
* @see {@link RArgument.isUnnamed} - to check whether an argument is unnamed
|
|
34
34
|
*/
|
|
35
35
|
readonly is: <Info = object>(this: void, node: RNode<Info> | undefined) => node is RArgument<Info>;
|
|
36
|
+
/**
|
|
37
|
+
* Type guard for arguments that are empty, i.e. {@link EmptyArgument}.
|
|
38
|
+
*/
|
|
39
|
+
readonly isEmpty: <Info = object>(this: void, node: RNode<Info> | typeof EmptyArgument | undefined) => node is typeof EmptyArgument;
|
|
40
|
+
/**
|
|
41
|
+
* Type guard for arguments that are _not_ empty, i.e. _not_ {@link EmptyArgument}.
|
|
42
|
+
*/
|
|
43
|
+
readonly isNotEmpty: <Info = object>(this: void, node: RNode<Info> | typeof EmptyArgument | undefined) => node is RArgument<Info>;
|
|
36
44
|
/**
|
|
37
45
|
* Type guard for named arguments, i.e. arguments with a name.
|
|
38
46
|
*/
|
|
39
|
-
readonly isNamed: <Info = object>(this: void, node: RNode<Info> | undefined) => node is RArgument<Info> & {
|
|
47
|
+
readonly isNamed: <Info = object>(this: void, node: RNode<Info> | typeof EmptyArgument | undefined) => node is RArgument<Info> & {
|
|
40
48
|
name: RSymbol<Info, BrandedIdentifier>;
|
|
41
49
|
};
|
|
42
50
|
/**
|
|
43
51
|
* Type guard for unnamed arguments, i.e. arguments without a name.
|
|
44
52
|
*/
|
|
45
|
-
readonly isUnnamed: <Info = object>(this: void, node: RNode<Info> | undefined) => node is RUnnamedArgument<Info>;
|
|
53
|
+
readonly isUnnamed: <Info = object>(this: void, node: RNode<Info> | typeof EmptyArgument | undefined) => node is RUnnamedArgument<Info>;
|
|
46
54
|
/**
|
|
47
55
|
* Type guard for arguments with a value, i.e. arguments that are not just placeholders without a value.
|
|
48
56
|
*/
|
|
49
57
|
readonly isWithValue: <Info = object>(this: void, node: RNode<Info> | undefined) => node is RArgument<Info> & {
|
|
50
58
|
value: RNode<Info>;
|
|
51
59
|
};
|
|
52
|
-
readonly getWithId: <OtherInfo>(args: readonly
|
|
60
|
+
readonly getWithId: <OtherInfo>(args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], id: NodeId | undefined) => Exclude<PotentiallyEmptyRArgument<OtherInfo & ParentInformation>, typeof EmptyArgument> | undefined;
|
|
53
61
|
/**
|
|
54
62
|
* Retrieve the value of the argument with the given id from the list of arguments.
|
|
55
63
|
*/
|
|
56
|
-
readonly getValue: <OtherInfo>(args: readonly
|
|
64
|
+
readonly getValue: <OtherInfo>(args: readonly PotentiallyEmptyRArgument<OtherInfo & ParentInformation>[], id: NodeId | undefined) => RNode<OtherInfo> | undefined;
|
|
57
65
|
readonly getLocation: (this: void, node: RNode) => import("../../../../../util/range").SourceLocation | undefined;
|
|
58
66
|
readonly getId: (this: void, node: RNode<ParentInformation>) => NodeId;
|
|
59
67
|
readonly getType: (this: void, node: RNode) => RType;
|
|
@@ -17,17 +17,29 @@ exports.RArgument = {
|
|
|
17
17
|
is(node) {
|
|
18
18
|
return node?.type === type_1.RType.Argument;
|
|
19
19
|
},
|
|
20
|
+
/**
|
|
21
|
+
* Type guard for arguments that are empty, i.e. {@link EmptyArgument}.
|
|
22
|
+
*/
|
|
23
|
+
isEmpty(node) {
|
|
24
|
+
return node === r_function_call_1.EmptyArgument;
|
|
25
|
+
},
|
|
26
|
+
/**
|
|
27
|
+
* Type guard for arguments that are _not_ empty, i.e. _not_ {@link EmptyArgument}.
|
|
28
|
+
*/
|
|
29
|
+
isNotEmpty(node) {
|
|
30
|
+
return node !== r_function_call_1.EmptyArgument && exports.RArgument.is(node);
|
|
31
|
+
},
|
|
20
32
|
/**
|
|
21
33
|
* Type guard for named arguments, i.e. arguments with a name.
|
|
22
34
|
*/
|
|
23
35
|
isNamed(node) {
|
|
24
|
-
return exports.RArgument.is(node) && node.name !== undefined;
|
|
36
|
+
return node !== r_function_call_1.EmptyArgument && exports.RArgument.is(node) && node.name !== undefined;
|
|
25
37
|
},
|
|
26
38
|
/**
|
|
27
39
|
* Type guard for unnamed arguments, i.e. arguments without a name.
|
|
28
40
|
*/
|
|
29
41
|
isUnnamed(node) {
|
|
30
|
-
return exports.RArgument.is(node) && node.name === undefined && node.value !== undefined;
|
|
42
|
+
return node !== r_function_call_1.EmptyArgument && exports.RArgument.is(node) && node.name === undefined && node.value !== undefined;
|
|
31
43
|
},
|
|
32
44
|
/**
|
|
33
45
|
* Type guard for arguments with a value, i.e. arguments that are not just placeholders without a value.
|
|
@@ -4,7 +4,7 @@ import { RType } from '../type';
|
|
|
4
4
|
import type { RSymbol } from './r-symbol';
|
|
5
5
|
import type { RArgument } from './r-argument';
|
|
6
6
|
export declare const EmptyArgument = "<>";
|
|
7
|
-
export type
|
|
7
|
+
export type PotentiallyEmptyRArgument<Info = NoInfo> = RArgument<Info> | typeof EmptyArgument;
|
|
8
8
|
/**
|
|
9
9
|
* Calls of functions like `a()` and `foo(42, "hello")`.
|
|
10
10
|
* @see RUnnamedFunctionCall
|
|
@@ -14,7 +14,7 @@ export interface RNamedFunctionCall<Info = NoInfo> extends RAstNodeBase<Info>, L
|
|
|
14
14
|
readonly named: true;
|
|
15
15
|
functionName: RSymbol<Info>;
|
|
16
16
|
/** arguments can be empty, for example when calling as `a(1, ,3)` */
|
|
17
|
-
readonly arguments: readonly
|
|
17
|
+
readonly arguments: readonly PotentiallyEmptyRArgument<Info>[];
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* Direct calls of functions like `(function(x) { x })(3)`.
|
|
@@ -27,7 +27,7 @@ export interface RUnnamedFunctionCall<Info = NoInfo> extends RAstNodeBase<Info>,
|
|
|
27
27
|
/** marks function calls like `3 %xx% 4` which have been written in special infix notation; deprecated in v2 */
|
|
28
28
|
infixSpecial?: boolean;
|
|
29
29
|
/** arguments can be undefined, for example when calling as `a(1, ,3)` */
|
|
30
|
-
readonly arguments: readonly
|
|
30
|
+
readonly arguments: readonly PotentiallyEmptyRArgument<Info>[];
|
|
31
31
|
}
|
|
32
32
|
export type RFunctionCall<Info = NoInfo> = RNamedFunctionCall<Info> | RUnnamedFunctionCall<Info>;
|
|
33
33
|
/**
|
|
@@ -23,6 +23,15 @@ export declare const RPipe: {
|
|
|
23
23
|
* Returns the minimum R version that supports the pipe operator.
|
|
24
24
|
*/
|
|
25
25
|
readonly availableFromRVersion: (this: void) => SemVer;
|
|
26
|
+
/**
|
|
27
|
+
* Returns the minimum R version that supports using the placeholder like '_'.
|
|
28
|
+
*/
|
|
29
|
+
readonly hasPlaceHolderFromRVersion: (this: void) => SemVer;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the minimum R version that supports using the placeholder like '_' in access
|
|
32
|
+
* patterns: `_$a`
|
|
33
|
+
*/
|
|
34
|
+
readonly hasAccessPlaceHolderFromRVersion: (this: void) => SemVer;
|
|
26
35
|
readonly getLocation: (this: void, node: RNode) => import("../../../../../util/range").SourceLocation | undefined;
|
|
27
36
|
readonly getId: (this: void, node: RNode<import("../processing/decorate").ParentInformation>) => import("../processing/node-id").NodeId;
|
|
28
37
|
readonly getType: (this: void, node: RNode) => RType;
|
|
@@ -23,5 +23,18 @@ exports.RPipe = {
|
|
|
23
23
|
availableFromRVersion() {
|
|
24
24
|
return new semver_1.SemVer(versions_1.MIN_VERSION_PIPE);
|
|
25
25
|
},
|
|
26
|
+
/**
|
|
27
|
+
* Returns the minimum R version that supports using the placeholder like '_'.
|
|
28
|
+
*/
|
|
29
|
+
hasPlaceHolderFromRVersion() {
|
|
30
|
+
return new semver_1.SemVer(versions_1.MIN_VERSION_PIPE_PLACEHOLDER);
|
|
31
|
+
},
|
|
32
|
+
/**
|
|
33
|
+
* Returns the minimum R version that supports using the placeholder like '_' in access
|
|
34
|
+
* patterns: `_$a`
|
|
35
|
+
*/
|
|
36
|
+
hasAccessPlaceHolderFromRVersion() {
|
|
37
|
+
return new semver_1.SemVer(versions_1.MIN_VERSION_PIPE_PLACEHOLDER_EXTRACT);
|
|
38
|
+
}
|
|
26
39
|
};
|
|
27
40
|
//# sourceMappingURL=r-pipe.js.map
|
|
@@ -4,5 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export declare const MIN_VERSION_PIPE = "4.1.0";
|
|
6
6
|
export declare const MIN_VERSION_LAMBDA = "4.1.0";
|
|
7
|
+
export declare const MIN_VERSION_PIPE_PLACEHOLDER = "4.2.0";
|
|
8
|
+
export declare const MIN_VERSION_PIPE_PLACEHOLDER_EXTRACT = "4.3.0";
|
|
7
9
|
/** between 4.0.0 and (i think) 4.1.0 the parser handled them differently. We ignore that for now. */
|
|
8
10
|
export declare const MIN_VERSION_RAW_STABLE = "4.1.0";
|
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.MIN_VERSION_RAW_STABLE = exports.MIN_VERSION_LAMBDA = exports.MIN_VERSION_PIPE = void 0;
|
|
7
|
+
exports.MIN_VERSION_RAW_STABLE = exports.MIN_VERSION_PIPE_PLACEHOLDER_EXTRACT = exports.MIN_VERSION_PIPE_PLACEHOLDER = exports.MIN_VERSION_LAMBDA = exports.MIN_VERSION_PIPE = void 0;
|
|
8
8
|
exports.MIN_VERSION_PIPE = '4.1.0';
|
|
9
9
|
exports.MIN_VERSION_LAMBDA = '4.1.0';
|
|
10
|
+
exports.MIN_VERSION_PIPE_PLACEHOLDER = '4.2.0';
|
|
11
|
+
exports.MIN_VERSION_PIPE_PLACEHOLDER_EXTRACT = '4.3.0';
|
|
10
12
|
/** between 4.0.0 and (i think) 4.1.0 the parser handled them differently. We ignore that for now. */
|
|
11
13
|
exports.MIN_VERSION_RAW_STABLE = '4.1.0';
|
|
12
14
|
//# sourceMappingURL=versions.js.map
|
|
@@ -85,30 +85,39 @@ function getDocumentationOfByName(name, idMap) {
|
|
|
85
85
|
return getDocumentationOf(node.info.id, idMap);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
function
|
|
88
|
+
function filterDocumentationForParamsInherited(doc, filter) {
|
|
89
89
|
if (!doc) {
|
|
90
90
|
return doc;
|
|
91
91
|
}
|
|
92
92
|
if (Array.isArray(doc)) {
|
|
93
|
-
|
|
93
|
+
const ds = doc.filter(filter);
|
|
94
|
+
for (const d of ds) {
|
|
95
|
+
d.inherited = true;
|
|
96
|
+
}
|
|
97
|
+
return ds;
|
|
94
98
|
}
|
|
95
99
|
else {
|
|
96
|
-
|
|
100
|
+
const d = doc;
|
|
101
|
+
if (filter(d)) {
|
|
102
|
+
d.inherited = true;
|
|
103
|
+
return d;
|
|
104
|
+
}
|
|
105
|
+
return undefined;
|
|
97
106
|
}
|
|
98
107
|
}
|
|
99
108
|
function expandInheritOfTag(tag, otherTags, idMap) {
|
|
100
109
|
if (tag.type === roxygen_ast_1.KnownRoxygenTags.Inherit) {
|
|
101
110
|
const inheritDoc = getDocumentationOfByName(tag.value.source, idMap);
|
|
102
|
-
return
|
|
111
|
+
return filterDocumentationForParamsInherited(inheritDoc, t => tag.value.components.includes(t.type));
|
|
103
112
|
}
|
|
104
113
|
else if (tag.type === roxygen_ast_1.KnownRoxygenTags.InheritDotParams) {
|
|
105
114
|
const inheritDoc = getDocumentationOfByName(tag.value.source, idMap);
|
|
106
|
-
return
|
|
115
|
+
return filterDocumentationForParamsInherited(inheritDoc, t => t.type === roxygen_ast_1.KnownRoxygenTags.Param && t.value.name === '...');
|
|
107
116
|
}
|
|
108
117
|
else if (tag.type === roxygen_ast_1.KnownRoxygenTags.InheritParams) {
|
|
109
118
|
const inheritDoc = getDocumentationOfByName(tag.value, idMap);
|
|
110
119
|
const alreadyExplainedParams = new Set(otherTags.filter(t => t.type === roxygen_ast_1.KnownRoxygenTags.Param).map(t => t.value.name));
|
|
111
|
-
return
|
|
120
|
+
return filterDocumentationForParamsInherited(inheritDoc, t => t.type === roxygen_ast_1.KnownRoxygenTags.Param && !alreadyExplainedParams.has(t.value.name));
|
|
112
121
|
}
|
|
113
122
|
return tag;
|
|
114
123
|
}
|