{"version":3,"file":"TextRange.js","sourceRoot":"","sources":["../../src/parser/TextRange.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Text coordinates represented as a line number and column number.\r\n *\r\n * @remarks\r\n * The first character in a file is considered to be in column 1 of line 1.\r\n * The location with column 0 and line 0 is used to represent an empty, unspecified,\r\n * or unknown location.\r\n */\r\nexport interface ITextLocation {\r\n line: number;\r\n column: number;\r\n}\r\n\r\n/**\r\n * Efficiently references a range of text from a string buffer.\r\n */\r\nexport class TextRange {\r\n /**\r\n * Used to represent an empty or unknown range.\r\n */\r\n public static readonly empty: TextRange = new TextRange('', 0, 0);\r\n\r\n /**\r\n * The starting index into the associated text buffer.\r\n *\r\n * @remarks\r\n * The text range corresponds to the `range.buffer.substring(range.pos, range.end)`.\r\n */\r\n public readonly pos: number;\r\n\r\n /**\r\n * The (non-inclusive) ending index for the associated text buffer.\r\n *\r\n * @remarks\r\n * The text range corresponds to the `range.buffer.substring(range.pos, range.end)`.\r\n */\r\n public readonly end: number;\r\n\r\n /**\r\n * The string buffer that the `pos` and `end` indexes refer to.\r\n */\r\n public readonly buffer: string;\r\n\r\n private constructor(buffer: string, pos: number, end: number) {\r\n this.buffer = buffer;\r\n this.pos = pos;\r\n this.end = end;\r\n this._validateBounds();\r\n }\r\n\r\n /**\r\n * Constructs a TextRange that corresponds to an entire string object.\r\n */\r\n public static fromString(buffer: string): TextRange {\r\n return new TextRange(buffer, 0, buffer.length);\r\n }\r\n\r\n /**\r\n * Constructs a TextRange that corresponds to an entire string object.\r\n */\r\n public static fromStringRange(buffer: string, pos: number, end: number): TextRange {\r\n return new TextRange(buffer, pos, end);\r\n }\r\n\r\n /**\r\n * Returns the length of the text range.\r\n * @remarks\r\n * This value is calculated as the `end` property minus the `pos` property.\r\n */\r\n public get length(): number {\r\n return this.end - this.pos;\r\n }\r\n\r\n /**\r\n * Constructs a TextRange that corresponds to a different range of an existing buffer.\r\n */\r\n public getNewRange(pos: number, end: number): TextRange {\r\n return new TextRange(this.buffer, pos, end);\r\n }\r\n\r\n /**\r\n * Returns true if the length of the range is zero. Note that the object reference may not\r\n * be equal to `TextRange.empty`, and the buffer may be different.\r\n */\r\n public isEmpty(): boolean {\r\n return this.pos === this.end;\r\n }\r\n\r\n /**\r\n * Returns the range from the associated string buffer.\r\n */\r\n public toString(): string {\r\n return this.buffer.substring(this.pos, this.end);\r\n }\r\n\r\n /**\r\n * Returns a debugging dump of the range, indicated via custom delimiters.\r\n * @remarks\r\n * For example if the delimiters are \"[\" and \"]\", and the range is 3..5 inside \"1234567\",\r\n * then the output would be \"12[345]67\".\r\n */\r\n public getDebugDump(posDelimiter: string, endDelimiter: string): string {\r\n return (\r\n this.buffer.substring(0, this.pos) +\r\n posDelimiter +\r\n this.buffer.substring(this.pos, this.end) +\r\n endDelimiter +\r\n this.buffer.substring(this.end)\r\n );\r\n }\r\n\r\n /**\r\n * Calculates the line and column number for the specified offset into the buffer.\r\n *\r\n * @remarks\r\n * This is a potentially expensive operation.\r\n *\r\n * @param index - an integer offset\r\n * @param buffer - the buffer\r\n */\r\n public getLocation(index: number): ITextLocation {\r\n if (index < 0 || index > this.buffer.length) {\r\n // No match\r\n return { line: 0, column: 0 };\r\n }\r\n\r\n // TODO: Consider caching or optimizing this somehow\r\n let line: number = 1;\r\n let column: number = 1;\r\n\r\n let currentIndex: number = 0;\r\n\r\n while (currentIndex < index) {\r\n const current: string = this.buffer[currentIndex];\r\n ++currentIndex;\r\n\r\n if (current === '\\r') {\r\n // CR\r\n // Ignore '\\r' and assume it will always have an accompanying '\\n'\r\n continue;\r\n }\r\n\r\n if (current === '\\n') {\r\n // LF\r\n ++line;\r\n column = 1;\r\n } else {\r\n // NOTE: For consistency with the TypeScript compiler, a tab character is assumed\r\n // to advance by one column\r\n ++column;\r\n }\r\n }\r\n\r\n return { line, column };\r\n }\r\n\r\n private _validateBounds(): void {\r\n if (this.pos < 0) {\r\n throw new Error('TextRange.pos cannot be negative');\r\n }\r\n if (this.end < 0) {\r\n throw new Error('TextRange.end cannot be negative');\r\n }\r\n if (this.end < this.pos) {\r\n throw new Error('TextRange.end cannot be smaller than TextRange.pos');\r\n }\r\n if (this.pos > this.buffer.length) {\r\n throw new Error('TextRange.pos cannot exceed the associated text buffer length');\r\n }\r\n if (this.end > this.buffer.length) {\r\n throw new Error('TextRange.end cannot exceed the associated text buffer length');\r\n }\r\n }\r\n}\r\n"]}