UNPKG

4.05 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.isLineBreak = void 0;
4function isLineBreak(ch) {
5 // ES5 7.3:
6 // The ECMAScript line terminator characters are listed in Table 3.
7 // Table 3: Line Terminator Characters
8 // Code Unit Value Name Formal Name
9 // \u000A Line Feed <LF>
10 // \u000D Carriage Return <CR>
11 // \u2028 Line separator <LS>
12 // \u2029 Paragraph separator <PS>
13 // Only the characters in Table 3 are treated as line terminators. Other new line or line
14 // breaking characters are treated as white space but not as line terminators.
15 return (ch === 10 /* LineFeed */ ||
16 ch === 13 /* CarriageReturn */ ||
17 ch === 8232 /* LineSeparator */ ||
18 ch === 8233 /* ParagraphSeparator */);
19}
20exports.isLineBreak = isLineBreak;
21class SourceFile {
22 constructor(file) {
23 this.file = file;
24 this.lineStarts = this.computeLineStarts();
25 }
26 get name() {
27 return this.file.name;
28 }
29 get content() {
30 return this.file.textContent;
31 }
32 getLocation(range) {
33 return {
34 end: this.getPosition(range[1]),
35 start: this.getPosition(range[0]),
36 };
37 }
38 getPosition(pos) {
39 let lineNumber = this.binarySearch(pos);
40 if (lineNumber < 0) {
41 // If the actual position was not found,
42 // the binary search returns the 2's-complement of the next line start
43 // e.g. if the line starts at [5, 10, 23, 80] and the position requested was 20
44 // then the search will return -2.
45 //
46 // We want the index of the previous line start, so we subtract 1.
47 // Review 2's-complement if this is confusing.
48 lineNumber = ~lineNumber - 1;
49 }
50 return {
51 column: pos - this.lineStarts[lineNumber],
52 line: lineNumber,
53 };
54 }
55 /**
56 * Performs a binary search, finding the index at which 'value' occurs in 'array'.
57 * If no such index is found, returns the 2's-complement of first index at which
58 * number[index] exceeds number.
59 * @param array A sorted array whose first element must be no larger than number
60 * @param number The value to be searched for in the array.
61 */
62 binarySearch(position, offset = 0) {
63 let low = offset;
64 let high = this.lineStarts.length - 1;
65 while (low <= high) {
66 const middle = low + ((high - low) >> 1);
67 const midValue = this.lineStarts[middle];
68 if (midValue === position) {
69 return middle;
70 }
71 else if (midValue > position) {
72 high = middle - 1;
73 }
74 else {
75 low = middle + 1;
76 }
77 }
78 return ~low;
79 }
80 computeLineStarts() {
81 const result = [];
82 let pos = 0;
83 let lineStart = 0;
84 const markLineStart = () => {
85 result.push(lineStart);
86 lineStart = pos;
87 };
88 while (pos < this.file.textContent.length) {
89 const ch = this.file.textContent.charCodeAt(pos);
90 pos++;
91 switch (ch) {
92 case 13 /* CarriageReturn */:
93 if (this.file.textContent.charCodeAt(pos) === 10 /* LineFeed */) {
94 pos++;
95 }
96 markLineStart();
97 break;
98 case 10 /* LineFeed */:
99 markLineStart();
100 break;
101 default:
102 if (ch > 127 /* MaxAsciiCharacter */ && isLineBreak(ch)) {
103 markLineStart();
104 }
105 break;
106 }
107 }
108 result.push(lineStart);
109 return result;
110 }
111}
112exports.default = SourceFile;
113//# sourceMappingURL=SourceFile.js.map
\No newline at end of file