@gdquest/gd-exercise
Version:
Core package that handles logic for the GDExercise project.
1,532 lines (1,529 loc) • 186 kB
JavaScript
import "./chunk-MJPHVYKR.mjs";
// ../codemirror-gdscript/dist/index.mjs
import {
foldNodeProp,
foldInside,
indentNodeProp,
LRLanguage,
LanguageSupport
} from "@codemirror/language";
// ../../node_modules/.pnpm/@lezer+common@1.0.3/node_modules/@lezer/common/dist/index.js
var DefaultBufferLength = 1024;
var nextPropID = 0;
var Range = class {
constructor(from, to) {
this.from = from;
this.to = to;
}
};
var NodeProp = class {
/// Create a new node prop type.
constructor(config = {}) {
this.id = nextPropID++;
this.perNode = !!config.perNode;
this.deserialize = config.deserialize || (() => {
throw new Error("This node type doesn't define a deserialize function");
});
}
/// This is meant to be used with
/// [`NodeSet.extend`](#common.NodeSet.extend) or
/// [`LRParser.configure`](#lr.ParserConfig.props) to compute
/// prop values for each node type in the set. Takes a [match
/// object](#common.NodeType^match) or function that returns undefined
/// if the node type doesn't get this prop, and the prop's value if
/// it does.
add(match) {
if (this.perNode)
throw new RangeError("Can't add per-node props to node types");
if (typeof match != "function")
match = NodeType.match(match);
return (type) => {
let result = match(type);
return result === void 0 ? null : [this, result];
};
}
};
NodeProp.closedBy = new NodeProp({ deserialize: (str) => str.split(" ") });
NodeProp.openedBy = new NodeProp({ deserialize: (str) => str.split(" ") });
NodeProp.group = new NodeProp({ deserialize: (str) => str.split(" ") });
NodeProp.contextHash = new NodeProp({ perNode: true });
NodeProp.lookAhead = new NodeProp({ perNode: true });
NodeProp.mounted = new NodeProp({ perNode: true });
var noProps = /* @__PURE__ */ Object.create(null);
var NodeType = class _NodeType2 {
/// @internal
constructor(name2, props, id2, flags = 0) {
this.name = name2;
this.props = props;
this.id = id2;
this.flags = flags;
}
/// Define a node type.
static define(spec) {
let props = spec.props && spec.props.length ? /* @__PURE__ */ Object.create(null) : noProps;
let flags = (spec.top ? 1 : 0) | (spec.skipped ? 2 : 0) | (spec.error ? 4 : 0) | (spec.name == null ? 8 : 0);
let type = new _NodeType2(spec.name || "", props, spec.id, flags);
if (spec.props)
for (let src of spec.props) {
if (!Array.isArray(src))
src = src(type);
if (src) {
if (src[0].perNode)
throw new RangeError("Can't store a per-node prop on a node type");
props[src[0].id] = src[1];
}
}
return type;
}
/// Retrieves a node prop for this type. Will return `undefined` if
/// the prop isn't present on this node.
prop(prop) {
return this.props[prop.id];
}
/// True when this is the top node of a grammar.
get isTop() {
return (this.flags & 1) > 0;
}
/// True when this node is produced by a skip rule.
get isSkipped() {
return (this.flags & 2) > 0;
}
/// Indicates whether this is an error node.
get isError() {
return (this.flags & 4) > 0;
}
/// When true, this node type doesn't correspond to a user-declared
/// named node, for example because it is used to cache repetition.
get isAnonymous() {
return (this.flags & 8) > 0;
}
/// Returns true when this node's name or one of its
/// [groups](#common.NodeProp^group) matches the given string.
is(name2) {
if (typeof name2 == "string") {
if (this.name == name2)
return true;
let group = this.prop(NodeProp.group);
return group ? group.indexOf(name2) > -1 : false;
}
return this.id == name2;
}
/// Create a function from node types to arbitrary values by
/// specifying an object whose property names are node or
/// [group](#common.NodeProp^group) names. Often useful with
/// [`NodeProp.add`](#common.NodeProp.add). You can put multiple
/// names, separated by spaces, in a single property name to map
/// multiple node names to a single value.
static match(map) {
let direct = /* @__PURE__ */ Object.create(null);
for (let prop in map)
for (let name2 of prop.split(" "))
direct[name2] = map[prop];
return (node) => {
for (let groups = node.prop(NodeProp.group), i = -1; i < (groups ? groups.length : 0); i++) {
let found = direct[i < 0 ? node.name : groups[i]];
if (found)
return found;
}
};
}
};
NodeType.none = new NodeType(
"",
/* @__PURE__ */ Object.create(null),
0,
8
/* NodeFlag.Anonymous */
);
var NodeSet = class _NodeSet {
/// Create a set with the given types. The `id` property of each
/// type should correspond to its position within the array.
constructor(types) {
this.types = types;
for (let i = 0; i < types.length; i++)
if (types[i].id != i)
throw new RangeError("Node type ids should correspond to array positions when creating a node set");
}
/// Create a copy of this set with some node properties added. The
/// arguments to this method can be created with
/// [`NodeProp.add`](#common.NodeProp.add).
extend(...props) {
let newTypes = [];
for (let type of this.types) {
let newProps = null;
for (let source of props) {
let add = source(type);
if (add) {
if (!newProps)
newProps = Object.assign({}, type.props);
newProps[add[0].id] = add[1];
}
}
newTypes.push(newProps ? new NodeType(type.name, newProps, type.id, type.flags) : type);
}
return new _NodeSet(newTypes);
}
};
var CachedNode = /* @__PURE__ */ new WeakMap();
var CachedInnerNode = /* @__PURE__ */ new WeakMap();
var IterMode;
(function(IterMode3) {
IterMode3[IterMode3["ExcludeBuffers"] = 1] = "ExcludeBuffers";
IterMode3[IterMode3["IncludeAnonymous"] = 2] = "IncludeAnonymous";
IterMode3[IterMode3["IgnoreMounts"] = 4] = "IgnoreMounts";
IterMode3[IterMode3["IgnoreOverlays"] = 8] = "IgnoreOverlays";
})(IterMode || (IterMode = {}));
var Tree = class _Tree2 {
/// Construct a new tree. See also [`Tree.build`](#common.Tree^build).
constructor(type, children, positions, length, props) {
this.type = type;
this.children = children;
this.positions = positions;
this.length = length;
this.props = null;
if (props && props.length) {
this.props = /* @__PURE__ */ Object.create(null);
for (let [prop, value] of props)
this.props[typeof prop == "number" ? prop : prop.id] = value;
}
}
/// @internal
toString() {
let mounted = this.prop(NodeProp.mounted);
if (mounted && !mounted.overlay)
return mounted.tree.toString();
let children = "";
for (let ch of this.children) {
let str = ch.toString();
if (str) {
if (children)
children += ",";
children += str;
}
}
return !this.type.name ? children : (/\W/.test(this.type.name) && !this.type.isError ? JSON.stringify(this.type.name) : this.type.name) + (children.length ? "(" + children + ")" : "");
}
/// Get a [tree cursor](#common.TreeCursor) positioned at the top of
/// the tree. Mode can be used to [control](#common.IterMode) which
/// nodes the cursor visits.
cursor(mode = 0) {
return new TreeCursor(this.topNode, mode);
}
/// Get a [tree cursor](#common.TreeCursor) pointing into this tree
/// at the given position and side (see
/// [`moveTo`](#common.TreeCursor.moveTo).
cursorAt(pos, side = 0, mode = 0) {
let scope = CachedNode.get(this) || this.topNode;
let cursor = new TreeCursor(scope);
cursor.moveTo(pos, side);
CachedNode.set(this, cursor._tree);
return cursor;
}
/// Get a [syntax node](#common.SyntaxNode) object for the top of the
/// tree.
get topNode() {
return new TreeNode(this, 0, 0, null);
}
/// Get the [syntax node](#common.SyntaxNode) at the given position.
/// If `side` is -1, this will move into nodes that end at the
/// position. If 1, it'll move into nodes that start at the
/// position. With 0, it'll only enter nodes that cover the position
/// from both sides.
///
/// Note that this will not enter
/// [overlays](#common.MountedTree.overlay), and you often want
/// [`resolveInner`](#common.Tree.resolveInner) instead.
resolve(pos, side = 0) {
let node = resolveNode(CachedNode.get(this) || this.topNode, pos, side, false);
CachedNode.set(this, node);
return node;
}
/// Like [`resolve`](#common.Tree.resolve), but will enter
/// [overlaid](#common.MountedTree.overlay) nodes, producing a syntax node
/// pointing into the innermost overlaid tree at the given position
/// (with parent links going through all parent structure, including
/// the host trees).
resolveInner(pos, side = 0) {
let node = resolveNode(CachedInnerNode.get(this) || this.topNode, pos, side, true);
CachedInnerNode.set(this, node);
return node;
}
/// Iterate over the tree and its children, calling `enter` for any
/// node that touches the `from`/`to` region (if given) before
/// running over such a node's children, and `leave` (if given) when
/// leaving the node. When `enter` returns `false`, that node will
/// not have its children iterated over (or `leave` called).
iterate(spec) {
let { enter, leave, from = 0, to = this.length } = spec;
let mode = spec.mode || 0, anon = (mode & IterMode.IncludeAnonymous) > 0;
for (let c = this.cursor(mode | IterMode.IncludeAnonymous); ; ) {
let entered = false;
if (c.from <= to && c.to >= from && (!anon && c.type.isAnonymous || enter(c) !== false)) {
if (c.firstChild())
continue;
entered = true;
}
for (; ; ) {
if (entered && leave && (anon || !c.type.isAnonymous))
leave(c);
if (c.nextSibling())
break;
if (!c.parent())
return;
entered = true;
}
}
}
/// Get the value of the given [node prop](#common.NodeProp) for this
/// node. Works with both per-node and per-type props.
prop(prop) {
return !prop.perNode ? this.type.prop(prop) : this.props ? this.props[prop.id] : void 0;
}
/// Returns the node's [per-node props](#common.NodeProp.perNode) in a
/// format that can be passed to the [`Tree`](#common.Tree)
/// constructor.
get propValues() {
let result = [];
if (this.props)
for (let id2 in this.props)
result.push([+id2, this.props[id2]]);
return result;
}
/// Balance the direct children of this tree, producing a copy of
/// which may have children grouped into subtrees with type
/// [`NodeType.none`](#common.NodeType^none).
balance(config = {}) {
return this.children.length <= 8 ? this : balanceRange(NodeType.none, this.children, this.positions, 0, this.children.length, 0, this.length, (children, positions, length) => new _Tree2(this.type, children, positions, length, this.propValues), config.makeTree || ((children, positions, length) => new _Tree2(NodeType.none, children, positions, length)));
}
/// Build a tree from a postfix-ordered buffer of node information,
/// or a cursor over such a buffer.
static build(data) {
return buildTree(data);
}
};
Tree.empty = new Tree(NodeType.none, [], [], 0);
var FlatBufferCursor = class _FlatBufferCursor2 {
constructor(buffer, index) {
this.buffer = buffer;
this.index = index;
}
get id() {
return this.buffer[this.index - 4];
}
get start() {
return this.buffer[this.index - 3];
}
get end() {
return this.buffer[this.index - 2];
}
get size() {
return this.buffer[this.index - 1];
}
get pos() {
return this.index;
}
next() {
this.index -= 4;
}
fork() {
return new _FlatBufferCursor2(this.buffer, this.index);
}
};
var TreeBuffer = class _TreeBuffer2 {
/// Create a tree buffer.
constructor(buffer, length, set) {
this.buffer = buffer;
this.length = length;
this.set = set;
}
/// @internal
get type() {
return NodeType.none;
}
/// @internal
toString() {
let result = [];
for (let index = 0; index < this.buffer.length; ) {
result.push(this.childString(index));
index = this.buffer[index + 3];
}
return result.join(",");
}
/// @internal
childString(index) {
let id2 = this.buffer[index], endIndex = this.buffer[index + 3];
let type = this.set.types[id2], result = type.name;
if (/\W/.test(result) && !type.isError)
result = JSON.stringify(result);
index += 4;
if (endIndex == index)
return result;
let children = [];
while (index < endIndex) {
children.push(this.childString(index));
index = this.buffer[index + 3];
}
return result + "(" + children.join(",") + ")";
}
/// @internal
findChild(startIndex, endIndex, dir, pos, side) {
let { buffer } = this, pick = -1;
for (let i = startIndex; i != endIndex; i = buffer[i + 3]) {
if (checkSide(side, pos, buffer[i + 1], buffer[i + 2])) {
pick = i;
if (dir > 0)
break;
}
}
return pick;
}
/// @internal
slice(startI, endI, from) {
let b = this.buffer;
let copy = new Uint16Array(endI - startI), len = 0;
for (let i = startI, j = 0; i < endI; ) {
copy[j++] = b[i++];
copy[j++] = b[i++] - from;
let to = copy[j++] = b[i++] - from;
copy[j++] = b[i++] - startI;
len = Math.max(len, to);
}
return new _TreeBuffer2(copy, len, this.set);
}
};
function checkSide(side, pos, from, to) {
switch (side) {
case -2:
return from < pos;
case -1:
return to >= pos && from < pos;
case 0:
return from < pos && to > pos;
case 1:
return from <= pos && to > pos;
case 2:
return to > pos;
case 4:
return true;
}
}
function enterUnfinishedNodesBefore(node, pos) {
let scan = node.childBefore(pos);
while (scan) {
let last = scan.lastChild;
if (!last || last.to != scan.to)
break;
if (last.type.isError && last.from == last.to) {
node = scan;
scan = last.prevSibling;
} else {
scan = last;
}
}
return node;
}
function resolveNode(node, pos, side, overlays) {
var _a;
while (node.from == node.to || (side < 1 ? node.from >= pos : node.from > pos) || (side > -1 ? node.to <= pos : node.to < pos)) {
let parent = !overlays && node instanceof TreeNode && node.index < 0 ? null : node.parent;
if (!parent)
return node;
node = parent;
}
let mode = overlays ? 0 : IterMode.IgnoreOverlays;
if (overlays)
for (let scan = node, parent = scan.parent; parent; scan = parent, parent = scan.parent) {
if (scan instanceof TreeNode && scan.index < 0 && ((_a = parent.enter(pos, side, mode)) === null || _a === void 0 ? void 0 : _a.from) != scan.from)
node = parent;
}
for (; ; ) {
let inner = node.enter(pos, side, mode);
if (!inner)
return node;
node = inner;
}
}
var TreeNode = class _TreeNode2 {
constructor(_tree, from, index, _parent) {
this._tree = _tree;
this.from = from;
this.index = index;
this._parent = _parent;
}
get type() {
return this._tree.type;
}
get name() {
return this._tree.type.name;
}
get to() {
return this.from + this._tree.length;
}
nextChild(i, dir, pos, side, mode = 0) {
for (let parent = this; ; ) {
for (let { children, positions } = parent._tree, e = dir > 0 ? children.length : -1; i != e; i += dir) {
let next = children[i], start = positions[i] + parent.from;
if (!checkSide(side, pos, start, start + next.length))
continue;
if (next instanceof TreeBuffer) {
if (mode & IterMode.ExcludeBuffers)
continue;
let index = next.findChild(0, next.buffer.length, dir, pos - start, side);
if (index > -1)
return new BufferNode(new BufferContext(parent, next, i, start), null, index);
} else if (mode & IterMode.IncludeAnonymous || (!next.type.isAnonymous || hasChild(next))) {
let mounted;
if (!(mode & IterMode.IgnoreMounts) && next.props && (mounted = next.prop(NodeProp.mounted)) && !mounted.overlay)
return new _TreeNode2(mounted.tree, start, i, parent);
let inner = new _TreeNode2(next, start, i, parent);
return mode & IterMode.IncludeAnonymous || !inner.type.isAnonymous ? inner : inner.nextChild(dir < 0 ? next.children.length - 1 : 0, dir, pos, side);
}
}
if (mode & IterMode.IncludeAnonymous || !parent.type.isAnonymous)
return null;
if (parent.index >= 0)
i = parent.index + dir;
else
i = dir < 0 ? -1 : parent._parent._tree.children.length;
parent = parent._parent;
if (!parent)
return null;
}
}
get firstChild() {
return this.nextChild(
0,
1,
0,
4
/* Side.DontCare */
);
}
get lastChild() {
return this.nextChild(
this._tree.children.length - 1,
-1,
0,
4
/* Side.DontCare */
);
}
childAfter(pos) {
return this.nextChild(
0,
1,
pos,
2
/* Side.After */
);
}
childBefore(pos) {
return this.nextChild(
this._tree.children.length - 1,
-1,
pos,
-2
/* Side.Before */
);
}
enter(pos, side, mode = 0) {
let mounted;
if (!(mode & IterMode.IgnoreOverlays) && (mounted = this._tree.prop(NodeProp.mounted)) && mounted.overlay) {
let rPos = pos - this.from;
for (let { from, to } of mounted.overlay) {
if ((side > 0 ? from <= rPos : from < rPos) && (side < 0 ? to >= rPos : to > rPos))
return new _TreeNode2(mounted.tree, mounted.overlay[0].from + this.from, -1, this);
}
}
return this.nextChild(0, 1, pos, side, mode);
}
nextSignificantParent() {
let val = this;
while (val.type.isAnonymous && val._parent)
val = val._parent;
return val;
}
get parent() {
return this._parent ? this._parent.nextSignificantParent() : null;
}
get nextSibling() {
return this._parent && this.index >= 0 ? this._parent.nextChild(
this.index + 1,
1,
0,
4
/* Side.DontCare */
) : null;
}
get prevSibling() {
return this._parent && this.index >= 0 ? this._parent.nextChild(
this.index - 1,
-1,
0,
4
/* Side.DontCare */
) : null;
}
cursor(mode = 0) {
return new TreeCursor(this, mode);
}
get tree() {
return this._tree;
}
toTree() {
return this._tree;
}
resolve(pos, side = 0) {
return resolveNode(this, pos, side, false);
}
resolveInner(pos, side = 0) {
return resolveNode(this, pos, side, true);
}
enterUnfinishedNodesBefore(pos) {
return enterUnfinishedNodesBefore(this, pos);
}
getChild(type, before = null, after = null) {
let r = getChildren(this, type, before, after);
return r.length ? r[0] : null;
}
getChildren(type, before = null, after = null) {
return getChildren(this, type, before, after);
}
/// @internal
toString() {
return this._tree.toString();
}
get node() {
return this;
}
matchContext(context) {
return matchNodeContext(this, context);
}
};
function getChildren(node, type, before, after) {
let cur = node.cursor(), result = [];
if (!cur.firstChild())
return result;
if (before != null) {
while (!cur.type.is(before))
if (!cur.nextSibling())
return result;
}
for (; ; ) {
if (after != null && cur.type.is(after))
return result;
if (cur.type.is(type))
result.push(cur.node);
if (!cur.nextSibling())
return after == null ? result : [];
}
}
function matchNodeContext(node, context, i = context.length - 1) {
for (let p = node.parent; i >= 0; p = p.parent) {
if (!p)
return false;
if (!p.type.isAnonymous) {
if (context[i] && context[i] != p.name)
return false;
i--;
}
}
return true;
}
var BufferContext = class {
constructor(parent, buffer, index, start) {
this.parent = parent;
this.buffer = buffer;
this.index = index;
this.start = start;
}
};
var BufferNode = class _BufferNode2 {
get name() {
return this.type.name;
}
get from() {
return this.context.start + this.context.buffer.buffer[this.index + 1];
}
get to() {
return this.context.start + this.context.buffer.buffer[this.index + 2];
}
constructor(context, _parent, index) {
this.context = context;
this._parent = _parent;
this.index = index;
this.type = context.buffer.set.types[context.buffer.buffer[index]];
}
child(dir, pos, side) {
let { buffer } = this.context;
let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], dir, pos - this.context.start, side);
return index < 0 ? null : new _BufferNode2(this.context, this, index);
}
get firstChild() {
return this.child(
1,
0,
4
/* Side.DontCare */
);
}
get lastChild() {
return this.child(
-1,
0,
4
/* Side.DontCare */
);
}
childAfter(pos) {
return this.child(
1,
pos,
2
/* Side.After */
);
}
childBefore(pos) {
return this.child(
-1,
pos,
-2
/* Side.Before */
);
}
enter(pos, side, mode = 0) {
if (mode & IterMode.ExcludeBuffers)
return null;
let { buffer } = this.context;
let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], side > 0 ? 1 : -1, pos - this.context.start, side);
return index < 0 ? null : new _BufferNode2(this.context, this, index);
}
get parent() {
return this._parent || this.context.parent.nextSignificantParent();
}
externalSibling(dir) {
return this._parent ? null : this.context.parent.nextChild(
this.context.index + dir,
dir,
0,
4
/* Side.DontCare */
);
}
get nextSibling() {
let { buffer } = this.context;
let after = buffer.buffer[this.index + 3];
if (after < (this._parent ? buffer.buffer[this._parent.index + 3] : buffer.buffer.length))
return new _BufferNode2(this.context, this._parent, after);
return this.externalSibling(1);
}
get prevSibling() {
let { buffer } = this.context;
let parentStart = this._parent ? this._parent.index + 4 : 0;
if (this.index == parentStart)
return this.externalSibling(-1);
return new _BufferNode2(this.context, this._parent, buffer.findChild(
parentStart,
this.index,
-1,
0,
4
/* Side.DontCare */
));
}
cursor(mode = 0) {
return new TreeCursor(this, mode);
}
get tree() {
return null;
}
toTree() {
let children = [], positions = [];
let { buffer } = this.context;
let startI = this.index + 4, endI = buffer.buffer[this.index + 3];
if (endI > startI) {
let from = buffer.buffer[this.index + 1];
children.push(buffer.slice(startI, endI, from));
positions.push(0);
}
return new Tree(this.type, children, positions, this.to - this.from);
}
resolve(pos, side = 0) {
return resolveNode(this, pos, side, false);
}
resolveInner(pos, side = 0) {
return resolveNode(this, pos, side, true);
}
enterUnfinishedNodesBefore(pos) {
return enterUnfinishedNodesBefore(this, pos);
}
/// @internal
toString() {
return this.context.buffer.childString(this.index);
}
getChild(type, before = null, after = null) {
let r = getChildren(this, type, before, after);
return r.length ? r[0] : null;
}
getChildren(type, before = null, after = null) {
return getChildren(this, type, before, after);
}
get node() {
return this;
}
matchContext(context) {
return matchNodeContext(this, context);
}
};
var TreeCursor = class {
/// Shorthand for `.type.name`.
get name() {
return this.type.name;
}
/// @internal
constructor(node, mode = 0) {
this.mode = mode;
this.buffer = null;
this.stack = [];
this.index = 0;
this.bufferNode = null;
if (node instanceof TreeNode) {
this.yieldNode(node);
} else {
this._tree = node.context.parent;
this.buffer = node.context;
for (let n = node._parent; n; n = n._parent)
this.stack.unshift(n.index);
this.bufferNode = node;
this.yieldBuf(node.index);
}
}
yieldNode(node) {
if (!node)
return false;
this._tree = node;
this.type = node.type;
this.from = node.from;
this.to = node.to;
return true;
}
yieldBuf(index, type) {
this.index = index;
let { start, buffer } = this.buffer;
this.type = type || buffer.set.types[buffer.buffer[index]];
this.from = start + buffer.buffer[index + 1];
this.to = start + buffer.buffer[index + 2];
return true;
}
yield(node) {
if (!node)
return false;
if (node instanceof TreeNode) {
this.buffer = null;
return this.yieldNode(node);
}
this.buffer = node.context;
return this.yieldBuf(node.index, node.type);
}
/// @internal
toString() {
return this.buffer ? this.buffer.buffer.childString(this.index) : this._tree.toString();
}
/// @internal
enterChild(dir, pos, side) {
if (!this.buffer)
return this.yield(this._tree.nextChild(dir < 0 ? this._tree._tree.children.length - 1 : 0, dir, pos, side, this.mode));
let { buffer } = this.buffer;
let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], dir, pos - this.buffer.start, side);
if (index < 0)
return false;
this.stack.push(this.index);
return this.yieldBuf(index);
}
/// Move the cursor to this node's first child. When this returns
/// false, the node has no child, and the cursor has not been moved.
firstChild() {
return this.enterChild(
1,
0,
4
/* Side.DontCare */
);
}
/// Move the cursor to this node's last child.
lastChild() {
return this.enterChild(
-1,
0,
4
/* Side.DontCare */
);
}
/// Move the cursor to the first child that ends after `pos`.
childAfter(pos) {
return this.enterChild(
1,
pos,
2
/* Side.After */
);
}
/// Move to the last child that starts before `pos`.
childBefore(pos) {
return this.enterChild(
-1,
pos,
-2
/* Side.Before */
);
}
/// Move the cursor to the child around `pos`. If side is -1 the
/// child may end at that position, when 1 it may start there. This
/// will also enter [overlaid](#common.MountedTree.overlay)
/// [mounted](#common.NodeProp^mounted) trees unless `overlays` is
/// set to false.
enter(pos, side, mode = this.mode) {
if (!this.buffer)
return this.yield(this._tree.enter(pos, side, mode));
return mode & IterMode.ExcludeBuffers ? false : this.enterChild(1, pos, side);
}
/// Move to the node's parent node, if this isn't the top node.
parent() {
if (!this.buffer)
return this.yieldNode(this.mode & IterMode.IncludeAnonymous ? this._tree._parent : this._tree.parent);
if (this.stack.length)
return this.yieldBuf(this.stack.pop());
let parent = this.mode & IterMode.IncludeAnonymous ? this.buffer.parent : this.buffer.parent.nextSignificantParent();
this.buffer = null;
return this.yieldNode(parent);
}
/// @internal
sibling(dir) {
if (!this.buffer)
return !this._tree._parent ? false : this.yield(this._tree.index < 0 ? null : this._tree._parent.nextChild(this._tree.index + dir, dir, 0, 4, this.mode));
let { buffer } = this.buffer, d = this.stack.length - 1;
if (dir < 0) {
let parentStart = d < 0 ? 0 : this.stack[d] + 4;
if (this.index != parentStart)
return this.yieldBuf(buffer.findChild(
parentStart,
this.index,
-1,
0,
4
/* Side.DontCare */
));
} else {
let after = buffer.buffer[this.index + 3];
if (after < (d < 0 ? buffer.buffer.length : buffer.buffer[this.stack[d] + 3]))
return this.yieldBuf(after);
}
return d < 0 ? this.yield(this.buffer.parent.nextChild(this.buffer.index + dir, dir, 0, 4, this.mode)) : false;
}
/// Move to this node's next sibling, if any.
nextSibling() {
return this.sibling(1);
}
/// Move to this node's previous sibling, if any.
prevSibling() {
return this.sibling(-1);
}
atLastNode(dir) {
let index, parent, { buffer } = this;
if (buffer) {
if (dir > 0) {
if (this.index < buffer.buffer.buffer.length)
return false;
} else {
for (let i = 0; i < this.index; i++)
if (buffer.buffer.buffer[i + 3] < this.index)
return false;
}
({ index, parent } = buffer);
} else {
({ index, _parent: parent } = this._tree);
}
for (; parent; { index, _parent: parent } = parent) {
if (index > -1)
for (let i = index + dir, e = dir < 0 ? -1 : parent._tree.children.length; i != e; i += dir) {
let child = parent._tree.children[i];
if (this.mode & IterMode.IncludeAnonymous || child instanceof TreeBuffer || !child.type.isAnonymous || hasChild(child))
return false;
}
}
return true;
}
move(dir, enter) {
if (enter && this.enterChild(
dir,
0,
4
/* Side.DontCare */
))
return true;
for (; ; ) {
if (this.sibling(dir))
return true;
if (this.atLastNode(dir) || !this.parent())
return false;
}
}
/// Move to the next node in a
/// [pre-order](https://en.wikipedia.org/wiki/Tree_traversal#Pre-order,_NLR)
/// traversal, going from a node to its first child or, if the
/// current node is empty or `enter` is false, its next sibling or
/// the next sibling of the first parent node that has one.
next(enter = true) {
return this.move(1, enter);
}
/// Move to the next node in a last-to-first pre-order traveral. A
/// node is followed by its last child or, if it has none, its
/// previous sibling or the previous sibling of the first parent
/// node that has one.
prev(enter = true) {
return this.move(-1, enter);
}
/// Move the cursor to the innermost node that covers `pos`. If
/// `side` is -1, it will enter nodes that end at `pos`. If it is 1,
/// it will enter nodes that start at `pos`.
moveTo(pos, side = 0) {
while (this.from == this.to || (side < 1 ? this.from >= pos : this.from > pos) || (side > -1 ? this.to <= pos : this.to < pos))
if (!this.parent())
break;
while (this.enterChild(1, pos, side)) {
}
return this;
}
/// Get a [syntax node](#common.SyntaxNode) at the cursor's current
/// position.
get node() {
if (!this.buffer)
return this._tree;
let cache2 = this.bufferNode, result = null, depth = 0;
if (cache2 && cache2.context == this.buffer) {
scan:
for (let index = this.index, d = this.stack.length; d >= 0; ) {
for (let c = cache2; c; c = c._parent)
if (c.index == index) {
if (index == this.index)
return c;
result = c;
depth = d + 1;
break scan;
}
index = this.stack[--d];
}
}
for (let i = depth; i < this.stack.length; i++)
result = new BufferNode(this.buffer, result, this.stack[i]);
return this.bufferNode = new BufferNode(this.buffer, result, this.index);
}
/// Get the [tree](#common.Tree) that represents the current node, if
/// any. Will return null when the node is in a [tree
/// buffer](#common.TreeBuffer).
get tree() {
return this.buffer ? null : this._tree._tree;
}
/// Iterate over the current node and all its descendants, calling
/// `enter` when entering a node and `leave`, if given, when leaving
/// one. When `enter` returns `false`, any children of that node are
/// skipped, and `leave` isn't called for it.
iterate(enter, leave) {
for (let depth = 0; ; ) {
let mustLeave = false;
if (this.type.isAnonymous || enter(this) !== false) {
if (this.firstChild()) {
depth++;
continue;
}
if (!this.type.isAnonymous)
mustLeave = true;
}
for (; ; ) {
if (mustLeave && leave)
leave(this);
mustLeave = this.type.isAnonymous;
if (this.nextSibling())
break;
if (!depth)
return;
this.parent();
depth--;
mustLeave = true;
}
}
}
/// Test whether the current node matches a given context—a sequence
/// of direct parent node names. Empty strings in the context array
/// are treated as wildcards.
matchContext(context) {
if (!this.buffer)
return matchNodeContext(this.node, context);
let { buffer } = this.buffer, { types } = buffer.set;
for (let i = context.length - 1, d = this.stack.length - 1; i >= 0; d--) {
if (d < 0)
return matchNodeContext(this.node, context, i);
let type = types[buffer.buffer[this.stack[d]]];
if (!type.isAnonymous) {
if (context[i] && context[i] != type.name)
return false;
i--;
}
}
return true;
}
};
function hasChild(tree) {
return tree.children.some((ch) => ch instanceof TreeBuffer || !ch.type.isAnonymous || hasChild(ch));
}
function buildTree(data) {
var _a;
let { buffer, nodeSet, maxBufferLength = DefaultBufferLength, reused = [], minRepeatType = nodeSet.types.length } = data;
let cursor = Array.isArray(buffer) ? new FlatBufferCursor(buffer, buffer.length) : buffer;
let types = nodeSet.types;
let contextHash = 0, lookAhead = 0;
function takeNode(parentStart, minPos, children2, positions2, inRepeat) {
let { id: id2, start, end, size } = cursor;
let lookAheadAtStart = lookAhead;
while (size < 0) {
cursor.next();
if (size == -1) {
let node2 = reused[id2];
children2.push(node2);
positions2.push(start - parentStart);
return;
} else if (size == -3) {
contextHash = id2;
return;
} else if (size == -4) {
lookAhead = id2;
return;
} else {
throw new RangeError(`Unrecognized record size: ${size}`);
}
}
let type = types[id2], node, buffer2;
let startPos = start - parentStart;
if (end - start <= maxBufferLength && (buffer2 = findBufferSize(cursor.pos - minPos, inRepeat))) {
let data2 = new Uint16Array(buffer2.size - buffer2.skip);
let endPos = cursor.pos - buffer2.size, index = data2.length;
while (cursor.pos > endPos)
index = copyToBuffer(buffer2.start, data2, index);
node = new TreeBuffer(data2, end - buffer2.start, nodeSet);
startPos = buffer2.start - parentStart;
} else {
let endPos = cursor.pos - size;
cursor.next();
let localChildren = [], localPositions = [];
let localInRepeat = id2 >= minRepeatType ? id2 : -1;
let lastGroup = 0, lastEnd = end;
while (cursor.pos > endPos) {
if (localInRepeat >= 0 && cursor.id == localInRepeat && cursor.size >= 0) {
if (cursor.end <= lastEnd - maxBufferLength) {
makeRepeatLeaf(localChildren, localPositions, start, lastGroup, cursor.end, lastEnd, localInRepeat, lookAheadAtStart);
lastGroup = localChildren.length;
lastEnd = cursor.end;
}
cursor.next();
} else {
takeNode(start, endPos, localChildren, localPositions, localInRepeat);
}
}
if (localInRepeat >= 0 && lastGroup > 0 && lastGroup < localChildren.length)
makeRepeatLeaf(localChildren, localPositions, start, lastGroup, start, lastEnd, localInRepeat, lookAheadAtStart);
localChildren.reverse();
localPositions.reverse();
if (localInRepeat > -1 && lastGroup > 0) {
let make = makeBalanced(type);
node = balanceRange(type, localChildren, localPositions, 0, localChildren.length, 0, end - start, make, make);
} else {
node = makeTree(type, localChildren, localPositions, end - start, lookAheadAtStart - end);
}
}
children2.push(node);
positions2.push(startPos);
}
function makeBalanced(type) {
return (children2, positions2, length2) => {
let lookAhead2 = 0, lastI = children2.length - 1, last, lookAheadProp;
if (lastI >= 0 && (last = children2[lastI]) instanceof Tree) {
if (!lastI && last.type == type && last.length == length2)
return last;
if (lookAheadProp = last.prop(NodeProp.lookAhead))
lookAhead2 = positions2[lastI] + last.length + lookAheadProp;
}
return makeTree(type, children2, positions2, length2, lookAhead2);
};
}
function makeRepeatLeaf(children2, positions2, base, i, from, to, type, lookAhead2) {
let localChildren = [], localPositions = [];
while (children2.length > i) {
localChildren.push(children2.pop());
localPositions.push(positions2.pop() + base - from);
}
children2.push(makeTree(nodeSet.types[type], localChildren, localPositions, to - from, lookAhead2 - to));
positions2.push(from - base);
}
function makeTree(type, children2, positions2, length2, lookAhead2 = 0, props) {
if (contextHash) {
let pair2 = [NodeProp.contextHash, contextHash];
props = props ? [pair2].concat(props) : [pair2];
}
if (lookAhead2 > 25) {
let pair2 = [NodeProp.lookAhead, lookAhead2];
props = props ? [pair2].concat(props) : [pair2];
}
return new Tree(type, children2, positions2, length2, props);
}
function findBufferSize(maxSize, inRepeat) {
let fork = cursor.fork();
let size = 0, start = 0, skip = 0, minStart = fork.end - maxBufferLength;
let result = { size: 0, start: 0, skip: 0 };
scan:
for (let minPos = fork.pos - maxSize; fork.pos > minPos; ) {
let nodeSize3 = fork.size;
if (fork.id == inRepeat && nodeSize3 >= 0) {
result.size = size;
result.start = start;
result.skip = skip;
skip += 4;
size += 4;
fork.next();
continue;
}
let startPos = fork.pos - nodeSize3;
if (nodeSize3 < 0 || startPos < minPos || fork.start < minStart)
break;
let localSkipped = fork.id >= minRepeatType ? 4 : 0;
let nodeStart = fork.start;
fork.next();
while (fork.pos > startPos) {
if (fork.size < 0) {
if (fork.size == -3)
localSkipped += 4;
else
break scan;
} else if (fork.id >= minRepeatType) {
localSkipped += 4;
}
fork.next();
}
start = nodeStart;
size += nodeSize3;
skip += localSkipped;
}
if (inRepeat < 0 || size == maxSize) {
result.size = size;
result.start = start;
result.skip = skip;
}
return result.size > 4 ? result : void 0;
}
function copyToBuffer(bufferStart, buffer2, index) {
let { id: id2, start, end, size } = cursor;
cursor.next();
if (size >= 0 && id2 < minRepeatType) {
let startIndex = index;
if (size > 4) {
let endPos = cursor.pos - (size - 4);
while (cursor.pos > endPos)
index = copyToBuffer(bufferStart, buffer2, index);
}
buffer2[--index] = startIndex;
buffer2[--index] = end - bufferStart;
buffer2[--index] = start - bufferStart;
buffer2[--index] = id2;
} else if (size == -3) {
contextHash = id2;
} else if (size == -4) {
lookAhead = id2;
}
return index;
}
let children = [], positions = [];
while (cursor.pos > 0)
takeNode(data.start || 0, data.bufferStart || 0, children, positions, -1);
let length = (_a = data.length) !== null && _a !== void 0 ? _a : children.length ? positions[0] + children[0].length : 0;
return new Tree(types[data.topID], children.reverse(), positions.reverse(), length);
}
var nodeSizeCache = /* @__PURE__ */ new WeakMap();
function nodeSize(balanceType, node) {
if (!balanceType.isAnonymous || node instanceof TreeBuffer || node.type != balanceType)
return 1;
let size = nodeSizeCache.get(node);
if (size == null) {
size = 1;
for (let child of node.children) {
if (child.type != balanceType || !(child instanceof Tree)) {
size = 1;
break;
}
size += nodeSize(balanceType, child);
}
nodeSizeCache.set(node, size);
}
return size;
}
function balanceRange(balanceType, children, positions, from, to, start, length, mkTop, mkTree) {
let total = 0;
for (let i = from; i < to; i++)
total += nodeSize(balanceType, children[i]);
let maxChild = Math.ceil(
total * 1.5 / 8
/* Balance.BranchFactor */
);
let localChildren = [], localPositions = [];
function divide(children2, positions2, from2, to2, offset) {
for (let i = from2; i < to2; ) {
let groupFrom = i, groupStart = positions2[i], groupSize = nodeSize(balanceType, children2[i]);
i++;
for (; i < to2; i++) {
let nextSize = nodeSize(balanceType, children2[i]);
if (groupSize + nextSize >= maxChild)
break;
groupSize += nextSize;
}
if (i == groupFrom + 1) {
if (groupSize > maxChild) {
let only = children2[groupFrom];
divide(only.children, only.positions, 0, only.children.length, positions2[groupFrom] + offset);
continue;
}
localChildren.push(children2[groupFrom]);
} else {
let length2 = positions2[i - 1] + children2[i - 1].length - groupStart;
localChildren.push(balanceRange(balanceType, children2, positions2, groupFrom, i, groupStart, length2, null, mkTree));
}
localPositions.push(groupStart + offset - start);
}
}
divide(children, positions, from, to, 0);
return (mkTop || mkTree)(localChildren, localPositions, length);
}
var Parser = class {
/// Start a parse, returning a [partial parse](#common.PartialParse)
/// object. [`fragments`](#common.TreeFragment) can be passed in to
/// make the parse incremental.
///
/// By default, the entire input is parsed. You can pass `ranges`,
/// which should be a sorted array of non-empty, non-overlapping
/// ranges, to parse only those ranges. The tree returned in that
/// case will start at `ranges[0].from`.
startParse(input, fragments, ranges) {
if (typeof input == "string")
input = new StringInput(input);
ranges = !ranges ? [new Range(0, input.length)] : ranges.length ? ranges.map((r) => new Range(r.from, r.to)) : [new Range(0, 0)];
return this.createParse(input, fragments || [], ranges);
}
/// Run a full parse, returning the resulting tree.
parse(input, fragments, ranges) {
let parse = this.startParse(input, fragments, ranges);
for (; ; ) {
let done = parse.advance();
if (done)
return done;
}
}
};
var StringInput = class {
constructor(string2) {
this.string = string2;
}
get length() {
return this.string.length;
}
chunk(from) {
return this.string.slice(from);
}
get lineChunks() {
return false;
}
read(from, to) {
return this.string.slice(from, to);
}
};
var stoppedInner = new NodeProp({ perNode: true });
// ../../node_modules/.pnpm/@lezer+lr@1.3.9/node_modules/@lezer/lr/dist/index.js
var Stack = class _Stack {
/// @internal
constructor(p, stack, state, reducePos, pos, score, buffer, bufferBase, curContext, lookAhead = 0, parent) {
this.p = p;
this.stack = stack;
this.state = state;
this.reducePos = reducePos;
this.pos = pos;
this.score = score;
this.buffer = buffer;
this.bufferBase = bufferBase;
this.curContext = curContext;
this.lookAhead = lookAhead;
this.parent = parent;
}
/// @internal
toString() {
return `[${this.stack.filter((_, i) => i % 3 == 0).concat(this.state)}]@${this.pos}${this.score ? "!" + this.score : ""}`;
}
// Start an empty stack
/// @internal
static start(p, state, pos = 0) {
let cx = p.parser.context;
return new _Stack(p, [], state, pos, pos, 0, [], 0, cx ? new StackContext(cx, cx.start) : null, 0, null);
}
/// The stack's current [context](#lr.ContextTracker) value, if
/// any. Its type will depend on the context tracker's type
/// parameter, or it will be `null` if there is no context
/// tracker.
get context() {
return this.curContext ? this.curContext.context : null;
}
// Push a state onto the stack, tracking its start position as well
// as the buffer base at that point.
/// @internal
pushState(state, start) {
this.stack.push(this.state, start, this.bufferBase + this.buffer.length);
this.state = state;
}
// Apply a reduce action
/// @internal
reduce(action) {
var _a;
let depth = action >> 19, type = action & 65535;
let { parser: parser2 } = this.p;
let dPrec = parser2.dynamicPrecedence(type);
if (dPrec)
this.score += dPrec;
if (depth == 0) {
this.pushState(parser2.getGoto(this.state, type, true), this.reducePos);
if (type < parser2.minRepeatTerm)
this.storeNode(type, this.reducePos, this.reducePos, 4, true);
this.reduceContext(type, this.reducePos);
return;
}
let base = this.stack.length - (depth - 1) * 3 - (action & 262144 ? 6 : 0);
let start = base ? this.stack[base - 2] : this.p.ranges[0].from, size = this.reducePos - start;
if (size >= 2e3 && !((_a = this.p.parser.nodeSet.types[type]) === null || _a === void 0 ? void 0 : _a.isAnonymous)) {
if (start == this.p.lastBigReductionStart) {
this.p.bigReductionCount++;
this.p.lastBigReductionSize = size;
} else if (this.p.lastBigReductionSize < size) {
this.p.bigReductionCount = 1;
this.p.lastBigReductionStart = start;
this.p.lastBigReductionSize = size;
}
}
let bufferBase = base ? this.stack[base - 1] : 0, count = this.bufferBase + this.buffer.length - bufferBase;
if (type < parser2.minRepeatTerm || action & 131072) {
let pos = parser2.stateFlag(
this.state,
1
/* StateFlag.Skipped */
) ? this.pos : this.reducePos;
this.storeNode(type, start, pos, count + 4, true);
}
if (action & 262144) {
this.state = this.stack[base];
} else {
let baseStateID = this.stack[base - 3];
this.state = parser2.getGoto(baseStateID, type, true);
}
while (this.stack.length > base)
this.stack.pop();
this.reduceContext(type, start);
}
// Shift a value into the buffer
/// @internal
storeNode(term, start, end, size = 4, isReduce = false) {
if (term == 0 && (!this.stack.length || this.stack[this.stack.length - 1] < this.buffer.length + this.bufferBase)) {
let cur = this, top = this.buffer.length;
if (top == 0 && cur.parent) {
top = cur.bufferBase - cur.parent.bufferBase;
cur = cur.parent;
}
if (top > 0 && cur.buffer[top - 4] == 0 && cur.buffer[top - 1] > -1) {
if (start == end)
return;
if (cur.buffer[top - 2] >= start) {
cur.buffer[top - 2] = end;
return;
}
}
}
if (!isReduce || this.pos == end) {
this.buffer.push(term, start, end, size);
} else {
let index = this.buffer.length;
if (index > 0 && this.buffer[index - 4] != 0)
while (index > 0 && this.buffer[index - 2] > end) {
this.buffer[index] = this.buffer[index - 4];
this.buffer[index + 1] = this.buffer[index - 3];
this.buffer[index + 2] = this.buffer[index - 2];
this.buffer[index + 3] = this.buffer[index - 1];
index -= 4;
if (size > 4)
size -= 4;
}
this.buffer[index] = term;
this.buffer[index + 1] = start;
this.buffer[index + 2] = end;
this.buffer[index + 3] = size;
}
}
// Apply a shift action
/// @internal
shift(action, next, nextEnd) {
let start = this.pos;
if (action & 131072) {
this.pushState(action & 65535, this.pos);
} else if ((action & 262144) == 0) {
let nextState = action, { parser: parser2 } = this.p;
if (nextEnd > this.pos || next <= parser2.maxNode) {
this.pos = nextEnd;
if (!parser2.stateFlag(
nextState,
1
/* StateFlag.Skipped */
))
this.reducePos = nextEnd;
}
this.pushState(nextState, start);
this.shiftContext(next, start);
if (next <= parser2.maxNode)
this.buffer.push(next, start, nextEnd, 4);
} else {
this.pos = nextEnd;
this.shiftContext(next, start);
if (next <= this.p.parser.maxNode)
this.buffer.push(next, start, nextEnd, 4);
}
}
// Apply an action
/// @internal
apply(action, next, nextEnd) {
if (action & 65536)
this.reduce(action);
else
this.shift(action, next, nextEnd);
}
// Add a prebuilt (reused) node into the buffer.
/// @internal
useNode(value, next) {
let index = this.p.reused.length - 1;
if (index < 0 || this.p.reused[index] != value) {
this.p.reused.push(value);
index++;
}
let start = this.pos;
this.reducePos = this.pos = start + value.length;
this.pushState(next, start);
this.buffer.push(
index,
start,
this.reducePos,
-1
/* size == -1 means this is a reused value */
);
if (this.curContext)
this.updateContext(this.curContext.tracker.reuse(this.curContext.context, value, this, this.p.stream.reset(this.pos - value.length)));
}
// Split the stack. Due to the buffer sharing and the fact
// that `this.stack`