lineRange.ts ×40

Frontier kind: Code frontier

unlabeled · c_c7e9fef2281c

3285 tests · 4020 LOC · 22 files · introduces 0 tests · 148 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
40 ranges148 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
617 ranges4020 lines · 22 files · Browse complete extent
All tests (intent)
3285 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 148 introduced LOC across 40 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/editor/common/core/ranges/lineRange.ts 148 introduced LOC · 40 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- lineRange.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { BugIndicatingError } from '../../../../base/common/errors.js';
7 > import { OffsetRange } from './offsetRange.js';
8 > import { IRange, Range } from '../range.js';
9 > import { findFirstIdxMonotonousOrArrLen, findLastIdxMonotonous, findLastMonotonous } from '../../../../base/common/arraysFind.js';
10 > import { Comparator, compareBy, numberComparator } from '../../../../base/common/arrays.js';
11 >
12 > /**
13 > * A range of lines (1-based).
14 > */
15 > export class LineRange {
16 > public static ofLength(startLineNumber: number, length: number): LineRange {
17 return new LineRange(startLineNumber, startLineNumber + length);
18 }
20 > public static fromRange(range: IRange): LineRange {
21 return new LineRange(range.startLineNumber, range.endLineNumber);
22 }
24 > public static fromRangeInclusive(range: IRange): LineRange {
25 return new LineRange(range.startLineNumber, range.endLineNumber + 1);
26 }
28 > public static readonly compareByStart: Comparator<LineRange> = compareBy(l => l.startLineNumber, numberComparator);
29 >
30 > public static subtract(a: LineRange, b: LineRange | undefined): LineRange[] {
31 if (!b) {
32 return [a];
45 }
46 }
48 > /**
49 > * @param lineRanges An array of arrays of of sorted line ranges.
50 > */
51 > public static joinMany(lineRanges: readonly (readonly LineRange[])[]): readonly LineRange[] {
52 if (lineRanges.length === 0) {
53 return [];
59 return result.ranges;
60 }
62 > public static join(lineRanges: LineRange[]): LineRange {
63 if (lineRanges.length === 0) {
64 throw new BugIndicatingError('lineRanges cannot be empty');
72 return new LineRange(startLineNumber, endLineNumberExclusive);
73 }
75 > /**
76 > * @internal
77 > */
78 > public static deserialize(lineRange: ISerializedLineRange): LineRange {
79 return new LineRange(lineRange[0], lineRange[1]);
80 }
82 > /**
83 > * The start line number.
84 > */
85 > public readonly startLineNumber: number;
86 >
87 > /**
88 > * The end line number (exclusive).
89 > */
90 > public readonly endLineNumberExclusive: number;
91 >
92 > constructor(
93 startLineNumber: number,
94 endLineNumberExclusive: number,
100 this.endLineNumberExclusive = endLineNumberExclusive;
101 }
102 > lineRange.ts
103 > /**
104 > * Indicates if this line range contains the given line number.
105 > */
106 > public contains(lineNumber: number): boolean {
107 return this.startLineNumber <= lineNumber && lineNumber < this.endLineNumberExclusive;
108 }
109 > lineRange.ts
110 > public containsRange(range: LineRange): boolean {
111 return this.startLineNumber <= range.startLineNumber && range.endLineNumberExclusive <= this.endLineNumberExclusive;
112 }
113 > lineRange.ts
114 > /**
115 > * Indicates if this line range is empty.
116 > */
117 > get isEmpty(): boolean {
118 return this.startLineNumber === this.endLineNumberExclusive;
119 }
120 > lineRange.ts
121 > /**
122 > * Moves this line range by the given offset of line numbers.
123 > */
124 > public delta(offset: number): LineRange {
125 return new LineRange(this.startLineNumber + offset, this.endLineNumberExclusive + offset);
126 }
127 > lineRange.ts
128 > public deltaLength(offset: number): LineRange {
129 return new LineRange(this.startLineNumber, this.endLineNumberExclusive + offset);
130 }
131 > lineRange.ts
132 > /**
133 > * The number of lines this line range spans.
134 > */
135 > public get length(): number {
136 return this.endLineNumberExclusive - this.startLineNumber;
137 }
138 > lineRange.ts
139 > /**
140 > * Creates a line range that combines this and the given line range.
141 > */
142 > public join(other: LineRange): LineRange {
143 return new LineRange(
144 Math.min(this.startLineNumber, other.startLineNumber),
146 );
147 }
148 > lineRange.ts
149 > public toString(): string {
150 return `[${this.startLineNumber},${this.endLineNumberExclusive})`;
151 }
152 > lineRange.ts
153 > /**
154 > * The resulting range is empty if the ranges do not intersect, but touch.
155 > * If the ranges don't even touch, the result is undefined.
156 > */
157 > public intersect(other: LineRange): LineRange | undefined {
158 const startLineNumber = Math.max(this.startLineNumber, other.startLineNumber);
159 const endLineNumberExclusive = Math.min(this.endLineNumberExclusive, other.endLineNumberExclusive);
163 return undefined;
164 }
165 > lineRange.ts
166 > public intersectsStrict(other: LineRange): boolean {
167 return this.startLineNumber < other.endLineNumberExclusive && other.startLineNumber < this.endLineNumberExclusive;
168 }
169 > lineRange.ts
170 > public intersectsOrTouches(other: LineRange): boolean {
171 return this.startLineNumber <= other.endLineNumberExclusive && other.startLineNumber <= this.endLineNumberExclusive;
172 }
173 > lineRange.ts
174 > public equals(b: LineRange): boolean {
175 return this.startLineNumber === b.startLineNumber && this.endLineNumberExclusive === b.endLineNumberExclusive;
176 }
177 > lineRange.ts
178 > public toInclusiveRange(): Range | null {
179 if (this.isEmpty) {
180 return null;
182 return new Range(this.startLineNumber, 1, this.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER);
183 }
184 > lineRange.ts
185 > /**
186 > * @deprecated Using this function is discouraged because it might lead to bugs: The end position is not guaranteed to be a valid position!
187 > */
188 > public toExclusiveRange(): Range {
189 return new Range(this.startLineNumber, 1, this.endLineNumberExclusive, 1);
190 }
191 > lineRange.ts
192 > public mapToLineArray<T>(f: (lineNumber: number) => T): T[] {
193 const result: T[] = [];
194 for (let lineNumber = this.startLineNumber; lineNumber < this.endLineNumberExclusive; lineNumber++) {
197 return result;
198 }
199 > lineRange.ts
200 > public forEach(f: (lineNumber: number) => void): void {
201 for (let lineNumber = this.startLineNumber; lineNumber < this.endLineNumberExclusive; lineNumber++) {
202 f(lineNumber);
203 }
204 }
205 > lineRange.ts
206 > /**
207 > * @internal
208 > */
209 > public serialize(): ISerializedLineRange {
210 return [this.startLineNumber, this.endLineNumberExclusive];
211 }
212 > lineRange.ts
213 > /**
214 > * Converts this 1-based line range to a 0-based offset range (subtracts 1!).
215 > * @internal
216 > */
217 > public toOffsetRange(): OffsetRange {
218 return new OffsetRange(this.startLineNumber - 1, this.endLineNumberExclusive - 1);
219 }
220 > lineRange.ts
221 > public distanceToRange(other: LineRange): number {
222 if (this.endLineNumberExclusive <= other.startLineNumber) {
223 return other.startLineNumber - this.endLineNumberExclusive;
228 return 0;
229 }
230 > lineRange.ts
231 > public distanceToLine(lineNumber: number): number {
232 if (this.contains(lineNumber)) {
233 return 0;
238 return lineNumber - this.endLineNumberExclusive;
239 }
240 > lineRange.ts
241 > public addMargin(marginTop: number, marginBottom: number): LineRange {
242 return new LineRange(
243 this.startLineNumber - marginTop,
245 );
246 }
247 > } lineRange.ts
248 >
249 > export type ISerializedLineRange = [startLineNumber: number, endLineNumberExclusive: number];
250 >
251 >
252 > export class LineRangeSet {
253 > constructor(
254 /**
255 * Sorted by start line number.
259 ) {
260 }
261 > lineRange.ts
262 > get ranges(): readonly LineRange[] {
263 return this._normalizedRanges;
264 }
265 > lineRange.ts
266 > addRange(range: LineRange): void {
267 if (range.length === 0) {
268 return;
290 }
291 }
292 > lineRange.ts
293 > contains(lineNumber: number): boolean {
294 const rangeThatStartsBeforeEnd = findLastMonotonous(this._normalizedRanges, r => r.startLineNumber <= lineNumber);
295 return !!rangeThatStartsBeforeEnd && rangeThatStartsBeforeEnd.endLineNumberExclusive > lineNumber;
296 }
297 > lineRange.ts
298 > intersects(range: LineRange): boolean {
299 const rangeThatStartsBeforeEnd = findLastMonotonous(this._normalizedRanges, r => r.startLineNumber < range.endLineNumberExclusive);
300 return !!rangeThatStartsBeforeEnd && rangeThatStartsBeforeEnd.endLineNumberExclusive > range.startLineNumber;
301 }
302 > lineRange.ts
303 > getUnion(other: LineRangeSet): LineRangeSet {
304 if (this._normalizedRanges.length === 0) {
305 return other;
351 return new LineRangeSet(result);
352 }
353 > lineRange.ts
354 > /**
355 > * Subtracts all ranges in this set from `range` and returns the result.
356 > */
357 > subtractFrom(range: LineRange): LineRangeSet {
358 // idx of first element that touches range or that is after range
359 const joinRangeStartIdx = findFirstIdxMonotonousOrArrLen(this._normalizedRanges, r => r.endLineNumberExclusive >= range.startLineNumber);
380 return new LineRangeSet(result);
381 }
382 > lineRange.ts
383 > toString() {
384 return this._normalizedRanges.map(r => r.toString()).join(', ');
385 }
386 > lineRange.ts
387 > getIntersection(other: LineRangeSet): LineRangeSet {
388 const result: LineRange[] = [];
389
408 return new LineRangeSet(result);
409 }
410 > lineRange.ts
411 > getWithDelta(value: number): LineRangeSet {
412 return new LineRangeSet(this._normalizedRanges.map(r => r.delta(value)));
413 }
414 > } lineRange.ts