webpack
Version:
Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.
65 lines (60 loc) • 1.69 kB
JavaScript
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Alexander Akait @alexander-akait
*/
"use strict";
class LocConverter {
/**
* Creates an instance of LocConverter.
* @param {string} input input
*/
constructor(input) {
/** @type {string} */
this._input = input;
/** @type {number} */
this.line = 1;
/** @type {number} */
this.column = 0;
/** @type {number} */
this.pos = 0;
}
/**
* Returns location converter.
* @param {number} pos position
* @returns {LocConverter} location converter
*/
get(pos) {
if (this.pos !== pos) {
if (this.pos < pos) {
// Advance: delta-bounded scan of [this.pos, pos), allocation-free
// (unbounded index scans go quadratic on newline-free input).
const input = this._input;
let last = -1;
for (let j = this.pos; j < pos; j++) {
if (input.charCodeAt(j) === 10) {
this.line++;
last = j;
}
}
this.column =
last === -1 ? this.column + (pos - this.pos) : pos - last - 1;
} else {
// Retreat: count newlines crossed in (pos, this.pos), i.e.
// exclude the newline at `this.pos` itself. By convention a
// `\n` is the last column of its line, so when `this.pos`
// sits on one we're already on the line containing it; only
// newlines strictly **before** `this.pos` and at-or-after
// `pos` represent crossed line boundaries.
let i = this._input.lastIndexOf("\n", this.pos - 1);
while (i >= pos) {
this.line--;
i = i > 0 ? this._input.lastIndexOf("\n", i - 1) : -1;
}
this.column = i === -1 ? pos : pos - i - 1;
}
this.pos = pos;
}
return this;
}
}
module.exports = LocConverter;