`third_party/node/node_modules` is generated by `./mach vendor node`. Differential Revision: https://phabricator.services.mozilla.com/D320322
65 lines
1.6 KiB
JavaScript
65 lines
1.6 KiB
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;
|