| 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; |