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.
91 lines
2.6 KiB
91 lines
2.6 KiB
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;
|
|
|