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