You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.3 KiB
87 lines
2.3 KiB
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] |
|
} |
|
}; |
|
} |
|
};
|
|
|