92 lines
2.6 KiB
JavaScript
92 lines
2.6 KiB
JavaScript
|
var adoptBuffer = require('./adopt-buffer');
|
||
|
var isBOM = require('../tokenizer').isBOM;
|
||
|
|
||
|
var N = 10;
|
||
|
var F = 12;
|
||
|
var R = 13;
|
||
|
|
||
|
function computeLinesAndColumns(host, source) {
|
||
|
var sourceLength = source.length;
|
||
|
var lines = adoptBuffer(host.lines, sourceLength); // +1
|
||
|
var line = host.startLine;
|
||
|
var columns = adoptBuffer(host.columns, sourceLength);
|
||
|
var column = host.startColumn;
|
||
|
var startOffset = source.length > 0 ? isBOM(source.charCodeAt(0)) : 0;
|
||
|
|
||
|
for (var i = startOffset; i < sourceLength; i++) { // -1
|
||
|
var 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[i] = line;
|
||
|
columns[i] = column;
|
||
|
|
||
|
host.lines = lines;
|
||
|
host.columns = columns;
|
||
|
}
|
||
|
|
||
|
var OffsetToLocation = function() {
|
||
|
this.lines = null;
|
||
|
this.columns = null;
|
||
|
this.linesAndColumnsComputed = false;
|
||
|
};
|
||
|
|
||
|
OffsetToLocation.prototype = {
|
||
|
setSource: function(source, startOffset, startLine, startColumn) {
|
||
|
this.source = source;
|
||
|
this.startOffset = typeof startOffset === 'undefined' ? 0 : startOffset;
|
||
|
this.startLine = typeof startLine === 'undefined' ? 1 : startLine;
|
||
|
this.startColumn = typeof startColumn === 'undefined' ? 1 : startColumn;
|
||
|
this.linesAndColumnsComputed = false;
|
||
|
},
|
||
|
|
||
|
ensureLinesAndColumnsComputed: function() {
|
||
|
if (!this.linesAndColumnsComputed) {
|
||
|
computeLinesAndColumns(this, this.source);
|
||
|
this.linesAndColumnsComputed = true;
|
||
|
}
|
||
|
},
|
||
|
getLocation: function(offset, filename) {
|
||
|
this.ensureLinesAndColumnsComputed();
|
||
|
|
||
|
return {
|
||
|
source: filename,
|
||
|
offset: this.startOffset + offset,
|
||
|
line: this.lines[offset],
|
||
|
column: this.columns[offset]
|
||
|
};
|
||
|
},
|
||
|
getLocationRange: function(start, end, filename) {
|
||
|
this.ensureLinesAndColumnsComputed();
|
||
|
|
||
|
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]
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
};
|
||
|
|
||
|
module.exports = OffsetToLocation;
|