2025-09-05 14:59:21 +08:00

105 lines
3.1 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Context = void 0;
const _1 = require(".");
const options_1 = require("./options");
const utils_1 = require("./utils");
class Context {
constructor(origCode, parserOptions) {
this.tokens = [];
this.comments = [];
this.locsMap = new Map();
this.options = (0, options_1.parserOptionsToYAMLOption)(parserOptions);
const len = origCode.length;
const lineStartIndices = [0];
for (let index = 0; index < len;) {
const c = origCode[index++];
if (c === "\r") {
const next = origCode[index];
if (next === "\n") {
index++;
}
lineStartIndices.push(index);
}
else if (c === "\n") {
lineStartIndices.push(index);
}
}
this.code = origCode;
this.locs = new LinesAndColumns(lineStartIndices);
}
getLocFromIndex(index) {
let loc = this.locsMap.get(index);
if (!loc) {
loc = this.locs.getLocFromIndex(index);
this.locsMap.set(index, loc);
}
return {
line: loc.line,
column: loc.column,
};
}
/**
* Get the location information of the given range.
*/
getConvertLocation(start, end) {
return {
range: [start, end],
loc: {
start: this.getLocFromIndex(start),
end: this.getLocFromIndex(end),
},
};
}
addComment(comment) {
this.comments.push(comment);
}
/**
* Add token to tokens
*/
addToken(type, range) {
const token = Object.assign({ type, value: this.code.slice(...range) }, this.getConvertLocation(...range));
this.tokens.push(token);
return token;
}
/* istanbul ignore next */
throwUnexpectedTokenError(cst) {
const token = "source" in cst ? `'${cst.source}'` : cst.type;
throw this.throwError(`Unexpected token: ${token}`, cst);
}
throwError(message, cst) {
const offset = typeof cst === "number"
? cst
: "offset" in cst
? cst.offset
: cst.range[0];
const loc = this.getLocFromIndex(offset);
throw new _1.ParseError(message, offset, loc.line, loc.column);
}
/**
* Gets the last index with whitespace skipped.
*/
lastSkipSpaces(startIndex, endIndex) {
const str = this.code;
for (let index = endIndex - 1; index >= startIndex; index--) {
if (str[index].trim()) {
return index + 1;
}
}
return startIndex;
}
}
exports.Context = Context;
class LinesAndColumns {
constructor(lineStartIndices) {
this.lineStartIndices = lineStartIndices;
}
getLocFromIndex(index) {
const lineNumber = (0, utils_1.sortedLastIndex)(this.lineStartIndices, index);
return {
line: lineNumber,
column: index - this.lineStartIndices[lineNumber - 1],
};
}
}