| import { adoptBuffer } from './adopt-buffer.js'; |
| import { isBOM } from './char-code-definitions.js'; |
| |
| const N = 10; |
| const F = 12; |
| const R = 13; |
| |
| function computeLinesAndColumns(host) { |
| const source = host.source; |
| const sourceLength = source.length; |
| const startOffset = source.length > 0 ? isBOM(source.charCodeAt(0)) : 0; |
| const lines = adoptBuffer(host.lines, sourceLength); |
| const columns = adoptBuffer(host.columns, sourceLength); |
| let line = host.startLine; |
| let column = host.startColumn; |
| |
| for (let i = startOffset; i < sourceLength; i++) { |
| const code = source.charCodeAt(i); |
| |
| lines[i] = line; |
| columns[i] = column++; |
| |
| if (code === N || code === R || code === F) { |
| if (code === R && i + 1 < sourceLength && source.charCodeAt(i + 1) === N) { |
| i++; |
| lines[i] = line; |
| columns[i] = column; |
| } |
| |
| line++; |
| column = 1; |
| } |
| } |
| |
| lines[sourceLength] = line; |
| columns[sourceLength] = column; |
| |
| host.lines = lines; |
| host.columns = columns; |
| host.computed = true; |
| } |
| |
| export class OffsetToLocation { |
| constructor() { |
| this.lines = null; |
| this.columns = null; |
| this.computed = false; |
| } |
| setSource(source, startOffset = 0, startLine = 1, startColumn = 1) { |
| this.source = source; |
| this.startOffset = startOffset; |
| this.startLine = startLine; |
| this.startColumn = startColumn; |
| this.computed = false; |
| } |
| getLocation(offset, filename) { |
| if (!this.computed) { |
| computeLinesAndColumns(this); |
| } |
| |
| return { |
| source: filename, |
| offset: this.startOffset + offset, |
| line: this.lines[offset], |
| column: this.columns[offset] |
| }; |
| } |
| getLocationRange(start, end, filename) { |
| if (!this.computed) { |
| computeLinesAndColumns(this); |
| } |
| |
| return { |
| source: filename, |
| start: { |
| offset: this.startOffset + start, |
| line: this.lines[start], |
| column: this.columns[start] |
| }, |
| end: { |
| offset: this.startOffset + end, |
| line: this.lines[end], |
| column: this.columns[end] |
| } |
| }; |
| } |
| }; |