1 | /**
|
2 | * Efficiently references a range of text from a string buffer.
|
3 | */
|
4 | var TextRange = /** @class */ (function () {
|
5 | function TextRange(buffer, pos, end) {
|
6 | this.buffer = buffer;
|
7 | this.pos = pos;
|
8 | this.end = end;
|
9 | this._validateBounds();
|
10 | }
|
11 | /**
|
12 | * Constructs a TextRange that corresponds to an entire string object.
|
13 | */
|
14 | TextRange.fromString = function (buffer) {
|
15 | return new TextRange(buffer, 0, buffer.length);
|
16 | };
|
17 | /**
|
18 | * Constructs a TextRange that corresponds to an entire string object.
|
19 | */
|
20 | TextRange.fromStringRange = function (buffer, pos, end) {
|
21 | return new TextRange(buffer, pos, end);
|
22 | };
|
23 | Object.defineProperty(TextRange.prototype, "length", {
|
24 | /**
|
25 | * Returns the length of the text range.
|
26 | * @remarks
|
27 | * This value is calculated as the `end` property minus the `pos` property.
|
28 | */
|
29 | get: function () {
|
30 | return this.end - this.pos;
|
31 | },
|
32 | enumerable: false,
|
33 | configurable: true
|
34 | });
|
35 | /**
|
36 | * Constructs a TextRange that corresponds to a different range of an existing buffer.
|
37 | */
|
38 | TextRange.prototype.getNewRange = function (pos, end) {
|
39 | return new TextRange(this.buffer, pos, end);
|
40 | };
|
41 | /**
|
42 | * Returns true if the length of the range is zero. Note that the object reference may not
|
43 | * be equal to `TextRange.empty`, and the buffer may be different.
|
44 | */
|
45 | TextRange.prototype.isEmpty = function () {
|
46 | return this.pos === this.end;
|
47 | };
|
48 | /**
|
49 | * Returns the range from the associated string buffer.
|
50 | */
|
51 | TextRange.prototype.toString = function () {
|
52 | return this.buffer.substring(this.pos, this.end);
|
53 | };
|
54 | /**
|
55 | * Returns a debugging dump of the range, indicated via custom delimiters.
|
56 | * @remarks
|
57 | * For example if the delimiters are "[" and "]", and the range is 3..5 inside "1234567",
|
58 | * then the output would be "12[345]67".
|
59 | */
|
60 | TextRange.prototype.getDebugDump = function (posDelimiter, endDelimiter) {
|
61 | return (this.buffer.substring(0, this.pos) +
|
62 | posDelimiter +
|
63 | this.buffer.substring(this.pos, this.end) +
|
64 | endDelimiter +
|
65 | this.buffer.substring(this.end));
|
66 | };
|
67 | /**
|
68 | * Calculates the line and column number for the specified offset into the buffer.
|
69 | *
|
70 | * @remarks
|
71 | * This is a potentially expensive operation.
|
72 | *
|
73 | * @param index - an integer offset
|
74 | * @param buffer - the buffer
|
75 | */
|
76 | TextRange.prototype.getLocation = function (index) {
|
77 | if (index < 0 || index > this.buffer.length) {
|
78 | // No match
|
79 | return { line: 0, column: 0 };
|
80 | }
|
81 | // TODO: Consider caching or optimizing this somehow
|
82 | var line = 1;
|
83 | var column = 1;
|
84 | var currentIndex = 0;
|
85 | while (currentIndex < index) {
|
86 | var current = this.buffer[currentIndex];
|
87 | ++currentIndex;
|
88 | if (current === '\r') {
|
89 | // CR
|
90 | // Ignore '\r' and assume it will always have an accompanying '\n'
|
91 | continue;
|
92 | }
|
93 | if (current === '\n') {
|
94 | // LF
|
95 | ++line;
|
96 | column = 1;
|
97 | }
|
98 | else {
|
99 | // NOTE: For consistency with the TypeScript compiler, a tab character is assumed
|
100 | // to advance by one column
|
101 | ++column;
|
102 | }
|
103 | }
|
104 | return { line: line, column: column };
|
105 | };
|
106 | TextRange.prototype._validateBounds = function () {
|
107 | if (this.pos < 0) {
|
108 | throw new Error('TextRange.pos cannot be negative');
|
109 | }
|
110 | if (this.end < 0) {
|
111 | throw new Error('TextRange.end cannot be negative');
|
112 | }
|
113 | if (this.end < this.pos) {
|
114 | throw new Error('TextRange.end cannot be smaller than TextRange.pos');
|
115 | }
|
116 | if (this.pos > this.buffer.length) {
|
117 | throw new Error('TextRange.pos cannot exceed the associated text buffer length');
|
118 | }
|
119 | if (this.end > this.buffer.length) {
|
120 | throw new Error('TextRange.end cannot exceed the associated text buffer length');
|
121 | }
|
122 | };
|
123 | /**
|
124 | * Used to represent an empty or unknown range.
|
125 | */
|
126 | TextRange.empty = new TextRange('', 0, 0);
|
127 | return TextRange;
|
128 | }());
|
129 | export { TextRange };
|
130 | //# sourceMappingURL=TextRange.js.map |
\ | No newline at end of file |