@eagleoutice/flowr 2.9.2 → 2.9.3

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.
Files changed (63) hide show
  1. package/README.md +20 -20
  2. package/core/print/slice-diff-ansi.js +3 -3
  3. package/dataflow/environments/built-in.d.ts +10 -1
  4. package/dataflow/eval/resolve/alias-tracking.d.ts +8 -8
  5. package/dataflow/eval/resolve/alias-tracking.js +33 -34
  6. package/dataflow/eval/resolve/resolve.d.ts +7 -41
  7. package/dataflow/eval/resolve/resolve.js +24 -54
  8. package/dataflow/extractor.js +2 -2
  9. package/dataflow/graph/graph.js +4 -10
  10. package/dataflow/internal/process/functions/call/argument/make-argument.js +1 -2
  11. package/dataflow/internal/process/functions/call/built-in/built-in-register-hook.js +2 -2
  12. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +2 -2
  13. package/dataflow/internal/process/functions/call/built-in/built-in-s-seven-new-generic.js +2 -2
  14. package/dataflow/internal/process/functions/call/built-in/built-in-s-three-dispatch.js +1 -1
  15. package/documentation/doc-util/doc-search.js +2 -2
  16. package/linter/linter-executor.js +1 -2
  17. package/linter/linter-format.d.ts +37 -11
  18. package/linter/linter-format.js +59 -16
  19. package/linter/linter-rules.d.ts +8 -23
  20. package/linter/rules/absolute-path.d.ts +2 -2
  21. package/linter/rules/absolute-path.js +6 -7
  22. package/linter/rules/dataframe-access-validation.d.ts +1 -1
  23. package/linter/rules/dataframe-access-validation.js +3 -4
  24. package/linter/rules/dead-code.d.ts +2 -2
  25. package/linter/rules/dead-code.js +5 -6
  26. package/linter/rules/deprecated-functions.d.ts +4 -7
  27. package/linter/rules/file-path-validity.d.ts +2 -2
  28. package/linter/rules/file-path-validity.js +9 -6
  29. package/linter/rules/function-finder-util.d.ts +8 -11
  30. package/linter/rules/function-finder-util.js +21 -12
  31. package/linter/rules/naming-convention.d.ts +4 -11
  32. package/linter/rules/naming-convention.js +10 -10
  33. package/linter/rules/network-functions.d.ts +5 -8
  34. package/linter/rules/network-functions.js +14 -1
  35. package/linter/rules/seeded-randomness.d.ts +3 -3
  36. package/linter/rules/seeded-randomness.js +5 -5
  37. package/linter/rules/unused-definition.d.ts +2 -2
  38. package/linter/rules/unused-definition.js +13 -14
  39. package/linter/rules/useless-loop.d.ts +3 -3
  40. package/linter/rules/useless-loop.js +4 -4
  41. package/package.json +1 -1
  42. package/project/plugins/file-plugins/files/flowr-namespace-file.js +2 -2
  43. package/queries/catalog/does-call-query/does-call-query-format.js +2 -2
  44. package/queries/catalog/inspect-exceptions-query/inspect-exception-query-format.js +5 -4
  45. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.d.ts +1 -1
  46. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-format.js +5 -4
  47. package/queries/catalog/inspect-recursion-query/inspect-recursion-query-format.js +4 -3
  48. package/queries/catalog/linter-query/linter-query-format.d.ts +1 -1
  49. package/queries/catalog/linter-query/linter-query-format.js +13 -9
  50. package/queries/query.d.ts +1 -1
  51. package/r-bridge/lang-4.x/ast/parser/main/normalize-meta.d.ts +1 -1
  52. package/r-bridge/lang-4.x/ast/parser/main/normalize-meta.js +2 -2
  53. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +1 -1
  54. package/r-bridge/roxygen2/roxygen-parse.js +1 -1
  55. package/statistics/features/supported/defined-functions/defined-functions.d.ts +1 -1
  56. package/statistics/features/supported/defined-functions/defined-functions.js +4 -4
  57. package/statistics/features/supported/used-functions/used-functions.js +3 -3
  58. package/statistics/features/supported/variables/variables.js +4 -4
  59. package/util/mermaid/dfg.d.ts +0 -5
  60. package/util/mermaid/dfg.js +2 -19
  61. package/util/range.d.ts +137 -54
  62. package/util/range.js +249 -88
  63. package/util/version.js +1 -1
package/util/range.d.ts CHANGED
@@ -1,8 +1,10 @@
1
+ import type { RNode } from '../r-bridge/lang-4.x/ast/model/model';
1
2
  /**
2
3
  * A source position in a file.
3
4
  *
4
5
  * Please note that some packages like `xmlparsedata` use their own start and end only to break ties
5
6
  * (e.g., `xmlparsedata` calculates them on a max col width approximation)
7
+ * @see {@link SourceRange|source ranges} for describing ranges of source positions.
6
8
  */
7
9
  export type SourcePosition = [
8
10
  /** starts with 1 */
@@ -11,15 +13,28 @@ export type SourcePosition = [
11
13
  column: number
12
14
  ];
13
15
  /**
16
+ * Utility functions for {@link SourcePosition|source positions}.
17
+ */
18
+ export declare const SourcePosition: {
19
+ /**
20
+ * Formats a {@link SourcePosition|source position} as a human-readable string.
21
+ */
22
+ readonly format: (this: void, pos: SourcePosition | undefined) => string;
23
+ /**
24
+ * Creates a source position from the given line and column numbers.
25
+ * @param line - line number (starts with 1)
26
+ * @param column - column number (starts with 1)
27
+ */
28
+ readonly from: (this: void, line: number | string, column: number | string) => SourcePosition;
29
+ /**
30
+ * returns an invalid source position
31
+ */
32
+ readonly invalid: (this: void) => SourcePosition;
33
+ };
34
+ /**
35
+ * **Please note** that for multi-file projects we also have a {@link SourceLocation|source location} type that includes the file name.
14
36
  * Describe the start and end {@link SourcePosition|source position} of an element.
15
- * @see {@link rangeFrom} - to create a range
16
- * @see {@link mergeRanges} - to merge multiple ranges
17
- * @see {@link getRangeStart} - to get the start of a range
18
- * @see {@link getRangeEnd} - to get the end of a range
19
- * @see {@link rangeStartsCompletelyBefore} - to check if one range starts before another
20
- * @see {@link rangesOverlap} - to check if two ranges overlap
21
- * @see {@link addRanges} - to add two ranges
22
- * @see {@link rangeCompare} - to compare two ranges
37
+ * @see {@link SourceRange.format} and related utility functions for working with source ranges.
23
38
  */
24
39
  export type SourceRange = [
25
40
  /** inclusive start position */
@@ -29,55 +44,123 @@ export type SourceRange = [
29
44
  endLine: number,
30
45
  endColumn: number
31
46
  ];
32
- export declare function getRangeStart(p: undefined): undefined;
33
- export declare function getRangeStart(p: SourceRange): SourcePosition;
34
- export declare function getRangeStart(p: SourceRange | undefined): SourcePosition | undefined;
35
- export declare function getRangeEnd(p: undefined): undefined;
36
- export declare function getRangeEnd(p: SourceRange): SourcePosition;
37
- export declare function getRangeEnd(p: SourceRange | undefined): SourcePosition | undefined;
38
- /**
39
- * This does not ensure ordering of start and end!
40
- * @param sl - start line
41
- * @param sc - start column
42
- * @param el - end line
43
- * @param ec - end column
44
- */
45
- export declare function rangeFrom(sl: number | string, sc: number | string, el: number | string, ec: number | string): SourceRange;
46
- /**
47
- * @returns an invalid source range
48
- */
49
- export declare function invalidRange(): SourceRange;
50
- /**
51
- * Merges multiple source ranges into a single source range that spans from the earliest start to the latest end.
52
- * If you are interested in combining overlapping ranges into a minimal set of ranges, see {@link combineRanges}.
53
- * @throws if no ranges are provided
54
- */
55
- export declare function mergeRanges(rs?: (SourceRange | undefined)[]): SourceRange;
56
47
  /**
57
- * @returns true iff `r1` starts and ends before `r2` starts (i.e., if `r1` and `r2` do not overlap and `r1` comes before `r2`
48
+ * Utility functions for {@link SourceRange|source ranges}.
58
49
  */
59
- export declare function rangeStartsCompletelyBefore([, , r1el, r1ec]: SourceRange, [r2sl, r2sc, ,]: SourceRange): boolean;
50
+ export declare const SourceRange: {
51
+ /**
52
+ * Prints a {@link SourceRange|range} as a human-readable string.
53
+ */
54
+ readonly format: (this: void, range: SourceRange | undefined) => string;
55
+ /**
56
+ * Returns the start position of a source range.
57
+ */
58
+ readonly getStart: (this: void, range: SourceRange) => SourcePosition;
59
+ /**
60
+ * Returns the start line of a source range.
61
+ */
62
+ readonly getStartLine: (this: void, range: SourceRange) => number;
63
+ /**
64
+ * Returns the end position of a source range.
65
+ */
66
+ readonly getEnd: (this: void, range: SourceRange) => SourcePosition;
67
+ /**
68
+ * Returns the end line of a source range.
69
+ */
70
+ readonly getEndLine: (this: void, range: SourceRange) => number;
71
+ /**
72
+ * Creates a source range from the given line and column numbers.
73
+ * @param sl - start line
74
+ * @param sc - start column
75
+ * @param el - end line
76
+ * @param ec - end column
77
+ */
78
+ readonly from: (this: void, sl: number | string, sc: number | string, el?: number | string, ec?: number | string) => SourceRange;
79
+ /**
80
+ * returns an invalid source range
81
+ */
82
+ readonly invalid: (this: void) => SourceRange;
83
+ /**
84
+ * Merges multiple source ranges into a single source range that spans from the earliest start to the latest end.
85
+ * If you are interested in combining overlapping ranges into a minimal set of ranges, see {@link combineRanges}.
86
+ * @throws if no ranges are provided
87
+ */
88
+ readonly merge: (this: void, rs: (SourceRange | undefined)[]) => SourceRange;
89
+ /**
90
+ * @returns true iff `r1` starts and ends before `r2` starts (i.e., if `r1` and `r2` do not overlap and `r1` comes before `r2`
91
+ */
92
+ readonly startsCompletelyBefore: (this: void, [, , r1el, r1ec]: SourceRange, [r2sl, r2sc, ,]: SourceRange) => boolean;
93
+ /**
94
+ * Checks if the two ranges overlap.
95
+ */
96
+ readonly overlap: (this: void, [r1sl, r1sc, r1el, r1ec]: SourceRange, [r2sl, r2sc, r2el, r2ec]: SourceRange) => boolean;
97
+ /**
98
+ * Calculates the component-wise sum of two ranges.
99
+ */
100
+ readonly add: (this: void, [r1sl, r1sc, r1el, r1ec]: SourceRange, [r2sl, r2sc, r2el, r2ec]: SourceRange) => SourceRange;
101
+ /**
102
+ * Provides a comparator for {@link SourceRange}s that sorts them in ascending order.
103
+ * @returns a positive number if `r1` comes after `r2`, a negative number if `r1` comes before `r2`, and `0` if they are equal
104
+ */
105
+ readonly compare: (this: void, [r1sl, r1sc, ,]: SourceRange, [r2sl, r2sc, ,]: SourceRange) => number;
106
+ /**
107
+ * Checks if the first range is a subset of the second range.
108
+ */
109
+ readonly isSubsetOf: (this: void, [r1sl, r1sc, r1el, r1ec]: SourceRange, [r2sl, r2sc, r2el, r2ec]: SourceRange) => boolean;
110
+ /**
111
+ * Combines overlapping or subset ranges into a minimal set of ranges.
112
+ * @see {@link SourceRange.merge} for merging multiple ranges into a single range.
113
+ */
114
+ readonly combineRanges: (this: void, ...ranges: SourceRange[]) => SourceRange[];
115
+ readonly fromNode: <OtherInfo>(this: void, node: RNode<OtherInfo> | undefined) => SourceRange | undefined;
116
+ };
60
117
  /**
61
- * Checks if the two ranges overlap.
118
+ * A source location consisting of a source range and an optional file name.
119
+ * @see {@link SourceLocation.format} and related utility functions for working with source locations.
62
120
  */
63
- export declare function rangesOverlap([r1sl, r1sc, r1el, r1ec]: SourceRange, [r2sl, r2sc, r2el, r2ec]: SourceRange): boolean;
64
- /**
65
- * Calculate the component-wise sum of two ranges
66
- */
67
- export declare function addRanges([r1sl, r1sc, r1el, r1ec]: SourceRange, [r2sl, r2sc, r2el, r2ec]: SourceRange): SourceRange;
68
- /**
69
- * Provides a comparator for {@link SourceRange}s that sorts them in ascending order.
70
- * @returns a positive number if `r1` comes after `r2`, a negative number if `r1` comes before `r2`, and `0` if they are equal
71
- */
72
- export declare function rangeCompare([r1sl, r1sc, ,]: SourceRange, [r2sl, r2sc, ,]: SourceRange): number;
73
- /**
74
- * Checks if the first range is a subset of the second range.
75
- */
76
- export declare function rangeIsSubsetOf([r1sl, r1sc, r1el, r1ec]: SourceRange, [r2sl, r2sc, r2el, r2ec]: SourceRange): boolean;
121
+ export type SourceLocation = [...r: SourceRange, f?: string];
77
122
  /**
78
- * Combines overlapping or subset ranges into a minimal set of ranges.
79
- * If you are interested in merging overlapping ranges, see {@link mergeRanges}.
123
+ * Utility functions for {@link SourceLocation|source locations}.
80
124
  */
81
- export declare function combineRanges(...ranges: SourceRange[]): SourceRange[];
82
- /** A source location consisting of a source range and an optional file name. */
83
- export type SourceLocation = [...r: SourceRange, f?: string];
125
+ export declare const SourceLocation: {
126
+ /**
127
+ * Formats a {@link SourceLocation|source location} as a human-readable string.
128
+ */
129
+ readonly format: (this: void, location: SourceLocation | undefined) => string;
130
+ /**
131
+ * Returns the {@link SourceRange|source range} part of a {@link SourceLocation|source location}.
132
+ */
133
+ readonly getRange: (this: void, location: SourceLocation) => SourceRange;
134
+ readonly getFile: (this: void, location: SourceLocation) => string | undefined;
135
+ /**
136
+ * Returns the file part of a {@link SourceLocation|source location}, or `undefined` if no file is set.
137
+ */
138
+ readonly from: (this: void, range: SourceRange, file?: string) => SourceLocation;
139
+ /**
140
+ * Creates a {@link SourceLocation|source location} from a {@link SourceRange|source range} and a file name.
141
+ * @returns undefined if the given range is undefined
142
+ * @see {@link SourceRange.fromNode} for getting the range from an AST node
143
+ */
144
+ readonly fromNode: <OtherInfo>(this: void, node: RNode<OtherInfo>) => SourceLocation | undefined;
145
+ /**
146
+ * Maps the file part of a {@link SourceLocation|source location} using the given mapper function.
147
+ */
148
+ readonly mapFile: (this: void, loc: SourceLocation, fileMapper: (file: string | undefined) => string) => SourceLocation;
149
+ /**
150
+ * Checks if the first location is a subset of the second location.
151
+ * For this, they must be in the same file!
152
+ * @see {@link SourceRange.isSubsetOf}
153
+ */
154
+ readonly isSubsetOf: (this: void, loc1: SourceLocation, loc2: SourceLocation) => boolean;
155
+ readonly compare: (this: void, loc1: SourceLocation, loc2: SourceLocation) => number;
156
+ /**
157
+ * Returns an invalid source location (i.e., with an invalid range and no file).
158
+ */
159
+ readonly invalid: (this: void) => SourceLocation;
160
+ /**
161
+ * Merges multiple source locations into a single source location that spans from the earliest start to the latest end.
162
+ * If the locations are from different files, `undefined` is returned.
163
+ * Files may be `undefined` themselves, but if there is at least one defined file, they must all be the same defined file for the merge to succeed.
164
+ */
165
+ readonly merge: (this: void, locs: (SourceLocation | undefined)[]) => SourceLocation | undefined;
166
+ };
package/util/range.js CHANGED
@@ -1,99 +1,260 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRangeStart = getRangeStart;
4
- exports.getRangeEnd = getRangeEnd;
5
- exports.rangeFrom = rangeFrom;
6
- exports.invalidRange = invalidRange;
7
- exports.mergeRanges = mergeRanges;
8
- exports.rangeStartsCompletelyBefore = rangeStartsCompletelyBefore;
9
- exports.rangesOverlap = rangesOverlap;
10
- exports.addRanges = addRanges;
11
- exports.rangeCompare = rangeCompare;
12
- exports.rangeIsSubsetOf = rangeIsSubsetOf;
13
- exports.combineRanges = combineRanges;
3
+ exports.SourceLocation = exports.SourceRange = exports.SourcePosition = void 0;
14
4
  const assert_1 = require("./assert");
15
5
  /**
16
- * Returns the start position of a source range.
6
+ * Utility functions for {@link SourcePosition|source positions}.
17
7
  */
18
- function getRangeStart(p) {
19
- return p === undefined ? undefined : [p[0], p[1]];
20
- }
21
- /**
22
- * Returns the end position of a source range.
23
- */
24
- function getRangeEnd(p) {
25
- return p === undefined ? undefined : [p[2], p[3]];
26
- }
27
- /**
28
- * This does not ensure ordering of start and end!
29
- * @param sl - start line
30
- * @param sc - start column
31
- * @param el - end line
32
- * @param ec - end column
33
- */
34
- function rangeFrom(sl, sc, el, ec) {
35
- return [Number(sl), Number(sc), Number(el), Number(ec)];
36
- }
37
- /**
38
- * @returns an invalid source range
39
- */
40
- function invalidRange() {
41
- return [-1, -1, -1, -1];
42
- }
43
- /**
44
- * Merges multiple source ranges into a single source range that spans from the earliest start to the latest end.
45
- * If you are interested in combining overlapping ranges into a minimal set of ranges, see {@link combineRanges}.
46
- * @throws if no ranges are provided
47
- */
48
- function mergeRanges(rs = []) {
49
- const rsSafe = rs.filter(assert_1.isNotUndefined);
50
- (0, assert_1.guard)(rsSafe.length > 0, 'Cannot merge no ranges');
51
- return rsSafe.reduce(([sl, sc, el, ec], [nsl, nsc, nel, nec]) => [
52
- ...(sl < nsl || (sl === nsl && sc < nsc) ? [sl, sc] : [nsl, nsc]),
53
- ...(el > nel || (el === nel && ec > nec) ? [el, ec] : [nel, nec])
54
- ], rsSafe[0]);
55
- }
56
- /**
57
- * @returns true iff `r1` starts and ends before `r2` starts (i.e., if `r1` and `r2` do not overlap and `r1` comes before `r2`
58
- */
59
- function rangeStartsCompletelyBefore([, , r1el, r1ec], [r2sl, r2sc, ,]) {
60
- return r1el < r2sl || (r1el === r2sl && r1ec < r2sc);
61
- }
62
- /**
63
- * Checks if the two ranges overlap.
64
- */
65
- function rangesOverlap([r1sl, r1sc, r1el, r1ec], [r2sl, r2sc, r2el, r2ec]) {
66
- return r1sl <= r2el && r2sl <= r1el && r1sc <= r2ec && r2sc <= r1ec;
67
- }
68
- /**
69
- * Calculate the component-wise sum of two ranges
70
- */
71
- function addRanges([r1sl, r1sc, r1el, r1ec], [r2sl, r2sc, r2el, r2ec]) {
72
- return [r1sl + r2sl, r1sc + r2sc, r1el + r2el, r1ec + r2ec];
73
- }
74
- /**
75
- * Provides a comparator for {@link SourceRange}s that sorts them in ascending order.
76
- * @returns a positive number if `r1` comes after `r2`, a negative number if `r1` comes before `r2`, and `0` if they are equal
77
- */
78
- function rangeCompare([r1sl, r1sc, ,], [r2sl, r2sc, ,]) {
79
- if (r1sl === r2sl) {
80
- return r1sc - r2sc;
81
- }
82
- else {
83
- return r1sl - r2sl;
8
+ exports.SourcePosition = {
9
+ /**
10
+ * Formats a {@link SourcePosition|source position} as a human-readable string.
11
+ */
12
+ format(pos) {
13
+ if (pos === undefined) {
14
+ return '??.??';
15
+ }
16
+ else {
17
+ return `${pos[0]}.${pos[1]}`;
18
+ }
19
+ },
20
+ /**
21
+ * Creates a source position from the given line and column numbers.
22
+ * @param line - line number (starts with 1)
23
+ * @param column - column number (starts with 1)
24
+ */
25
+ from(line, column) {
26
+ return [Number(line), Number(column)];
27
+ },
28
+ /**
29
+ * returns an invalid source position
30
+ */
31
+ invalid() {
32
+ return [-1, -1];
84
33
  }
85
- }
34
+ };
86
35
  /**
87
- * Checks if the first range is a subset of the second range.
36
+ * Utility functions for {@link SourceRange|source ranges}.
88
37
  */
89
- function rangeIsSubsetOf([r1sl, r1sc, r1el, r1ec], [r2sl, r2sc, r2el, r2ec]) {
90
- return (r1sl > r2sl || r1sl === r2sl && r1sc >= r2sc) && (r1el < r2el || r1sl === r2sl && r1ec <= r2ec);
91
- }
38
+ exports.SourceRange = {
39
+ /**
40
+ * Prints a {@link SourceRange|range} as a human-readable string.
41
+ */
42
+ format(range) {
43
+ if (range === undefined) {
44
+ return '??-??';
45
+ }
46
+ else if (range[0] === range[2]) {
47
+ if (range[1] === range[3]) {
48
+ return `${range[0]}.${range[1]}`;
49
+ }
50
+ else {
51
+ return `${range[0]}.${range[1]}-${range[3]}`;
52
+ }
53
+ }
54
+ return `${range[0]}.${range[1]}-${range[2]}.${range[3]}`;
55
+ },
56
+ /**
57
+ * Returns the start position of a source range.
58
+ */
59
+ getStart(range) {
60
+ return [range[0], range[1]];
61
+ },
62
+ /**
63
+ * Returns the start line of a source range.
64
+ */
65
+ getStartLine(range) {
66
+ return range[0];
67
+ },
68
+ /**
69
+ * Returns the end position of a source range.
70
+ */
71
+ getEnd(range) {
72
+ return [range[2], range[3]];
73
+ },
74
+ /**
75
+ * Returns the end line of a source range.
76
+ */
77
+ getEndLine(range) {
78
+ return range[2];
79
+ },
80
+ /**
81
+ * Creates a source range from the given line and column numbers.
82
+ * @param sl - start line
83
+ * @param sc - start column
84
+ * @param el - end line
85
+ * @param ec - end column
86
+ */
87
+ from(sl, sc, el = sl, ec = sc) {
88
+ return [Number(sl), Number(sc), Number(el), Number(ec)];
89
+ },
90
+ /**
91
+ * returns an invalid source range
92
+ */
93
+ invalid() {
94
+ return [-1, -1, -1, -1];
95
+ },
96
+ /**
97
+ * Merges multiple source ranges into a single source range that spans from the earliest start to the latest end.
98
+ * If you are interested in combining overlapping ranges into a minimal set of ranges, see {@link combineRanges}.
99
+ * @throws if no ranges are provided
100
+ */
101
+ merge(rs) {
102
+ const rsSafe = rs.filter(assert_1.isNotUndefined);
103
+ (0, assert_1.guard)(rsSafe.length > 0, 'Cannot merge no ranges');
104
+ return rsSafe.reduce(([sl, sc, el, ec], [nsl, nsc, nel, nec]) => [
105
+ ...(sl < nsl || (sl === nsl && sc < nsc) ? [sl, sc] : [nsl, nsc]),
106
+ ...(el > nel || (el === nel && ec > nec) ? [el, ec] : [nel, nec])
107
+ ], rsSafe[0]);
108
+ },
109
+ /**
110
+ * @returns true iff `r1` starts and ends before `r2` starts (i.e., if `r1` and `r2` do not overlap and `r1` comes before `r2`
111
+ */
112
+ startsCompletelyBefore([, , r1el, r1ec], [r2sl, r2sc, ,]) {
113
+ return r1el < r2sl || (r1el === r2sl && r1ec < r2sc);
114
+ },
115
+ /**
116
+ * Checks if the two ranges overlap.
117
+ */
118
+ overlap([r1sl, r1sc, r1el, r1ec], [r2sl, r2sc, r2el, r2ec]) {
119
+ return r1sl <= r2el && r2sl <= r1el && r1sc <= r2ec && r2sc <= r1ec;
120
+ },
121
+ /**
122
+ * Calculates the component-wise sum of two ranges.
123
+ */
124
+ add([r1sl, r1sc, r1el, r1ec], [r2sl, r2sc, r2el, r2ec]) {
125
+ return [r1sl + r2sl, r1sc + r2sc, r1el + r2el, r1ec + r2ec];
126
+ },
127
+ /**
128
+ * Provides a comparator for {@link SourceRange}s that sorts them in ascending order.
129
+ * @returns a positive number if `r1` comes after `r2`, a negative number if `r1` comes before `r2`, and `0` if they are equal
130
+ */
131
+ compare([r1sl, r1sc, ,], [r2sl, r2sc, ,]) {
132
+ if (r1sl === r2sl) {
133
+ return r1sc - r2sc;
134
+ }
135
+ else {
136
+ return r1sl - r2sl;
137
+ }
138
+ },
139
+ /**
140
+ * Checks if the first range is a subset of the second range.
141
+ */
142
+ isSubsetOf([r1sl, r1sc, r1el, r1ec], [r2sl, r2sc, r2el, r2ec]) {
143
+ return (r1sl > r2sl || r1sl === r2sl && r1sc >= r2sc) && (r1el < r2el || r1sl === r2sl && r1ec <= r2ec);
144
+ },
145
+ /**
146
+ * Combines overlapping or subset ranges into a minimal set of ranges.
147
+ * @see {@link SourceRange.merge} for merging multiple ranges into a single range.
148
+ */
149
+ combineRanges(...ranges) {
150
+ return ranges.filter(range => !ranges.some(other => range !== other && exports.SourceRange.isSubsetOf(range, other)));
151
+ },
152
+ fromNode(node) {
153
+ return node?.info.fullRange ?? node?.location;
154
+ }
155
+ };
92
156
  /**
93
- * Combines overlapping or subset ranges into a minimal set of ranges.
94
- * If you are interested in merging overlapping ranges, see {@link mergeRanges}.
157
+ * Utility functions for {@link SourceLocation|source locations}.
95
158
  */
96
- function combineRanges(...ranges) {
97
- return ranges.filter(range => !ranges.some(other => range !== other && rangeIsSubsetOf(range, other)));
98
- }
159
+ exports.SourceLocation = {
160
+ /**
161
+ * Formats a {@link SourceLocation|source location} as a human-readable string.
162
+ */
163
+ format(location) {
164
+ if (location === undefined) {
165
+ return '??:??-??';
166
+ }
167
+ else if (location[4] !== undefined) {
168
+ return `${location[4]}:${exports.SourceRange.format(location)}`;
169
+ }
170
+ else {
171
+ return exports.SourceRange.format(location);
172
+ }
173
+ },
174
+ /**
175
+ * Returns the {@link SourceRange|source range} part of a {@link SourceLocation|source location}.
176
+ */
177
+ getRange(location) {
178
+ return location;
179
+ },
180
+ getFile(location) {
181
+ return location[4];
182
+ },
183
+ /**
184
+ * Returns the file part of a {@link SourceLocation|source location}, or `undefined` if no file is set.
185
+ */
186
+ from(range, file) {
187
+ return file !== undefined ? [...range, file] : range;
188
+ },
189
+ /**
190
+ * Creates a {@link SourceLocation|source location} from a {@link SourceRange|source range} and a file name.
191
+ * @returns undefined if the given range is undefined
192
+ * @see {@link SourceRange.fromNode} for getting the range from an AST node
193
+ */
194
+ fromNode(node) {
195
+ const range = exports.SourceRange.fromNode(node);
196
+ return range !== undefined ? exports.SourceLocation.from(range, node.info.file) : undefined;
197
+ },
198
+ /**
199
+ * Maps the file part of a {@link SourceLocation|source location} using the given mapper function.
200
+ */
201
+ mapFile(loc, fileMapper) {
202
+ const range = exports.SourceLocation.getRange(loc);
203
+ const file = loc[4];
204
+ return exports.SourceLocation.from(range, fileMapper(file));
205
+ },
206
+ /**
207
+ * Checks if the first location is a subset of the second location.
208
+ * For this, they must be in the same file!
209
+ * @see {@link SourceRange.isSubsetOf}
210
+ */
211
+ isSubsetOf(loc1, loc2) {
212
+ if (exports.SourceLocation.getFile(loc1) !== exports.SourceLocation.getFile(loc2)) {
213
+ return false;
214
+ }
215
+ return exports.SourceRange.isSubsetOf(exports.SourceLocation.getRange(loc1), exports.SourceLocation.getRange(loc2));
216
+ },
217
+ compare(loc1, loc2) {
218
+ const res = exports.SourceRange.compare(exports.SourceLocation.getRange(loc1), exports.SourceLocation.getRange(loc2));
219
+ if (res !== 0) {
220
+ return res;
221
+ }
222
+ const file1 = exports.SourceLocation.getFile(loc1);
223
+ const file2 = exports.SourceLocation.getFile(loc2);
224
+ if (file1 === file2) {
225
+ return 0;
226
+ }
227
+ else if (file1 === undefined) {
228
+ return -1;
229
+ }
230
+ else if (file2 === undefined) {
231
+ return 1;
232
+ }
233
+ else {
234
+ return file1 < file2 ? -1 : 1;
235
+ }
236
+ },
237
+ /**
238
+ * Returns an invalid source location (i.e., with an invalid range and no file).
239
+ */
240
+ invalid() {
241
+ return exports.SourceRange.invalid();
242
+ },
243
+ /**
244
+ * Merges multiple source locations into a single source location that spans from the earliest start to the latest end.
245
+ * If the locations are from different files, `undefined` is returned.
246
+ * Files may be `undefined` themselves, but if there is at least one defined file, they must all be the same defined file for the merge to succeed.
247
+ */
248
+ merge(locs) {
249
+ const locsSafe = locs.filter(assert_1.isNotUndefined);
250
+ if (locsSafe.length === 0) {
251
+ return undefined;
252
+ }
253
+ const firstFile = locsSafe.find(loc => loc[4] !== undefined)?.[4];
254
+ if (locsSafe.some(loc => loc[4] !== undefined && loc[4] !== firstFile)) {
255
+ return undefined;
256
+ }
257
+ return exports.SourceLocation.from(exports.SourceRange.merge(locsSafe.map(exports.SourceLocation.getRange)), firstFile);
258
+ }
259
+ };
99
260
  //# sourceMappingURL=range.js.map
package/util/version.js CHANGED
@@ -6,7 +6,7 @@ exports.printVersionInformation = printVersionInformation;
6
6
  const semver_1 = require("semver");
7
7
  const assert_1 = require("./assert");
8
8
  // this is automatically replaced with the current version by release-it
9
- const version = '2.9.2';
9
+ const version = '2.9.3';
10
10
  /**
11
11
  * Retrieves the current flowR version as a new {@link SemVer} object.
12
12
  */