'use strict'; const adoptBuffer = require('./adopt-buffer.cjs'); const charCodeDefinitions = require('./char-code-definitions.cjs'); 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 ? charCodeDefinitions.isBOM(source.charCodeAt(0)) : 0; const lines = adoptBuffer.adoptBuffer(host.lines, sourceLength); const columns = adoptBuffer.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; } 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] } }; } } exports.OffsetToLocation = OffsetToLocation;