@eagleoutice/flowr 2.9.14 → 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 +52 -29
- 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/benchmark/stats/stats.d.ts +2 -2
- package/cli/flowr.js +1 -1
- package/cli/repl/parser/slice-query-parser.d.ts +2 -2
- package/config.d.ts +4 -0
- package/config.js +5 -3
- 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/identifier.d.ts +4 -0
- package/dataflow/environments/identifier.js +17 -0
- package/dataflow/environments/overwrite.js +2 -5
- package/dataflow/graph/call-graph.d.ts +4 -7
- package/dataflow/graph/call-graph.js +0 -22
- package/dataflow/graph/df-helper.d.ts +23 -12
- package/dataflow/graph/df-helper.js +44 -7
- package/dataflow/graph/graph-helper.d.ts +9 -4
- package/dataflow/graph/graph-helper.js +26 -3
- package/dataflow/graph/graph.d.ts +23 -2
- package/dataflow/graph/graph.js +38 -4
- package/dataflow/graph/vertex.d.ts +2 -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-apply.js +1 -0
- 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-assignment.js +1 -1
- 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-for-loop.js +1 -1
- 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 +8 -19
- 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 +6 -4
- 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/dataflow/internal/process/functions/process-parameter.js +1 -1
- package/documentation/doc-readme.js +2 -1
- package/documentation/wiki-absint.js +6 -5
- package/documentation/wiki-analyzer.js +0 -2
- package/documentation/wiki-linter.js +6 -0
- package/documentation/wiki-normalized-ast.js +7 -7
- package/linter/linter-rules.d.ts +49 -1
- package/linter/linter-rules.js +5 -1
- package/linter/rules/dataframe-access-validation.d.ts +1 -1
- package/linter/rules/dataframe-access-validation.js +3 -4
- package/linter/rules/problematic-eval.d.ts +44 -0
- package/linter/rules/problematic-eval.js +83 -0
- package/linter/rules/roxygen-arguments.d.ts +35 -0
- package/linter/rules/roxygen-arguments.js +100 -0
- package/package.json +8 -9
- 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-executor.js +1 -1
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +3 -3
- package/queries/catalog/df-shape-query/df-shape-query-format.js +7 -2
- package/queries/catalog/does-call-query/does-call-query-executor.js +1 -1
- package/queries/catalog/does-call-query/does-call-query-format.d.ts +2 -2
- package/queries/catalog/files-query/files-query-executor.js +0 -1
- package/queries/catalog/happens-before-query/happens-before-query-executor.js +2 -2
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +3 -3
- package/queries/catalog/input-sources-query/input-sources-query-executor.d.ts +6 -0
- package/queries/catalog/input-sources-query/input-sources-query-executor.js +66 -0
- package/queries/catalog/input-sources-query/input-sources-query-format.d.ts +36 -0
- package/queries/catalog/input-sources-query/input-sources-query-format.js +63 -0
- package/queries/catalog/input-sources-query/simple-input-classifier.d.ts +92 -0
- package/queries/catalog/input-sources-query/simple-input-classifier.js +310 -0
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.d.ts +2 -2
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-executor.js +1 -1
- package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.d.ts +2 -2
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +1 -1
- package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +2 -2
- package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.d.ts +2 -2
- package/queries/catalog/location-map-query/location-map-query-executor.js +1 -1
- package/queries/catalog/location-map-query/location-map-query-format.d.ts +2 -2
- package/queries/catalog/origin-query/origin-query-executor.d.ts +2 -2
- package/queries/catalog/origin-query/origin-query-executor.js +1 -1
- package/queries/catalog/origin-query/origin-query-format.d.ts +3 -3
- package/queries/catalog/provenance-query/provenance-query-executor.d.ts +1 -4
- package/queries/catalog/provenance-query/provenance-query-executor.js +3 -6
- package/queries/catalog/provenance-query/provenance-query-format.d.ts +2 -2
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +1 -1
- package/queries/query.d.ts +9 -1
- package/queries/query.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/model.d.ts +3 -0
- package/r-bridge/lang-4.x/ast/model/model.js +3 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-access.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.d.ts +29 -6
- package/r-bridge/lang-4.x/ast/model/nodes/r-argument.js +16 -2
- package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-binary-op.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.d.ts +15 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-break.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.d.ts +15 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-comment.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-expression-list.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-for-loop.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.d.ts +19 -4
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-call.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.d.ts +21 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-function-definition.js +16 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-if-then-else.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-line-directive.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-logical.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-next.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-number.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-parameter.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.d.ts +25 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-pipe.js +15 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-string.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-symbol.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-unary-op.js +2 -0
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.d.ts +16 -1
- package/r-bridge/lang-4.x/ast/model/nodes/r-while-loop.js +2 -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/search/search-executor/search-generators.js +1 -1
- package/slicing/criterion/parse.d.ts +11 -10
- package/slicing/criterion/parse.js +9 -8
- package/slicing/static/static-slicer.js +24 -1
- package/util/collections/arrays.d.ts +4 -0
- package/util/collections/arrays.js +7 -0
- package/util/mermaid/ast.js +2 -1
- package/util/mermaid/dfg.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.
|
|
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": {
|
|
@@ -165,8 +165,8 @@
|
|
|
165
165
|
}
|
|
166
166
|
},
|
|
167
167
|
"devDependencies": {
|
|
168
|
-
"@commitlint/cli": "^
|
|
169
|
-
"@commitlint/config-angular": "^
|
|
168
|
+
"@commitlint/cli": "^20.5.0",
|
|
169
|
+
"@commitlint/config-angular": "^20.5.0",
|
|
170
170
|
"@eagleoutice/eslint-config-flowr": "^1.0.36",
|
|
171
171
|
"@eslint/eslintrc": "^3.3.3",
|
|
172
172
|
"@eslint/js": "^9.39.2",
|
|
@@ -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",
|
|
@@ -191,11 +190,11 @@
|
|
|
191
190
|
"npm-run-all": "^4.1.5",
|
|
192
191
|
"release-it": "^19.2.3",
|
|
193
192
|
"ts-node": "^10.9.2",
|
|
194
|
-
"typedoc": "^0.
|
|
195
|
-
"typedoc-plugin-missing-exports": "^
|
|
196
|
-
"typedoc-theme-hierarchy": "^
|
|
193
|
+
"typedoc": "^0.28.17",
|
|
194
|
+
"typedoc-plugin-missing-exports": "^4.1.2",
|
|
195
|
+
"typedoc-theme-hierarchy": "^6.0.0",
|
|
197
196
|
"typedoc-umlclass": "^0.10.2",
|
|
198
|
-
"typescript": "^5.
|
|
197
|
+
"typescript": "^5.9.3",
|
|
199
198
|
"vitest": "^3.2.4"
|
|
200
199
|
},
|
|
201
200
|
"dependencies": {
|
|
@@ -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
|
|
@@ -39,7 +39,7 @@ async function executeDfShapeQuery({ analyzer }, queries) {
|
|
|
39
39
|
continue;
|
|
40
40
|
}
|
|
41
41
|
try {
|
|
42
|
-
const nodeId = parse_1.
|
|
42
|
+
const nodeId = parse_1.SlicingCriterion.parse(query.criterion, ast.idMap);
|
|
43
43
|
const node = ast.idMap.get(nodeId);
|
|
44
44
|
const value = inference.getAbstractValue(node?.info.id);
|
|
45
45
|
result.set(query.criterion, value);
|
|
@@ -3,17 +3,17 @@ import type { DataFrameDomain } from '../../../abstract-interpretation/data-fram
|
|
|
3
3
|
import type { StateAbstractDomain } from '../../../abstract-interpretation/domains/state-abstract-domain';
|
|
4
4
|
import type { ReplOutput } from '../../../cli/repl/commands/repl-main';
|
|
5
5
|
import type { FlowrConfig } from '../../../config';
|
|
6
|
-
import type {
|
|
6
|
+
import type { SlicingCriterion } from '../../../slicing/criterion/parse';
|
|
7
7
|
import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
|
|
8
8
|
import type { ParsedQueryLine } from '../../query';
|
|
9
9
|
import { executeDfShapeQuery } from './df-shape-query-executor';
|
|
10
10
|
/** Infer the shape of data frames using abstract interpretation. */
|
|
11
11
|
export interface DfShapeQuery extends BaseQueryFormat {
|
|
12
12
|
readonly type: 'df-shape';
|
|
13
|
-
readonly criterion?:
|
|
13
|
+
readonly criterion?: SlicingCriterion;
|
|
14
14
|
}
|
|
15
15
|
export interface DfShapeQueryResult extends BaseQueryResult {
|
|
16
|
-
domains: StateAbstractDomain<DataFrameDomain> | Map<
|
|
16
|
+
domains: StateAbstractDomain<DataFrameDomain> | Map<SlicingCriterion, DataFrameDomain | undefined>;
|
|
17
17
|
}
|
|
18
18
|
declare function dfShapeQueryLineParser(_output: ReplOutput, line: readonly string[], _config: FlowrConfig): ParsedQueryLine<'df-shape'>;
|
|
19
19
|
export declare const DfShapeQueryDefinition: {
|
|
@@ -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
|
},
|
|
@@ -19,7 +19,7 @@ async function executeDoesCallQuery({ analyzer }, queries) {
|
|
|
19
19
|
log_1.log.warn(`Duplicate query id '${id}' in does-call queries, SKIP.`);
|
|
20
20
|
continue;
|
|
21
21
|
}
|
|
22
|
-
const nodeId = parse_1.
|
|
22
|
+
const nodeId = parse_1.SlicingCriterion.tryParse(query.call, idMap);
|
|
23
23
|
if (!nodeId) {
|
|
24
24
|
results[id] = false;
|
|
25
25
|
continue;
|
|
@@ -3,7 +3,7 @@ import Joi from 'joi';
|
|
|
3
3
|
import type { ParsedQueryLine } from '../../query';
|
|
4
4
|
import { executeDoesCallQuery } from './does-call-query-executor';
|
|
5
5
|
import { type NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
6
|
-
import type {
|
|
6
|
+
import type { SlicingCriterion } from '../../../slicing/criterion/parse';
|
|
7
7
|
import type { ReplOutput } from '../../../cli/repl/commands/repl-main';
|
|
8
8
|
import type { FlowrConfig } from '../../../config';
|
|
9
9
|
interface CallsIdConstraint {
|
|
@@ -30,7 +30,7 @@ export type CallsConstraint = CallsIdConstraint | CallsWithNameConstraint | Call
|
|
|
30
30
|
export interface DoesCallQuery extends BaseQueryFormat {
|
|
31
31
|
readonly type: 'does-call';
|
|
32
32
|
readonly queryId?: string;
|
|
33
|
-
readonly call:
|
|
33
|
+
readonly call: SlicingCriterion;
|
|
34
34
|
readonly calls: CallsConstraint;
|
|
35
35
|
}
|
|
36
36
|
export interface FindAllCallsResult {
|
|
@@ -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();
|
|
@@ -22,8 +22,8 @@ async function executeHappensBefore({ analyzer }, queries) {
|
|
|
22
22
|
log_1.log.warn('Duplicate happens-before query', query, 'ignoring');
|
|
23
23
|
}
|
|
24
24
|
try {
|
|
25
|
-
const resolvedA = parse_1.
|
|
26
|
-
const resolvedB = parse_1.
|
|
25
|
+
const resolvedA = parse_1.SlicingCriterion.parse(a, ast.idMap);
|
|
26
|
+
const resolvedB = parse_1.SlicingCriterion.parse(b, ast.idMap);
|
|
27
27
|
results[fingerprint] = (0, happens_before_1.happensBefore)(cfg.graph, resolvedA, resolvedB);
|
|
28
28
|
}
|
|
29
29
|
catch (e) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
|
|
2
2
|
import Joi from 'joi';
|
|
3
3
|
import { executeHappensBefore } from './happens-before-query-executor';
|
|
4
|
-
import type {
|
|
4
|
+
import type { SlicingCriterion } from '../../../slicing/criterion/parse';
|
|
5
5
|
import type { Ternary } from '../../../util/logic';
|
|
6
6
|
export interface HappensBeforeQuery extends BaseQueryFormat {
|
|
7
7
|
readonly type: 'happens-before';
|
|
8
|
-
readonly a:
|
|
9
|
-
readonly b:
|
|
8
|
+
readonly a: SlicingCriterion;
|
|
9
|
+
readonly b: SlicingCriterion;
|
|
10
10
|
}
|
|
11
11
|
export interface HappensBeforeQueryResult extends BaseQueryResult {
|
|
12
12
|
readonly results: Record<string, Ternary>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { BasicQueryData } from '../../base-query-format';
|
|
2
|
+
import type { InputSourcesQuery, InputSourcesQueryResult } from './input-sources-query-format';
|
|
3
|
+
/**
|
|
4
|
+
* Execute an input sources query
|
|
5
|
+
*/
|
|
6
|
+
export declare function executeInputSourcesQuery({ analyzer }: BasicQueryData, queries: readonly InputSourcesQuery[]): Promise<InputSourcesQueryResult>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeInputSourcesQuery = executeInputSourcesQuery;
|
|
4
|
+
const log_1 = require("../../../util/log");
|
|
5
|
+
const parse_1 = require("../../../slicing/criterion/parse");
|
|
6
|
+
const r_function_definition_1 = require("../../../r-bridge/lang-4.x/ast/model/nodes/r-function-definition");
|
|
7
|
+
const model_1 = require("../../../r-bridge/lang-4.x/ast/model/model");
|
|
8
|
+
const df_helper_1 = require("../../../dataflow/graph/df-helper");
|
|
9
|
+
const simple_input_classifier_1 = require("./simple-input-classifier");
|
|
10
|
+
const network_functions_1 = require("../../../linter/rules/network-functions");
|
|
11
|
+
const seeded_randomness_1 = require("../../../linter/rules/seeded-randomness");
|
|
12
|
+
const read_functions_1 = require("../dependencies-query/function-info/read-functions");
|
|
13
|
+
/**
|
|
14
|
+
* Execute an input sources query
|
|
15
|
+
*/
|
|
16
|
+
async function executeInputSourcesQuery({ analyzer }, queries) {
|
|
17
|
+
const start = Date.now();
|
|
18
|
+
const results = {};
|
|
19
|
+
const nast = await analyzer.normalize();
|
|
20
|
+
const df = await analyzer.dataflow();
|
|
21
|
+
for (const query of queries) {
|
|
22
|
+
const key = query.criterion;
|
|
23
|
+
if (results[key]) {
|
|
24
|
+
log_1.log.warn(`Duplicate key for input-sources query: ${key}, skipping...`);
|
|
25
|
+
}
|
|
26
|
+
const criterionId = parse_1.SlicingCriterion.tryParse(key, nast.idMap) ?? key;
|
|
27
|
+
const provenanceNode = nast.idMap.get(criterionId);
|
|
28
|
+
const fdef = r_function_definition_1.RFunctionDefinition.rootFunctionDefinition(provenanceNode, nast.idMap);
|
|
29
|
+
const provenance = df_helper_1.Dataflow.provenanceGraph(criterionId, df.graph, fdef ? model_1.RNode.collectAllIds(fdef) : undefined);
|
|
30
|
+
results[key] = (0, simple_input_classifier_1.classifyInput)(criterionId, provenance, {
|
|
31
|
+
networkFns: query.config?.networkFns ?? network_functions_1.NETWORK_FUNCTIONS.info.defaultConfig.fns,
|
|
32
|
+
randomFns: query.config?.randomFns ?? seeded_randomness_1.SEEDED_RANDOMNESS.info.defaultConfig.randomnessConsumers,
|
|
33
|
+
pureFns: query.config?.pureFns ?? ['paste', 'paste0', 'parse', '+', '-', '*',
|
|
34
|
+
'/', '^', '%%', '%/%', '&', '|', '!', '&&', '||',
|
|
35
|
+
'<', '>', '<=', '>=', '==', '!=', ':',
|
|
36
|
+
'abs', 'sign', 'sqrt', 'exp', 'log', 'log10', 'log2',
|
|
37
|
+
'sin', 'cos', 'tan', 'asin', 'acos', 'atan',
|
|
38
|
+
'length', 'nchar', 'dim', 'nrow', 'ncol',
|
|
39
|
+
'c', 'list', 'data.frame',
|
|
40
|
+
'ifelse', 'switch', 'factor', 'as.factor',
|
|
41
|
+
'round', 'floor', 'ceiling', 'trunc',
|
|
42
|
+
'substr', 'substring', 'strsplit',
|
|
43
|
+
'min', 'max', 'range', 'sum', 'prod', 'mean', 'median', 'var', 'sd',
|
|
44
|
+
'head', 'tail', 'seq', 'rep',
|
|
45
|
+
'apply', 'lapply', 'sapply', 'vapply', 'tapply',
|
|
46
|
+
'matrix', 'array', 'substitute', 'quote', 'bquote', 'enquote', 'enexpr', 'enexprs', 'enquo', 'enquos',
|
|
47
|
+
'expression', 'call', 'as.call', 'as.expression',
|
|
48
|
+
'rownames', 'colnames',
|
|
49
|
+
'list.files', 'tolower', 'toupper', 'printf',
|
|
50
|
+
'<-', '->', '=', '<<-', '->>', 'assign', 'get',
|
|
51
|
+
'[', '[[', '$', 'length<-', 'dim<-', 'names<-', 'colnames<-', 'rownames<-',
|
|
52
|
+
'as.character', 'as.numeric', 'as.logical', 'as.list', 'as.data.frame', 'as.matrix', 'as.array',
|
|
53
|
+
'identity', 'invisible', 'return', 'force', 'missing',
|
|
54
|
+
'print', 'cat', 'message', 'warning', 'stop'
|
|
55
|
+
],
|
|
56
|
+
readFileFns: query.config?.readFileFns ?? read_functions_1.ReadFunctions.map(f => f.name)
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
'.meta': {
|
|
61
|
+
timing: Date.now() - start
|
|
62
|
+
},
|
|
63
|
+
results
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=input-sources-query-executor.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { BaseQueryFormat, BaseQueryResult } from '../../base-query-format';
|
|
2
|
+
import type { SlicingCriterion } from '../../../slicing/criterion/parse';
|
|
3
|
+
import type { ParsedQueryLine } from '../../query';
|
|
4
|
+
import Joi from 'joi';
|
|
5
|
+
import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id';
|
|
6
|
+
import type { InputClassifierConfig, InputSources } from './simple-input-classifier';
|
|
7
|
+
import type { ReplOutput } from '../../../cli/repl/commands/repl-main';
|
|
8
|
+
import type { FlowrConfig } from '../../../config';
|
|
9
|
+
import { executeInputSourcesQuery } from './input-sources-query-executor';
|
|
10
|
+
export type InputSourcesQueryConfig = InputClassifierConfig;
|
|
11
|
+
/**
|
|
12
|
+
* Calculates provenance for all inputs and their transformations
|
|
13
|
+
* based on the `provenance` of a given function.
|
|
14
|
+
*/
|
|
15
|
+
export interface InputSourcesQuery extends BaseQueryFormat {
|
|
16
|
+
readonly type: 'input-sources';
|
|
17
|
+
/**
|
|
18
|
+
* This takes a criterion (or a numerical id works too)
|
|
19
|
+
* {@link SlicingCriterion.fromId}
|
|
20
|
+
*/
|
|
21
|
+
readonly criterion: SlicingCriterion;
|
|
22
|
+
readonly config?: InputSourcesQueryConfig;
|
|
23
|
+
}
|
|
24
|
+
export interface InputSourcesQueryResult extends BaseQueryResult {
|
|
25
|
+
/** For each query key, a list of classified input sources (each with id and all traces) */
|
|
26
|
+
results: Record<string, InputSources>;
|
|
27
|
+
}
|
|
28
|
+
declare function inputSourcesQueryLineParser(output: ReplOutput, line: readonly string[], _config: FlowrConfig): ParsedQueryLine<'input-sources'>;
|
|
29
|
+
export declare const InputSourcesDefinition: {
|
|
30
|
+
readonly executor: typeof executeInputSourcesQuery;
|
|
31
|
+
readonly asciiSummarizer: (formatter: import("../../../util/text/ansi").OutputFormatter, analyzer: import("../../../project/flowr-analyzer").ReadonlyFlowrAnalysisProvider<import("../../../r-bridge/parser").KnownParser>, queryResults: BaseQueryResult, result: string[]) => Promise<boolean>;
|
|
32
|
+
readonly fromLine: typeof inputSourcesQueryLineParser;
|
|
33
|
+
readonly schema: Joi.ObjectSchema<any>;
|
|
34
|
+
readonly flattenInvolvedNodes: (queryResults: BaseQueryResult) => NodeId[];
|
|
35
|
+
};
|
|
36
|
+
export {};
|