UNPKG

antlr-ng

Version:

Next generation ANTLR Tool

107 lines (106 loc) 3.2 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); class RewriteRuleElementStream { static { __name(this, "RewriteRuleElementStream"); } /** * Cursor 0..n-1. If singleElement!=null, cursor is 0 until you next(), which bumps it to 1 meaning no more * elements. */ cursor = 0; /** The list of tokens or subtrees we are tracking */ elements; /** * Once a node / subtree has been used in a stream, it must be dup'd from then on. Streams are reset after * subrules so that the streams can be reused in future subrules. So, reset must set a dirty bit. If dirty, * then next() always returns a dup. * * I wanted to use "naughty bit" here, but couldn't think of a way to use "naughty". */ dirty = false; /** * The element or stream description; usually has name of the token or rule reference that this list tracks. Can * include rule name too, but the exception would track that info. */ elementDescription; constructor(elementDescription, elements) { this.elementDescription = elementDescription; this.elements = elements ?? []; } /** * Reset the condition of this stream so that it appears we have not consumed any of its elements. Elements * themselves are untouched. Once we reset the stream, any future use will need duplicates. Set the dirty bit. */ reset() { this.cursor = 0; this.dirty = true; } add(el) { if (el) { this.elements.push(el); } } /** * Return the next element in the stream. If out of elements, throw an exception unless size() == 1. If size is 1, * then return elements[0]. * * @returns a duplicate node/subtree if stream is out of elements and size == 1. If we've already used the element, * dup (dirty bit set). */ nextTree() { const n = this.size(); if (this.dirty || this.cursor >= n && n === 1) { const el = this.getNext(); return this.dup(el); } return this.getNext(); } hasNext() { return this.cursor < this.elements.length; } size() { return this.elements.length; } getDescription() { return this.elementDescription; } /** * Does the work of getting the next element, making sure that it's a tree node or subtree. Throws an exception * if the stream is empty or we're out of elements and size > 1. * * @returns the next element in the stream. */ getNext() { const n = this.size(); if (n === 0) { throw new Error(this.elementDescription); } if (this.cursor >= n) { if (n === 1) { return this.toTree(this.elements[0]); } throw new Error(this.elementDescription); } if (n === 1) { this.cursor++; return this.toTree(this.elements[0]); } const o = this.toTree(this.elements[this.cursor]); this.cursor++; return o; } /** * Ensures stream emits trees. Tokens must be converted to AST nodes. AST nodes can be passed through unmolested. * * @param el The element to convert. * * @returns the element unaltered. */ toTree(el) { return el; } } export { RewriteRuleElementStream };