Swap-Aggregator-Subgraph/node_modules/yaml/dist/cst/ParseContext.js
2022-07-03 07:27:35 +05:30

253 lines
7.9 KiB
JavaScript

"use strict";
exports.ParseContext = void 0;
var _constants = require("../constants");
var _errors = require("../errors");
var _Alias = require("./Alias");
var _BlockValue = require("./BlockValue");
var _Collection = require("./Collection");
var _CollectionItem = require("./CollectionItem");
var _FlowCollection = require("./FlowCollection");
var _Node = require("./Node");
var _PlainValue = require("./PlainValue");
var _QuoteDouble = require("./QuoteDouble");
var _QuoteSingle = require("./QuoteSingle");
var _Range = require("./Range");
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function createNewNode(type, props) {
switch (type) {
case _constants.Type.ALIAS:
return new _Alias.Alias(type, props);
case _constants.Type.BLOCK_FOLDED:
case _constants.Type.BLOCK_LITERAL:
return new _BlockValue.BlockValue(type, props);
case _constants.Type.FLOW_MAP:
case _constants.Type.FLOW_SEQ:
return new _FlowCollection.FlowCollection(type, props);
case _constants.Type.MAP_KEY:
case _constants.Type.MAP_VALUE:
case _constants.Type.SEQ_ITEM:
return new _CollectionItem.CollectionItem(type, props);
case _constants.Type.COMMENT:
case _constants.Type.PLAIN:
return new _PlainValue.PlainValue(type, props);
case _constants.Type.QUOTE_DOUBLE:
return new _QuoteDouble.QuoteDouble(type, props);
case _constants.Type.QUOTE_SINGLE:
return new _QuoteSingle.QuoteSingle(type, props);
/* istanbul ignore next */
default:
return null;
// should never happen
}
}
/**
* @param {boolean} atLineStart - Node starts at beginning of line
* @param {boolean} inFlow - true if currently in a flow context
* @param {boolean} inCollection - true if currently in a collection context
* @param {number} indent - Current level of indentation
* @param {number} lineStart - Start of the current line
* @param {Node} parent - The parent of the node
* @param {string} src - Source of the YAML document
*/
class ParseContext {
static parseType(src, offset, inFlow) {
switch (src[offset]) {
case '*':
return _constants.Type.ALIAS;
case '>':
return _constants.Type.BLOCK_FOLDED;
case '|':
return _constants.Type.BLOCK_LITERAL;
case '{':
return _constants.Type.FLOW_MAP;
case '[':
return _constants.Type.FLOW_SEQ;
case '?':
return !inFlow && _Node.Node.atBlank(src, offset + 1, true) ? _constants.Type.MAP_KEY : _constants.Type.PLAIN;
case ':':
return !inFlow && _Node.Node.atBlank(src, offset + 1, true) ? _constants.Type.MAP_VALUE : _constants.Type.PLAIN;
case '-':
return !inFlow && _Node.Node.atBlank(src, offset + 1, true) ? _constants.Type.SEQ_ITEM : _constants.Type.PLAIN;
case '"':
return _constants.Type.QUOTE_DOUBLE;
case "'":
return _constants.Type.QUOTE_SINGLE;
default:
return _constants.Type.PLAIN;
}
}
constructor(orig = {}, {
atLineStart,
inCollection,
inFlow,
indent,
lineStart,
parent
} = {}) {
_defineProperty(this, "parseNode", (overlay, start) => {
if (_Node.Node.atDocumentBoundary(this.src, start)) return null;
const context = new ParseContext(this, overlay);
const {
props,
type,
valueStart
} = context.parseProps(start);
const node = createNewNode(type, props);
let offset = node.parse(context, valueStart);
node.range = new _Range.Range(start, offset);
/* istanbul ignore if */
if (offset <= start) {
// This should never happen, but if it does, let's make sure to at least
// step one character forward to avoid a busy loop.
node.error = new Error(`Node#parse consumed no characters`);
node.error.parseEnd = offset;
node.error.source = node;
node.range.end = start + 1;
}
if (context.nodeStartsCollection(node)) {
if (!node.error && !context.atLineStart && context.parent.type === _constants.Type.DOCUMENT) {
node.error = new _errors.YAMLSyntaxError(node, 'Block collection must not have preceding content here (e.g. directives-end indicator)');
}
const collection = new _Collection.Collection(node);
offset = collection.parse(new ParseContext(context), offset);
collection.range = new _Range.Range(start, offset);
return collection;
}
return node;
});
this.atLineStart = atLineStart != null ? atLineStart : orig.atLineStart || false;
this.inCollection = inCollection != null ? inCollection : orig.inCollection || false;
this.inFlow = inFlow != null ? inFlow : orig.inFlow || false;
this.indent = indent != null ? indent : orig.indent;
this.lineStart = lineStart != null ? lineStart : orig.lineStart;
this.parent = parent != null ? parent : orig.parent || {};
this.root = orig.root;
this.src = orig.src;
}
nodeStartsCollection(node) {
const {
inCollection,
inFlow,
src
} = this;
if (inCollection || inFlow) return false;
if (node instanceof _CollectionItem.CollectionItem) return true; // check for implicit key
let offset = node.range.end;
if (src[offset] === '\n' || src[offset - 1] === '\n') return false;
offset = _Node.Node.endOfWhiteSpace(src, offset);
return src[offset] === ':';
} // Anchor and tag are before type, which determines the node implementation
// class; hence this intermediate step.
parseProps(offset) {
const {
inFlow,
parent,
src
} = this;
const props = [];
let lineHasProps = false;
offset = _Node.Node.endOfWhiteSpace(src, offset);
let ch = src[offset];
while (ch === _constants.Char.ANCHOR || ch === _constants.Char.COMMENT || ch === _constants.Char.TAG || ch === '\n') {
if (ch === '\n') {
const lineStart = offset + 1;
const inEnd = _Node.Node.endOfIndent(src, lineStart);
const indentDiff = inEnd - (lineStart + this.indent);
const noIndicatorAsIndent = parent.type === _constants.Type.SEQ_ITEM && parent.context.atLineStart;
if (!_Node.Node.nextNodeIsIndented(src[inEnd], indentDiff, !noIndicatorAsIndent)) break;
this.atLineStart = true;
this.lineStart = lineStart;
lineHasProps = false;
offset = inEnd;
} else if (ch === _constants.Char.COMMENT) {
const end = _Node.Node.endOfLine(src, offset + 1);
props.push(new _Range.Range(offset, end));
offset = end;
} else {
let end = _Node.Node.endOfIdentifier(src, offset + 1);
if (ch === _constants.Char.TAG && src[end] === ',' && /^[a-zA-Z0-9-]+\.[a-zA-Z0-9-]+,\d\d\d\d(-\d\d){0,2}\/\S/.test(src.slice(offset + 1, end + 13))) {
// Let's presume we're dealing with a YAML 1.0 domain tag here, rather
// than an empty but 'foo.bar' private-tagged node in a flow collection
// followed without whitespace by a plain string starting with a year
// or date divided by something.
end = _Node.Node.endOfIdentifier(src, end + 5);
}
props.push(new _Range.Range(offset, end));
lineHasProps = true;
offset = _Node.Node.endOfWhiteSpace(src, end);
}
ch = src[offset];
} // '- &a : b' has an anchor on an empty node
if (lineHasProps && ch === ':' && _Node.Node.atBlank(src, offset + 1, true)) offset -= 1;
const type = ParseContext.parseType(src, offset, inFlow);
return {
props,
type,
valueStart: offset
};
}
/**
* Parses a node from the source
* @param {ParseContext} overlay
* @param {number} start - Index of first non-whitespace character for the node
* @returns {?Node} - null if at a document boundary
*/
}
exports.ParseContext = ParseContext;