@eagleoutice/flowr 2.2.15 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +226 -6
- package/abstract-interpretation/data-frame/absint-info.d.ts +109 -0
- package/abstract-interpretation/data-frame/absint-info.js +31 -0
- package/abstract-interpretation/data-frame/absint-visitor.d.ts +59 -0
- package/abstract-interpretation/data-frame/absint-visitor.js +173 -0
- package/abstract-interpretation/data-frame/domain.d.ts +107 -0
- package/abstract-interpretation/data-frame/domain.js +315 -0
- package/abstract-interpretation/data-frame/mappers/access-mapper.d.ts +17 -0
- package/abstract-interpretation/data-frame/mappers/access-mapper.js +166 -0
- package/abstract-interpretation/data-frame/mappers/arguments.d.ts +117 -0
- package/abstract-interpretation/data-frame/mappers/arguments.js +188 -0
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.d.ts +20 -0
- package/abstract-interpretation/data-frame/mappers/assignment-mapper.js +34 -0
- package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +261 -0
- package/abstract-interpretation/data-frame/mappers/function-mapper.js +1219 -0
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.d.ts +12 -0
- package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +206 -0
- package/abstract-interpretation/data-frame/resolve-args.d.ts +42 -0
- package/abstract-interpretation/data-frame/resolve-args.js +118 -0
- package/abstract-interpretation/data-frame/semantics.d.ts +213 -0
- package/abstract-interpretation/data-frame/semantics.js +366 -0
- package/abstract-interpretation/data-frame/shape-inference.d.ts +38 -0
- package/abstract-interpretation/data-frame/shape-inference.js +117 -0
- package/benchmark/slicer.d.ts +18 -2
- package/benchmark/slicer.js +143 -5
- package/benchmark/stats/print.js +123 -45
- package/benchmark/stats/size-of.d.ts +7 -0
- package/benchmark/stats/size-of.js +1 -0
- package/benchmark/stats/stats.d.ts +30 -1
- package/benchmark/stats/stats.js +4 -2
- package/benchmark/summarizer/data.d.ts +33 -2
- package/benchmark/summarizer/first-phase/input.js +5 -1
- package/benchmark/summarizer/first-phase/process.d.ts +2 -1
- package/benchmark/summarizer/first-phase/process.js +49 -3
- package/benchmark/summarizer/second-phase/process.js +101 -3
- package/cli/benchmark-app.d.ts +2 -0
- package/cli/benchmark-app.js +5 -1
- package/cli/benchmark-helper-app.d.ts +2 -0
- package/cli/benchmark-helper-app.js +13 -8
- package/cli/common/options.js +4 -0
- package/cli/export-quads-app.js +2 -1
- package/cli/flowr.js +58 -57
- package/cli/repl/commands/repl-cfg.js +13 -13
- package/cli/repl/commands/repl-commands.js +2 -2
- package/cli/repl/commands/repl-dataflow.js +10 -10
- package/cli/repl/commands/repl-execute.d.ts +2 -3
- package/cli/repl/commands/repl-execute.js +4 -4
- package/cli/repl/commands/repl-lineage.js +4 -4
- package/cli/repl/commands/repl-main.d.ts +12 -1
- package/cli/repl/commands/repl-normalize.js +6 -6
- package/cli/repl/commands/repl-parse.js +2 -2
- package/cli/repl/commands/repl-query.js +9 -9
- package/cli/repl/commands/repl-version.js +1 -1
- package/cli/repl/core.d.ts +5 -2
- package/cli/repl/core.js +10 -8
- package/cli/repl/server/connection.d.ts +3 -1
- package/cli/repl/server/connection.js +7 -5
- package/cli/repl/server/server.d.ts +3 -2
- package/cli/repl/server/server.js +4 -2
- package/cli/script-core/statistics-core.d.ts +2 -1
- package/cli/script-core/statistics-core.js +2 -2
- package/cli/script-core/statistics-helper-core.d.ts +2 -1
- package/cli/script-core/statistics-helper-core.js +5 -4
- package/cli/slicer-app.js +4 -2
- package/cli/statistics-app.js +2 -1
- package/cli/statistics-helper-app.js +2 -1
- package/config.d.ts +43 -10
- package/config.js +47 -43
- package/control-flow/cfg-dead-code.js +45 -2
- package/control-flow/cfg-simplification.d.ts +2 -0
- package/control-flow/control-flow-graph.d.ts +2 -0
- package/control-flow/control-flow-graph.js +8 -0
- package/control-flow/dfg-cfg-guided-visitor.d.ts +5 -3
- package/control-flow/dfg-cfg-guided-visitor.js +15 -4
- package/control-flow/extract-cfg.d.ts +4 -2
- package/control-flow/extract-cfg.js +4 -3
- package/control-flow/semantic-cfg-guided-visitor.d.ts +20 -2
- package/control-flow/semantic-cfg-guided-visitor.js +24 -4
- package/core/pipeline-executor.d.ts +4 -1
- package/core/pipeline-executor.js +6 -5
- package/core/steps/all/core/10-normalize.d.ts +2 -0
- package/core/steps/all/core/10-normalize.js +1 -1
- package/core/steps/all/core/11-normalize-tree-sitter.d.ts +2 -1
- package/core/steps/all/core/11-normalize-tree-sitter.js +2 -2
- package/core/steps/all/core/20-dataflow.d.ts +2 -1
- package/core/steps/all/core/20-dataflow.js +2 -2
- package/core/steps/all/static-slicing/00-slice.d.ts +2 -1
- package/core/steps/all/static-slicing/00-slice.js +2 -2
- package/core/steps/pipeline/default-pipelines.d.ts +32 -31
- package/core/steps/pipeline/default-pipelines.js +8 -8
- package/core/steps/pipeline-step.d.ts +2 -1
- package/dataflow/environments/built-in-config.d.ts +3 -3
- package/dataflow/environments/built-in.d.ts +11 -3
- package/dataflow/environments/built-in.js +5 -3
- package/dataflow/environments/default-builtin-config.js +4 -2
- package/dataflow/environments/define.d.ts +2 -1
- package/dataflow/environments/define.js +4 -5
- package/dataflow/environments/remove.d.ts +6 -0
- package/dataflow/environments/remove.js +29 -0
- package/dataflow/eval/resolve/alias-tracking.d.ts +7 -2
- package/dataflow/eval/resolve/alias-tracking.js +11 -8
- package/dataflow/eval/resolve/resolve-argument.d.ts +8 -0
- package/dataflow/eval/resolve/resolve-argument.js +118 -0
- package/dataflow/eval/resolve/resolve.d.ts +65 -18
- package/dataflow/eval/resolve/resolve.js +144 -48
- package/dataflow/eval/values/string/string-constants.d.ts +1 -1
- package/dataflow/eval/values/string/string-constants.js +7 -2
- package/dataflow/extractor.d.ts +2 -1
- package/dataflow/extractor.js +2 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-access.js +5 -6
- package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +1 -1
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +4 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +11 -11
- package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +10 -11
- package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +7 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +2 -3
- 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-list.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +2 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-source.d.ts +6 -3
- package/dataflow/internal/process/functions/call/built-in/built-in-source.js +19 -15
- package/dataflow/internal/process/functions/call/built-in/built-in-vector.js +2 -2
- package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +1 -1
- package/dataflow/internal/process/functions/call/common.js +1 -1
- package/dataflow/internal/process/functions/process-parameter.js +1 -1
- package/dataflow/origin/dfg-get-symbol-refs.d.ts +21 -0
- package/dataflow/origin/dfg-get-symbol-refs.js +50 -0
- package/dataflow/processor.d.ts +5 -0
- package/documentation/doc-util/doc-cfg.js +4 -3
- package/documentation/doc-util/doc-code.d.ts +1 -1
- package/documentation/doc-util/doc-dfg.js +3 -2
- package/documentation/doc-util/doc-functions.d.ts +24 -0
- package/documentation/doc-util/doc-functions.js +65 -0
- package/documentation/doc-util/doc-normalized-ast.js +3 -2
- package/documentation/doc-util/doc-print.d.ts +5 -0
- package/documentation/doc-util/doc-print.js +36 -0
- package/documentation/doc-util/doc-query.js +13 -2
- package/documentation/doc-util/doc-repl.js +2 -1
- package/documentation/doc-util/doc-search.js +3 -2
- package/documentation/doc-util/doc-types.d.ts +28 -6
- package/documentation/doc-util/doc-types.js +89 -45
- package/documentation/print-cfg-wiki.js +6 -7
- package/documentation/print-core-wiki.js +5 -5
- package/documentation/print-dataflow-graph-wiki.js +10 -10
- package/documentation/print-engines-wiki.js +1 -2
- package/documentation/print-faq-wiki.js +8 -2
- package/documentation/print-interface-wiki.js +12 -2
- package/documentation/print-linter-issue.d.ts +1 -0
- package/documentation/print-linter-issue.js +71 -0
- package/documentation/print-linter-wiki.js +223 -34
- package/documentation/print-linting-and-testing-wiki.js +2 -4
- package/documentation/print-normalized-ast-wiki.js +3 -3
- package/documentation/print-query-wiki.js +18 -2
- package/documentation/print-readme.js +24 -1
- package/documentation/print-search-wiki.js +1 -2
- package/linter/linter-executor.d.ts +3 -1
- package/linter/linter-executor.js +3 -2
- package/linter/linter-format.d.ts +67 -7
- package/linter/linter-format.js +12 -1
- package/linter/linter-rules.d.ts +178 -16
- package/linter/linter-rules.js +14 -4
- package/linter/linter-tags.d.ts +80 -0
- package/linter/linter-tags.js +85 -0
- package/linter/rules/absolute-path.d.ts +71 -0
- package/linter/rules/absolute-path.js +177 -0
- package/linter/rules/dataframe-access-validation.d.ts +53 -0
- package/linter/rules/dataframe-access-validation.js +116 -0
- package/linter/rules/deprecated-functions.d.ts +43 -0
- package/linter/rules/deprecated-functions.js +58 -0
- package/linter/rules/{2-file-path-validity.d.ts → file-path-validity.d.ts} +16 -6
- package/linter/rules/{2-file-path-validity.js → file-path-validity.js} +21 -13
- package/linter/rules/naming-convention.d.ts +71 -0
- package/linter/rules/naming-convention.js +168 -0
- package/linter/rules/seeded-randomness.d.ts +65 -0
- package/linter/rules/seeded-randomness.js +122 -0
- package/linter/rules/unused-definition.d.ts +41 -0
- package/linter/rules/unused-definition.js +105 -0
- package/package.json +5 -2
- package/queries/base-query-format.d.ts +2 -0
- 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 +2 -2
- package/queries/catalog/cluster-query/cluster-query-format.d.ts +1 -1
- package/queries/catalog/config-query/config-query-executor.d.ts +1 -1
- package/queries/catalog/config-query/config-query-executor.js +2 -3
- package/queries/catalog/control-flow-query/control-flow-query-executor.d.ts +1 -1
- package/queries/catalog/control-flow-query/control-flow-query-executor.js +2 -2
- package/queries/catalog/control-flow-query/control-flow-query-format.d.ts +1 -1
- package/queries/catalog/dataflow-lens-query/dataflow-lens-query-format.d.ts +1 -1
- package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +1 -1
- package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -116
- package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +1 -1
- package/queries/catalog/df-shape-query/df-shape-query-executor.d.ts +3 -0
- package/queries/catalog/df-shape-query/df-shape-query-executor.js +46 -0
- package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +72 -0
- package/queries/catalog/df-shape-query/df-shape-query-format.js +31 -0
- package/queries/catalog/happens-before-query/happens-before-query-format.d.ts +1 -1
- package/queries/catalog/id-map-query/id-map-query-format.d.ts +1 -1
- package/queries/catalog/lineage-query/lineage-query-format.d.ts +1 -1
- package/queries/catalog/linter-query/linter-query-executor.d.ts +1 -1
- package/queries/catalog/linter-query/linter-query-executor.js +2 -2
- package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
- package/queries/catalog/linter-query/linter-query-format.js +16 -12
- package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +1 -1
- package/queries/catalog/origin-query/origin-query-format.d.ts +1 -1
- package/queries/catalog/project-query/project-query-format.d.ts +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.d.ts +1 -1
- package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +2 -2
- package/queries/catalog/resolve-value-query/resolve-value-query-format.d.ts +1 -1
- package/queries/catalog/search-query/search-query-executor.d.ts +1 -1
- package/queries/catalog/search-query/search-query-executor.js +2 -2
- package/queries/catalog/search-query/search-query-format.d.ts +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
- package/queries/catalog/static-slice-query/static-slice-query-executor.js +2 -2
- package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +1 -1
- package/queries/query.d.ts +76 -16
- package/queries/query.js +2 -0
- package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -1
- package/r-bridge/lang-4.x/ast/parser/json/parser.js +4 -2
- package/r-bridge/lang-4.x/convert-values.js +2 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.d.ts +3 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-executor.js +4 -4
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.d.ts +1 -1
- package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +7 -5
- package/r-bridge/shell.d.ts +3 -2
- package/r-bridge/shell.js +4 -5
- package/search/flowr-search-builder.d.ts +6 -2
- package/search/flowr-search-builder.js +7 -0
- package/search/flowr-search-filters.d.ts +32 -8
- package/search/flowr-search-filters.js +42 -15
- package/search/flowr-search.d.ts +4 -0
- package/search/search-executor/search-enrichers.d.ts +7 -3
- package/search/search-executor/search-enrichers.js +29 -20
- package/search/search-executor/search-generators.js +1 -1
- package/search/search-executor/search-transformer.d.ts +2 -0
- package/search/search-executor/search-transformer.js +10 -1
- package/slicing/static/static-slicer.d.ts +1 -1
- package/slicing/static/static-slicer.js +2 -3
- package/statistics/statistics.d.ts +3 -1
- package/statistics/statistics.js +5 -4
- package/util/containers.d.ts +12 -9
- package/util/containers.js +12 -9
- package/util/files.d.ts +8 -2
- package/util/files.js +22 -4
- package/util/objects.d.ts +5 -4
- package/util/r-value.d.ts +23 -0
- package/util/r-value.js +113 -0
- package/util/range.d.ts +5 -1
- package/util/range.js +11 -3
- package/util/text/strings.d.ts +6 -0
- package/util/text/strings.js +35 -0
- package/util/version.js +1 -1
- package/linter/rules/1-deprecated-functions.d.ts +0 -34
- package/linter/rules/1-deprecated-functions.js +0 -54
- package/util/cfg/cfg.d.ts +0 -0
- package/util/cfg/cfg.js +0 -2
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ABSOLUTE_PATH = void 0;
|
|
7
|
+
const linter_format_1 = require("../linter-format");
|
|
8
|
+
const objects_1 = require("../../util/objects");
|
|
9
|
+
const flowr_search_builder_1 = require("../../search/flowr-search-builder");
|
|
10
|
+
const range_1 = require("../../util/range");
|
|
11
|
+
const dfg_1 = require("../../util/mermaid/dfg");
|
|
12
|
+
const linter_tags_1 = require("../linter-tags");
|
|
13
|
+
const type_1 = require("../../r-bridge/lang-4.x/ast/model/type");
|
|
14
|
+
const strings_1 = require("../../util/text/strings");
|
|
15
|
+
const r_string_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-string");
|
|
16
|
+
const assert_1 = require("../../util/assert");
|
|
17
|
+
const read_functions_1 = require("../../queries/catalog/dependencies-query/function-info/read-functions");
|
|
18
|
+
const write_functions_1 = require("../../queries/catalog/dependencies-query/function-info/write-functions");
|
|
19
|
+
const search_enrichers_1 = require("../../search/search-executor/search-enrichers");
|
|
20
|
+
const source_functions_1 = require("../../queries/catalog/dependencies-query/function-info/source-functions");
|
|
21
|
+
const vertex_1 = require("../../dataflow/graph/vertex");
|
|
22
|
+
const dependencies_query_format_1 = require("../../queries/catalog/dependencies-query/dependencies-query-format");
|
|
23
|
+
const resolve_argument_1 = require("../../dataflow/eval/resolve/resolve-argument");
|
|
24
|
+
const path_1 = __importDefault(require("path"));
|
|
25
|
+
function inferWd(file, wd) {
|
|
26
|
+
if (wd === '@script') {
|
|
27
|
+
// we can use the script path as the working directory
|
|
28
|
+
return file;
|
|
29
|
+
}
|
|
30
|
+
else if (wd === '@home') {
|
|
31
|
+
// we can use the home directory as the working directory
|
|
32
|
+
return process.env.HOME || process.env.USERPROFILE || '';
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
return wd;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// this can be improved by respecting raw strings and supporting more scenarios
|
|
39
|
+
function buildQuickFix(str, filePath, wd) {
|
|
40
|
+
if (!wd || !(0, r_string_1.isRString)(str)) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
return [{
|
|
44
|
+
type: 'replace',
|
|
45
|
+
range: str.location,
|
|
46
|
+
description: `Replace with a relative path to \`${filePath}\``,
|
|
47
|
+
replacement: str.content.quotes + '.' + path_1.default.sep + path_1.default.relative(wd, filePath) + str.content.quotes
|
|
48
|
+
}];
|
|
49
|
+
}
|
|
50
|
+
/** return all strings constructable by these functions */
|
|
51
|
+
const PathFunctions = {
|
|
52
|
+
'file.path': (df, vtx, config) => {
|
|
53
|
+
const fsep = (0, resolve_argument_1.getArgumentStringValue)(config.solver.variables, df, vtx, undefined, 'fsep', true);
|
|
54
|
+
// in the future we can access `.Platform$file.sep` here
|
|
55
|
+
const sepValues = new Array(...fsep?.values()?.flatMap(s => [...s].filter(assert_1.isNotUndefined)) ?? [path_1.default.sep]);
|
|
56
|
+
if (sepValues.some(s => s === dependencies_query_format_1.Unknown || (0, assert_1.isUndefined)(s))) {
|
|
57
|
+
// if we have no fsep, we cannot construct a path
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
const args = (0, resolve_argument_1.getArgumentStringValue)(config.solver.variables, df, vtx, 'unnamed', undefined, true);
|
|
61
|
+
const argValues = args ? Array.from(args.values()).flatMap(v => [...v]) : [];
|
|
62
|
+
if (!argValues || argValues.length === 0 || argValues.some(v => v === dependencies_query_format_1.Unknown || (0, assert_1.isUndefined)(v))) {
|
|
63
|
+
// if we have no arguments, we cannot construct a path
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
const results = [];
|
|
67
|
+
for (const val of sepValues) {
|
|
68
|
+
results.push(argValues.join(val));
|
|
69
|
+
}
|
|
70
|
+
return results;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
exports.ABSOLUTE_PATH = {
|
|
74
|
+
/* this can be done better once we have types */
|
|
75
|
+
createSearch: (config) => {
|
|
76
|
+
let q;
|
|
77
|
+
if (config.include.allStrings) {
|
|
78
|
+
q = flowr_search_builder_1.Q.all().filter(type_1.RType.String);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
q = flowr_search_builder_1.Q.fromQuery({
|
|
82
|
+
type: 'dependencies',
|
|
83
|
+
// we use the dependencies query to give us all functions that take a file path as input
|
|
84
|
+
ignoreDefaultFunctions: true,
|
|
85
|
+
readFunctions: read_functions_1.ReadFunctions.concat(write_functions_1.WriteFunctions, source_functions_1.SourceFunctions, config.additionalPathFunctions),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
if (config.include.constructed) {
|
|
89
|
+
q = q.merge(flowr_search_builder_1.Q.all().filter(vertex_1.VertexType.FunctionCall).with(search_enrichers_1.Enrichment.CallTargets));
|
|
90
|
+
/* in the future we want to directly check whether this is one of the supported functions */
|
|
91
|
+
}
|
|
92
|
+
return q.unique();
|
|
93
|
+
},
|
|
94
|
+
processSearchResult: (elements, config, data) => {
|
|
95
|
+
const metadata = {
|
|
96
|
+
totalConsidered: 0,
|
|
97
|
+
totalUnknown: 0
|
|
98
|
+
};
|
|
99
|
+
const regex = config.absolutePathRegex ? new RegExp(config.absolutePathRegex) : undefined;
|
|
100
|
+
return {
|
|
101
|
+
results: elements.getElements().flatMap(element => {
|
|
102
|
+
metadata.totalConsidered++;
|
|
103
|
+
const node = element.node;
|
|
104
|
+
const wd = inferWd(node.info.file, config.useAsWd);
|
|
105
|
+
if ((0, r_string_1.isRString)(node)) {
|
|
106
|
+
if (node.content.str.length >= 3 && (0, strings_1.isAbsolutePath)(node.content.str, regex)) {
|
|
107
|
+
return [{
|
|
108
|
+
certainty: linter_format_1.LintingCertainty.Maybe,
|
|
109
|
+
filePath: node.content.str,
|
|
110
|
+
range: node.info.fullRange ?? node.location,
|
|
111
|
+
quickFix: buildQuickFix(node, node.content.str, wd)
|
|
112
|
+
}];
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else if (element.queryResult) {
|
|
119
|
+
const result = element.queryResult;
|
|
120
|
+
const mappedStrings = result.readData.filter(r => r.source !== dependencies_query_format_1.Unknown && (0, strings_1.isAbsolutePath)(r.source, regex)).map(r => {
|
|
121
|
+
const elem = data.normalize.idMap.get(r.nodeId);
|
|
122
|
+
return {
|
|
123
|
+
certainty: linter_format_1.LintingCertainty.Definitely,
|
|
124
|
+
filePath: r.source,
|
|
125
|
+
range: elem?.info.fullRange ?? elem?.location ?? (0, range_1.rangeFrom)(-1, -1, -1, -1),
|
|
126
|
+
quickFix: buildQuickFix(elem, r.source, wd)
|
|
127
|
+
};
|
|
128
|
+
});
|
|
129
|
+
if (mappedStrings.length > 0) {
|
|
130
|
+
return mappedStrings;
|
|
131
|
+
}
|
|
132
|
+
else if (result.readData.every(r => r.source !== dependencies_query_format_1.Unknown)) {
|
|
133
|
+
// if we have no absolute paths, but all paths are known, we can return an empty array
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
const dfNode = data.dataflow.graph.getVertex(node.info.id);
|
|
139
|
+
if ((0, vertex_1.isFunctionCallVertex)(dfNode)) {
|
|
140
|
+
const handler = PathFunctions[dfNode.name ?? ''];
|
|
141
|
+
const strings = handler ? handler(data.dataflow.graph, dfNode, data.config) : [];
|
|
142
|
+
if (strings) {
|
|
143
|
+
return strings.filter(s => (0, strings_1.isAbsolutePath)(s, regex)).map(str => ({
|
|
144
|
+
certainty: linter_format_1.LintingCertainty.Maybe,
|
|
145
|
+
filePath: str,
|
|
146
|
+
range: node.info.fullRange ?? node.location ?? (0, range_1.rangeFrom)(-1, -1, -1, -1)
|
|
147
|
+
}));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// check whether the df node is a function call that returns a file path
|
|
151
|
+
}
|
|
152
|
+
metadata.totalUnknown++;
|
|
153
|
+
return undefined;
|
|
154
|
+
}).filter(assert_1.isNotUndefined).map(r => (0, objects_1.compactRecord)(r)),
|
|
155
|
+
'.meta': metadata
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
prettyPrint: {
|
|
159
|
+
[linter_format_1.LintingPrettyPrintContext.Query]: result => `Path \`${result.filePath}\` at ${(0, dfg_1.formatRange)(result.range)}`,
|
|
160
|
+
[linter_format_1.LintingPrettyPrintContext.Full]: result => `Path \`${result.filePath}\` at ${(0, dfg_1.formatRange)(result.range)} is not absolute`
|
|
161
|
+
},
|
|
162
|
+
info: {
|
|
163
|
+
name: 'Absolute Paths',
|
|
164
|
+
description: 'Checks whether file paths are absolute.',
|
|
165
|
+
tags: [linter_tags_1.LintingRuleTag.Robustness, linter_tags_1.LintingRuleTag.Reproducibility, linter_tags_1.LintingRuleTag.Smell, linter_tags_1.LintingRuleTag.QuickFix],
|
|
166
|
+
defaultConfig: {
|
|
167
|
+
include: {
|
|
168
|
+
constructed: true,
|
|
169
|
+
allStrings: false
|
|
170
|
+
},
|
|
171
|
+
additionalPathFunctions: [],
|
|
172
|
+
absolutePathRegex: undefined,
|
|
173
|
+
useAsWd: '@script'
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
//# sourceMappingURL=absolute-path.js.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
2
|
+
import type { FlowrSearchElements } from '../../search/flowr-search';
|
|
3
|
+
import { type MergeableRecord } from '../../util/objects';
|
|
4
|
+
import { type SourceRange } from '../../util/range';
|
|
5
|
+
import type { LintingResult } from '../linter-format';
|
|
6
|
+
import { LintingRuleTag } from '../linter-tags';
|
|
7
|
+
export interface DataFrameAccessValidationResult extends LintingResult {
|
|
8
|
+
/** The type of the data frame access ("column" or "row") */
|
|
9
|
+
type: 'column' | 'row';
|
|
10
|
+
/** The name or index of the column or row being accessed in the data frame */
|
|
11
|
+
accessed: string | number;
|
|
12
|
+
/** The name of the function/operation used for the access (e.g. `$`, `[`, `[[`, but also `filter`, `select`, ...) */
|
|
13
|
+
access: string;
|
|
14
|
+
/** The variable/symbol name of the accessed data frame operand (`undefined` if operand is no symbol) */
|
|
15
|
+
operand?: string;
|
|
16
|
+
/** The source range in the code where the access occurs */
|
|
17
|
+
range: SourceRange;
|
|
18
|
+
}
|
|
19
|
+
export interface DataFrameAccessValidationConfig extends MergeableRecord {
|
|
20
|
+
/** Whether data frame shapes should be extracted from loaded external data files, such as CSV files (defaults to the option in the flowR config if `undefined`) */
|
|
21
|
+
readLoadedData?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface DataFrameAccessValidationMetadata extends MergeableRecord {
|
|
24
|
+
/** The number of data frame functions and operations containing inferred column or row accesses */
|
|
25
|
+
numOperations: number;
|
|
26
|
+
/** The number of inferred abstract column or row access operations */
|
|
27
|
+
numAccesses: number;
|
|
28
|
+
/** The total number of inferred accessed columns and rows */
|
|
29
|
+
totalAccessed: number;
|
|
30
|
+
}
|
|
31
|
+
export declare const DATA_FRAME_ACCESS_VALIDATION: {
|
|
32
|
+
readonly createSearch: () => import("../../search/flowr-search-builder").FlowrSearchBuilder<"all", ["with"], ParentInformation, FlowrSearchElements<ParentInformation, import("../../search/search-executor/search-enrichers").EnrichedFlowrSearchElement<ParentInformation>[]>>;
|
|
33
|
+
readonly processSearchResult: (elements: FlowrSearchElements<ParentInformation, import("../../search/flowr-search").FlowrSearchElement<ParentInformation>[]>, config: DataFrameAccessValidationConfig, data: {
|
|
34
|
+
normalize: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
35
|
+
dataflow: import("../../dataflow/info").DataflowInformation;
|
|
36
|
+
config: import("../../config").FlowrConfigOptions;
|
|
37
|
+
}) => {
|
|
38
|
+
results: DataFrameAccessValidationResult[];
|
|
39
|
+
'.meta': DataFrameAccessValidationMetadata;
|
|
40
|
+
};
|
|
41
|
+
readonly prettyPrint: {
|
|
42
|
+
readonly query: (result: DataFrameAccessValidationResult) => string;
|
|
43
|
+
readonly full: (result: DataFrameAccessValidationResult) => string;
|
|
44
|
+
};
|
|
45
|
+
readonly info: {
|
|
46
|
+
readonly name: "Dataframe Access Validation";
|
|
47
|
+
readonly tags: readonly [LintingRuleTag.Bug, LintingRuleTag.Usability, LintingRuleTag.Reproducibility];
|
|
48
|
+
readonly description: "Validates the existance of accessed columns and rows of dataframes.";
|
|
49
|
+
readonly defaultConfig: {
|
|
50
|
+
readonly readLoadedData: false;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DATA_FRAME_ACCESS_VALIDATION = void 0;
|
|
4
|
+
const absint_info_1 = require("../../abstract-interpretation/data-frame/absint-info");
|
|
5
|
+
const domain_1 = require("../../abstract-interpretation/data-frame/domain");
|
|
6
|
+
const shape_inference_1 = require("../../abstract-interpretation/data-frame/shape-inference");
|
|
7
|
+
const config_1 = require("../../config");
|
|
8
|
+
const extract_cfg_1 = require("../../control-flow/extract-cfg");
|
|
9
|
+
const type_1 = require("../../r-bridge/lang-4.x/ast/model/type");
|
|
10
|
+
const flowr_search_builder_1 = require("../../search/flowr-search-builder");
|
|
11
|
+
const search_enrichers_1 = require("../../search/search-executor/search-enrichers");
|
|
12
|
+
const dfg_1 = require("../../util/mermaid/dfg");
|
|
13
|
+
const range_1 = require("../../util/range");
|
|
14
|
+
const linter_format_1 = require("../linter-format");
|
|
15
|
+
const linter_tags_1 = require("../linter-tags");
|
|
16
|
+
;
|
|
17
|
+
;
|
|
18
|
+
exports.DATA_FRAME_ACCESS_VALIDATION = {
|
|
19
|
+
createSearch: () => flowr_search_builder_1.Q.all().with(search_enrichers_1.Enrichment.CallTargets, { onlyBuiltin: true }),
|
|
20
|
+
processSearchResult: (elements, config, data) => {
|
|
21
|
+
const flowrConfig = (0, config_1.amendConfig)(data.config, flowrConfig => {
|
|
22
|
+
if (config.readLoadedData !== undefined) {
|
|
23
|
+
flowrConfig.abstractInterpretation.dataFrame.readLoadedData.readExternalFiles = config.readLoadedData;
|
|
24
|
+
}
|
|
25
|
+
return flowrConfig;
|
|
26
|
+
});
|
|
27
|
+
const cfg = (0, extract_cfg_1.extractCfg)(data.normalize, flowrConfig, data.dataflow.graph);
|
|
28
|
+
(0, shape_inference_1.inferDataFrameShapes)(cfg, data.dataflow.graph, data.normalize, flowrConfig);
|
|
29
|
+
const accessOperations = getAccessOperations(elements);
|
|
30
|
+
const accesses = [];
|
|
31
|
+
for (const [nodeId, operations] of accessOperations) {
|
|
32
|
+
const access = { nodeId };
|
|
33
|
+
for (const operation of operations) {
|
|
34
|
+
access.operand ??= operation.operand;
|
|
35
|
+
access.operandShape ??= (0, shape_inference_1.resolveIdToDataFrameShape)(operation.operand, data.dataflow.graph);
|
|
36
|
+
if (operation.operation === 'accessCols' && operation.columns !== undefined) {
|
|
37
|
+
access.accessedCols ??= [];
|
|
38
|
+
access.accessedCols.push(...operation.columns);
|
|
39
|
+
}
|
|
40
|
+
else if (operation.operation === 'accessRows' && operation.rows !== undefined) {
|
|
41
|
+
access.accessedRows ??= [];
|
|
42
|
+
access.accessedRows.push(...operation.rows);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
accesses.push(access);
|
|
46
|
+
}
|
|
47
|
+
const operations = accessOperations.entries().flatMap(([, operations]) => operations).toArray();
|
|
48
|
+
const metadata = {
|
|
49
|
+
numOperations: accessOperations.size,
|
|
50
|
+
numAccesses: operations.length,
|
|
51
|
+
totalAccessed: operations
|
|
52
|
+
.map(operation => operation.operation === 'accessCols' ? operation.columns?.length ?? 0 : operation.rows?.length ?? 0)
|
|
53
|
+
.reduce((a, b) => a + b, 0)
|
|
54
|
+
};
|
|
55
|
+
const results = accesses
|
|
56
|
+
.flatMap(access => findInvalidDataFrameAccesses(access)
|
|
57
|
+
.map(accessed => ({ nodeId: access.nodeId, operand: access.operand, ...accessed })))
|
|
58
|
+
.map(({ nodeId, operand, ...accessed }) => ({
|
|
59
|
+
...accessed,
|
|
60
|
+
node: data.normalize.idMap.get(nodeId),
|
|
61
|
+
operand: operand !== undefined ? data.normalize.idMap.get(operand) : undefined,
|
|
62
|
+
}))
|
|
63
|
+
.map(({ node, operand, ...accessed }) => ({
|
|
64
|
+
...accessed,
|
|
65
|
+
access: node?.lexeme ?? '???',
|
|
66
|
+
...(operand?.type === type_1.RType.Symbol ? { operand: operand.content } : {}),
|
|
67
|
+
range: node?.info.fullRange ?? node?.location ?? (0, range_1.rangeFrom)(-1, -1, -1, -1),
|
|
68
|
+
certainty: linter_format_1.LintingCertainty.Definitely
|
|
69
|
+
}));
|
|
70
|
+
return { results, '.meta': metadata };
|
|
71
|
+
},
|
|
72
|
+
prettyPrint: {
|
|
73
|
+
[linter_format_1.LintingPrettyPrintContext.Query]: result => `Access of ${result.type} ` +
|
|
74
|
+
(typeof result.accessed === 'string' ? `"${result.accessed}"` : result.accessed) + ' ' +
|
|
75
|
+
(result.operand !== undefined ? `of \`${result.operand}\`` : `at \`${result.access}\``) + ` at ${(0, dfg_1.formatRange)(result.range)}`,
|
|
76
|
+
[linter_format_1.LintingPrettyPrintContext.Full]: result => `Accessed ${result.type} ` +
|
|
77
|
+
(typeof result.accessed === 'string' ? `"${result.accessed}"` : result.accessed) + ' does not exist ' +
|
|
78
|
+
(result.operand !== undefined ? `in \`${result.operand}\`` : `at \`${result.access}\``) + ` at ${(0, dfg_1.formatRange)(result.range)}`
|
|
79
|
+
},
|
|
80
|
+
info: {
|
|
81
|
+
name: 'Dataframe Access Validation',
|
|
82
|
+
tags: [linter_tags_1.LintingRuleTag.Bug, linter_tags_1.LintingRuleTag.Usability, linter_tags_1.LintingRuleTag.Reproducibility],
|
|
83
|
+
description: 'Validates the existance of accessed columns and rows of dataframes.',
|
|
84
|
+
defaultConfig: { readLoadedData: false }
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
function getAccessOperations(elements) {
|
|
88
|
+
return new Map(elements.getElements()
|
|
89
|
+
.map(element => element.node)
|
|
90
|
+
.filter(absint_info_1.hasDataFrameExpressionInfo)
|
|
91
|
+
.map(node => [node.info.id, node.info.dataFrame.operations
|
|
92
|
+
.filter(({ operation }) => operation === 'accessCols' || operation === 'accessRows')
|
|
93
|
+
.map(({ operation, operand, type: _type, options: _options, ...args }) => ({ operation, operand, ...args }))
|
|
94
|
+
])
|
|
95
|
+
.filter(([, operations]) => operations.length > 0));
|
|
96
|
+
}
|
|
97
|
+
function findInvalidDataFrameAccesses({ operandShape, accessedCols, accessedRows }) {
|
|
98
|
+
const invalidAccesses = [];
|
|
99
|
+
if (operandShape !== undefined) {
|
|
100
|
+
for (const row of accessedRows ?? []) {
|
|
101
|
+
if (!(0, domain_1.satisfiesLeqInterval)(operandShape.rows, row)) {
|
|
102
|
+
invalidAccesses.push({ type: 'row', accessed: row });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
for (const col of accessedCols ?? []) {
|
|
106
|
+
if (typeof col === 'string' && !(0, domain_1.satisfiesColsNames)(operandShape.colnames, col)) {
|
|
107
|
+
invalidAccesses.push({ type: 'column', accessed: col });
|
|
108
|
+
}
|
|
109
|
+
else if (typeof col === 'number' && !(0, domain_1.satisfiesLeqInterval)(operandShape.cols, col)) {
|
|
110
|
+
invalidAccesses.push({ type: 'column', accessed: col });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return invalidAccesses;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=dataframe-access-validation.js.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { LintingResult } from '../linter-format';
|
|
2
|
+
import { LintingCertainty } from '../linter-format';
|
|
3
|
+
import type { MergeableRecord } from '../../util/objects';
|
|
4
|
+
import type { SourceRange } from '../../util/range';
|
|
5
|
+
import type { Identifier } from '../../dataflow/environments/identifier';
|
|
6
|
+
import { LintingRuleTag } from '../linter-tags';
|
|
7
|
+
export interface DeprecatedFunctionsResult extends LintingResult {
|
|
8
|
+
function: string;
|
|
9
|
+
range: SourceRange;
|
|
10
|
+
}
|
|
11
|
+
export interface DeprecatedFunctionsConfig extends MergeableRecord {
|
|
12
|
+
/**
|
|
13
|
+
* The list of function names that should be marked as deprecated.
|
|
14
|
+
*/
|
|
15
|
+
deprecatedFunctions: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface DeprecatedFunctionsMetadata extends MergeableRecord {
|
|
18
|
+
totalDeprecatedCalls: number;
|
|
19
|
+
totalDeprecatedFunctionDefinitions: number;
|
|
20
|
+
}
|
|
21
|
+
export declare const DEPRECATED_FUNCTIONS: {
|
|
22
|
+
readonly createSearch: (config: DeprecatedFunctionsConfig) => import("../../search/flowr-search-builder").FlowrSearchBuilder<"all", ["with", "filter"], import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../../search/flowr-search").FlowrSearchElements<import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, [] | import("../../search/flowr-search").FlowrSearchElement<import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>>;
|
|
23
|
+
readonly processSearchResult: (elements: import("../../search/flowr-search").FlowrSearchElements<import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../../search/flowr-search").FlowrSearchElement<import("../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>[]>) => {
|
|
24
|
+
results: {
|
|
25
|
+
certainty: LintingCertainty.Definitely;
|
|
26
|
+
function: Identifier;
|
|
27
|
+
range: SourceRange;
|
|
28
|
+
}[];
|
|
29
|
+
'.meta': DeprecatedFunctionsMetadata;
|
|
30
|
+
};
|
|
31
|
+
readonly prettyPrint: {
|
|
32
|
+
readonly query: (result: DeprecatedFunctionsResult) => string;
|
|
33
|
+
readonly full: (result: DeprecatedFunctionsResult) => string;
|
|
34
|
+
};
|
|
35
|
+
readonly info: {
|
|
36
|
+
readonly name: "Deprecated Functions";
|
|
37
|
+
readonly tags: readonly [LintingRuleTag.Deprecated, LintingRuleTag.Smell, LintingRuleTag.Usability, LintingRuleTag.Reproducibility];
|
|
38
|
+
readonly description: "Marks deprecated functions that should not be used anymore.";
|
|
39
|
+
readonly defaultConfig: {
|
|
40
|
+
readonly deprecatedFunctions: readonly ["all_equal", "arrange_all", "distinct_all", "filter_all", "group_by_all", "summarise_all", "mutate_all", "select_all", "vars", "all_vars", "id", "failwith", "select_vars", "rename_vars", "select_var", "current_vars", "bench_tbls", "compare_tbls", "compare_tbls2", "eval_tbls", "eval_tbls2", "location", "changes", "combine", "do", "funs", "add_count_", "add_tally_", "arrange_", "count_", "distinct_", "do_", "filter_", "funs_", "group_by_", "group_indices_", "mutate_", "tally_", "transmute_", "rename_", "rename_vars_", "select_", "select_vars_", "slice_", "summarise_", "summarize_", "summarise_each", "src_local", "tbl_df", "add_rownames", "group_nest", "group_split", "with_groups", "nest_by", "progress_estimated", "recode", "sample_n", "top_n", "transmute", "fct_explicit_na", "aes_", "aes_auto", "annotation_logticks", "is.Coord", "coord_flip", "coord_map", "is.facet", "fortify", "is.ggproto", "guide_train", "is.ggplot", "qplot", "is.theme", "gg_dep", "liply", "isplit2", "list_along", "cross", "invoke", "at_depth", "prepend", "rerun", "splice", "`%@%`", "rbernoulli", "rdunif", "when", "update_list", "map_raw", "accumulate", "reduce_right", "flatten", "map_dfr", "as_vector", "transpose", "melt_delim", "melt_fwf", "melt_table", "read_table2", "str_interp", "as_tibble", "data_frame", "tibble_", "data_frame_", "lst_", "as_data_frame", "as.tibble", "frame_data", "trunc_mat", "is.tibble", "tidy_names", "set_tidy_names", "repair_names", "extract_numeric", "complete_", "drop_na_", "expand_", "crossing_", "nesting_", "extract_", "fill_", "gather_", "nest_", "separate_rows_", "separate_", "spread_", "unite_", "unnest_", "extract", "gather", "nest_legacy", "separate_rows", "separate", "spread"];
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEPRECATED_FUNCTIONS = void 0;
|
|
4
|
+
const linter_format_1 = require("../linter-format");
|
|
5
|
+
const flowr_search_builder_1 = require("../../search/flowr-search-builder");
|
|
6
|
+
const dfg_1 = require("../../util/mermaid/dfg");
|
|
7
|
+
const search_enrichers_1 = require("../../search/search-executor/search-enrichers");
|
|
8
|
+
const flowr_search_filters_1 = require("../../search/flowr-search-filters");
|
|
9
|
+
const linter_tags_1 = require("../linter-tags");
|
|
10
|
+
exports.DEPRECATED_FUNCTIONS = {
|
|
11
|
+
createSearch: (config) => flowr_search_builder_1.Q.all()
|
|
12
|
+
.with(search_enrichers_1.Enrichment.CallTargets, { onlyBuiltin: true })
|
|
13
|
+
.filter({
|
|
14
|
+
name: flowr_search_filters_1.FlowrFilter.MatchesEnrichment,
|
|
15
|
+
args: {
|
|
16
|
+
enrichment: search_enrichers_1.Enrichment.CallTargets,
|
|
17
|
+
test: (0, flowr_search_filters_1.testFunctionsIgnoringPackage)(config.deprecatedFunctions)
|
|
18
|
+
}
|
|
19
|
+
}),
|
|
20
|
+
processSearchResult: (elements) => {
|
|
21
|
+
const metadata = {
|
|
22
|
+
totalDeprecatedCalls: 0,
|
|
23
|
+
totalDeprecatedFunctionDefinitions: 0
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
results: elements.getElements()
|
|
27
|
+
.flatMap(element => {
|
|
28
|
+
metadata.totalDeprecatedCalls++;
|
|
29
|
+
return (0, search_enrichers_1.enrichmentContent)(element, search_enrichers_1.Enrichment.CallTargets).targets.map(target => {
|
|
30
|
+
metadata.totalDeprecatedFunctionDefinitions++;
|
|
31
|
+
return {
|
|
32
|
+
range: element.node.info.fullRange,
|
|
33
|
+
target: target
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
})
|
|
37
|
+
.map(element => ({
|
|
38
|
+
certainty: linter_format_1.LintingCertainty.Definitely,
|
|
39
|
+
function: element.target,
|
|
40
|
+
range: element.range
|
|
41
|
+
})),
|
|
42
|
+
'.meta': metadata
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
prettyPrint: {
|
|
46
|
+
[linter_format_1.LintingPrettyPrintContext.Query]: result => `Function \`${result.function}\` at ${(0, dfg_1.formatRange)(result.range)}`,
|
|
47
|
+
[linter_format_1.LintingPrettyPrintContext.Full]: result => `Function \`${result.function}\` called at ${(0, dfg_1.formatRange)(result.range)} is deprecated`
|
|
48
|
+
},
|
|
49
|
+
info: {
|
|
50
|
+
name: 'Deprecated Functions',
|
|
51
|
+
tags: [linter_tags_1.LintingRuleTag.Deprecated, linter_tags_1.LintingRuleTag.Smell, linter_tags_1.LintingRuleTag.Usability, linter_tags_1.LintingRuleTag.Reproducibility],
|
|
52
|
+
description: 'Marks deprecated functions that should not be used anymore.',
|
|
53
|
+
defaultConfig: {
|
|
54
|
+
deprecatedFunctions: ['all_equal', 'arrange_all', 'distinct_all', 'filter_all', 'group_by_all', 'summarise_all', 'mutate_all', 'select_all', 'vars', 'all_vars', 'id', 'failwith', 'select_vars', 'rename_vars', 'select_var', 'current_vars', 'bench_tbls', 'compare_tbls', 'compare_tbls2', 'eval_tbls', 'eval_tbls2', 'location', 'changes', 'combine', 'do', 'funs', 'add_count_', 'add_tally_', 'arrange_', 'count_', 'distinct_', 'do_', 'filter_', 'funs_', 'group_by_', 'group_indices_', 'mutate_', 'tally_', 'transmute_', 'rename_', 'rename_vars_', 'select_', 'select_vars_', 'slice_', 'summarise_', 'summarize_', 'summarise_each', 'src_local', 'tbl_df', 'add_rownames', 'group_nest', 'group_split', 'with_groups', 'nest_by', 'progress_estimated', 'recode', 'sample_n', 'top_n', 'transmute', 'fct_explicit_na', 'aes_', 'aes_auto', 'annotation_logticks', 'is.Coord', 'coord_flip', 'coord_map', 'is.facet', 'fortify', 'is.ggproto', 'guide_train', 'is.ggplot', 'qplot', 'is.theme', 'gg_dep', 'liply', 'isplit2', 'list_along', 'cross', 'invoke', 'at_depth', 'prepend', 'rerun', 'splice', '`%@%`', 'rbernoulli', 'rdunif', 'when', 'update_list', 'map_raw', 'accumulate', 'reduce_right', 'flatten', 'map_dfr', 'as_vector', 'transpose', 'melt_delim', 'melt_fwf', 'melt_table', 'read_table2', 'str_interp', 'as_tibble', 'data_frame', 'tibble_', 'data_frame_', 'lst_', 'as_data_frame', 'as.tibble', 'frame_data', 'trunc_mat', 'is.tibble', 'tidy_names', 'set_tidy_names', 'repair_names', 'extract_numeric', 'complete_', 'drop_na_', 'expand_', 'crossing_', 'nesting_', 'extract_', 'fill_', 'gather_', 'nest_', 'separate_rows_', 'separate_', 'spread_', 'unite_', 'unnest_', 'extract', 'gather', 'nest_legacy', 'separate_rows', 'separate', 'spread',]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=deprecated-functions.js.map
|
|
@@ -4,6 +4,7 @@ import type { SourceRange } from '../../util/range';
|
|
|
4
4
|
import type { ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
|
|
5
5
|
import type { FlowrSearchElementFromQuery } from '../../search/flowr-search';
|
|
6
6
|
import type { FunctionInfo } from '../../queries/catalog/dependencies-query/function-info/function-info';
|
|
7
|
+
import { LintingRuleTag } from '../linter-tags';
|
|
7
8
|
export interface FilePathValidityResult extends LintingResult {
|
|
8
9
|
filePath: string;
|
|
9
10
|
range: SourceRange;
|
|
@@ -30,19 +31,28 @@ export interface FilePathValidityMetadata extends MergeableRecord {
|
|
|
30
31
|
totalWritesBeforeAlways: number;
|
|
31
32
|
totalValid: number;
|
|
32
33
|
}
|
|
33
|
-
export declare const
|
|
34
|
+
export declare const FILE_PATH_VALIDITY: {
|
|
34
35
|
readonly createSearch: (config: FilePathValidityConfig) => import("../../search/flowr-search-builder").FlowrSearchBuilder<"from-query", [], ParentInformation, import("../../search/flowr-search").FlowrSearchElements<ParentInformation, FlowrSearchElementFromQuery<ParentInformation>[]>>;
|
|
35
36
|
readonly processSearchResult: (elements: import("../../search/flowr-search").FlowrSearchElements<ParentInformation, FlowrSearchElementFromQuery<ParentInformation>[]>, config: FilePathValidityConfig, data: {
|
|
36
37
|
normalize: import("../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst;
|
|
37
38
|
dataflow: import("../../dataflow/info").DataflowInformation;
|
|
39
|
+
config: import("../../config").FlowrConfigOptions;
|
|
38
40
|
}) => {
|
|
39
41
|
results: FilePathValidityResult[];
|
|
40
42
|
".meta": FilePathValidityMetadata;
|
|
41
43
|
};
|
|
42
|
-
readonly
|
|
43
|
-
|
|
44
|
-
readonly
|
|
45
|
-
readonly
|
|
46
|
-
readonly
|
|
44
|
+
readonly info: {
|
|
45
|
+
readonly name: "File Path Validity";
|
|
46
|
+
readonly description: "Checks whether file paths used in read and write operations are valid and point to existing files.";
|
|
47
|
+
readonly tags: readonly [LintingRuleTag.Robustness, LintingRuleTag.Reproducibility, LintingRuleTag.Bug];
|
|
48
|
+
readonly defaultConfig: {
|
|
49
|
+
readonly additionalReadFunctions: readonly [];
|
|
50
|
+
readonly additionalWriteFunctions: readonly [];
|
|
51
|
+
readonly includeUnknown: false;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
readonly prettyPrint: {
|
|
55
|
+
readonly query: (result: FilePathValidityResult) => string;
|
|
56
|
+
readonly full: (result: FilePathValidityResult) => string;
|
|
47
57
|
};
|
|
48
58
|
};
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.FILE_PATH_VALIDITY = void 0;
|
|
4
4
|
const linter_format_1 = require("../linter-format");
|
|
5
5
|
const flowr_search_builder_1 = require("../../search/flowr-search-builder");
|
|
6
6
|
const dfg_1 = require("../../util/mermaid/dfg");
|
|
7
7
|
const dependencies_query_format_1 = require("../../queries/catalog/dependencies-query/dependencies-query-format");
|
|
8
8
|
const built_in_source_1 = require("../../dataflow/internal/process/functions/call/built-in/built-in-source");
|
|
9
9
|
const logic_1 = require("../../util/logic");
|
|
10
|
-
const config_1 = require("../../config");
|
|
11
10
|
const retriever_1 = require("../../r-bridge/retriever");
|
|
12
11
|
const read_functions_1 = require("../../queries/catalog/dependencies-query/function-info/read-functions");
|
|
13
12
|
const write_functions_1 = require("../../queries/catalog/dependencies-query/function-info/write-functions");
|
|
14
13
|
const extract_cfg_1 = require("../../control-flow/extract-cfg");
|
|
15
14
|
const happens_before_1 = require("../../control-flow/happens-before");
|
|
16
|
-
|
|
15
|
+
const linter_tags_1 = require("../linter-tags");
|
|
16
|
+
exports.FILE_PATH_VALIDITY = {
|
|
17
17
|
createSearch: (config) => flowr_search_builder_1.Q.fromQuery({
|
|
18
18
|
type: 'dependencies',
|
|
19
19
|
// we only want to check read and write functions, so we explicitly clear all others
|
|
@@ -53,14 +53,14 @@ exports.R2_FILE_PATH_VALIDITY = {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
// check if any write to the same file happens before the read, and exclude this case if so
|
|
56
|
-
const writesToFile = results.writtenData.filter(r => samePath(r.destination, matchingRead.source));
|
|
56
|
+
const writesToFile = results.writtenData.filter(r => samePath(r.destination, matchingRead.source, data.config.solver.resolveSource?.ignoreCapitalization));
|
|
57
57
|
const writesBefore = writesToFile.map(w => (0, happens_before_1.happensBefore)(cfg, w.nodeId, element.node.info.id));
|
|
58
58
|
if (writesBefore.some(w => w === logic_1.Ternary.Always)) {
|
|
59
59
|
metadata.totalWritesBeforeAlways++;
|
|
60
60
|
return [];
|
|
61
61
|
}
|
|
62
62
|
// check if the file exists!
|
|
63
|
-
const paths = (0, built_in_source_1.findSource)(matchingRead.source, {
|
|
63
|
+
const paths = (0, built_in_source_1.findSource)(data.config.solver.resolveSource, matchingRead.source, {
|
|
64
64
|
referenceChain: element.node.info.file ? [(0, retriever_1.requestFromInput)(`file://${element.node.info.file}`)] : []
|
|
65
65
|
});
|
|
66
66
|
if (paths && paths.length) {
|
|
@@ -76,18 +76,26 @@ exports.R2_FILE_PATH_VALIDITY = {
|
|
|
76
76
|
'.meta': metadata
|
|
77
77
|
};
|
|
78
78
|
},
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
info: {
|
|
80
|
+
name: 'File Path Validity',
|
|
81
|
+
description: 'Checks whether file paths used in read and write operations are valid and point to existing files.',
|
|
82
|
+
tags: [linter_tags_1.LintingRuleTag.Robustness, linter_tags_1.LintingRuleTag.Reproducibility, linter_tags_1.LintingRuleTag.Bug],
|
|
83
|
+
defaultConfig: {
|
|
84
|
+
additionalReadFunctions: [],
|
|
85
|
+
additionalWriteFunctions: [],
|
|
86
|
+
includeUnknown: false
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
prettyPrint: {
|
|
90
|
+
[linter_format_1.LintingPrettyPrintContext.Query]: result => `Path \`${result.filePath}\` at ${(0, dfg_1.formatRange)(result.range)}`,
|
|
91
|
+
[linter_format_1.LintingPrettyPrintContext.Full]: result => `Path \`${result.filePath}\` at ${(0, dfg_1.formatRange)(result.range)} does not point to a valid file`
|
|
84
92
|
}
|
|
85
93
|
};
|
|
86
|
-
function samePath(a, b) {
|
|
87
|
-
if (
|
|
94
|
+
function samePath(a, b, ignoreCapitalization) {
|
|
95
|
+
if (ignoreCapitalization === true) {
|
|
88
96
|
a = a.toLowerCase();
|
|
89
97
|
b = b.toLowerCase();
|
|
90
98
|
}
|
|
91
99
|
return a === b;
|
|
92
100
|
}
|
|
93
|
-
//# sourceMappingURL=
|
|
101
|
+
//# sourceMappingURL=file-path-validity.js.map
|