add hw2
This commit is contained in:
243
node_modules/langium/lib/parser/cst-node-builder.js
generated
vendored
Normal file
243
node_modules/langium/lib/parser/cst-node-builder.js
generated
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
/******************************************************************************
|
||||
* Copyright 2021 TypeFox GmbH
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License, which is available in the project root.
|
||||
******************************************************************************/
|
||||
import { Position } from 'vscode-languageserver-types';
|
||||
import { tokenToRange } from '../utils/cst-utils.js';
|
||||
export class CstNodeBuilder {
|
||||
constructor() {
|
||||
this.nodeStack = [];
|
||||
}
|
||||
get current() {
|
||||
var _a;
|
||||
return (_a = this.nodeStack[this.nodeStack.length - 1]) !== null && _a !== void 0 ? _a : this.rootNode;
|
||||
}
|
||||
buildRootNode(input) {
|
||||
this.rootNode = new RootCstNodeImpl(input);
|
||||
this.rootNode.root = this.rootNode;
|
||||
this.nodeStack = [this.rootNode];
|
||||
return this.rootNode;
|
||||
}
|
||||
buildCompositeNode(feature) {
|
||||
const compositeNode = new CompositeCstNodeImpl();
|
||||
compositeNode.grammarSource = feature;
|
||||
compositeNode.root = this.rootNode;
|
||||
this.current.content.push(compositeNode);
|
||||
this.nodeStack.push(compositeNode);
|
||||
return compositeNode;
|
||||
}
|
||||
buildLeafNode(token, feature) {
|
||||
const leafNode = new LeafCstNodeImpl(token.startOffset, token.image.length, tokenToRange(token), token.tokenType, !feature);
|
||||
leafNode.grammarSource = feature;
|
||||
leafNode.root = this.rootNode;
|
||||
this.current.content.push(leafNode);
|
||||
return leafNode;
|
||||
}
|
||||
removeNode(node) {
|
||||
const parent = node.container;
|
||||
if (parent) {
|
||||
const index = parent.content.indexOf(node);
|
||||
if (index >= 0) {
|
||||
parent.content.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
addHiddenNodes(tokens) {
|
||||
const nodes = [];
|
||||
for (const token of tokens) {
|
||||
const leafNode = new LeafCstNodeImpl(token.startOffset, token.image.length, tokenToRange(token), token.tokenType, true);
|
||||
leafNode.root = this.rootNode;
|
||||
nodes.push(leafNode);
|
||||
}
|
||||
let current = this.current;
|
||||
let added = false;
|
||||
// If we are within a composite node, we add the hidden nodes to the content
|
||||
if (current.content.length > 0) {
|
||||
current.content.push(...nodes);
|
||||
return;
|
||||
}
|
||||
// Otherwise we are at a newly created node
|
||||
// Instead of adding the hidden nodes here, we search for the first parent node with content
|
||||
while (current.container) {
|
||||
const index = current.container.content.indexOf(current);
|
||||
if (index > 0) {
|
||||
// Add the hidden nodes before the current node
|
||||
current.container.content.splice(index, 0, ...nodes);
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
current = current.container;
|
||||
}
|
||||
// If we arrive at the root node, we add the hidden nodes at the beginning
|
||||
// This is the case if the hidden nodes are the first nodes in the tree
|
||||
if (!added) {
|
||||
this.rootNode.content.unshift(...nodes);
|
||||
}
|
||||
}
|
||||
construct(item) {
|
||||
const current = this.current;
|
||||
// The specified item could be a datatype ($type is symbol) or a fragment ($type is undefined)
|
||||
// Only if the $type is a string, we actually assign the element
|
||||
if (typeof item.$type === 'string') {
|
||||
this.current.astNode = item;
|
||||
}
|
||||
item.$cstNode = current;
|
||||
const node = this.nodeStack.pop();
|
||||
// Empty composite nodes are not valid
|
||||
// Simply remove the node from the tree
|
||||
if ((node === null || node === void 0 ? void 0 : node.content.length) === 0) {
|
||||
this.removeNode(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
export class AbstractCstNode {
|
||||
/** @deprecated use `container` instead. */
|
||||
get parent() {
|
||||
return this.container;
|
||||
}
|
||||
/** @deprecated use `grammarSource` instead. */
|
||||
get feature() {
|
||||
return this.grammarSource;
|
||||
}
|
||||
get hidden() {
|
||||
return false;
|
||||
}
|
||||
get astNode() {
|
||||
var _a, _b;
|
||||
const node = typeof ((_a = this._astNode) === null || _a === void 0 ? void 0 : _a.$type) === 'string' ? this._astNode : (_b = this.container) === null || _b === void 0 ? void 0 : _b.astNode;
|
||||
if (!node) {
|
||||
throw new Error('This node has no associated AST element');
|
||||
}
|
||||
return node;
|
||||
}
|
||||
set astNode(value) {
|
||||
this._astNode = value;
|
||||
}
|
||||
/** @deprecated use `astNode` instead. */
|
||||
get element() {
|
||||
return this.astNode;
|
||||
}
|
||||
get text() {
|
||||
return this.root.fullText.substring(this.offset, this.end);
|
||||
}
|
||||
}
|
||||
export class LeafCstNodeImpl extends AbstractCstNode {
|
||||
get offset() {
|
||||
return this._offset;
|
||||
}
|
||||
get length() {
|
||||
return this._length;
|
||||
}
|
||||
get end() {
|
||||
return this._offset + this._length;
|
||||
}
|
||||
get hidden() {
|
||||
return this._hidden;
|
||||
}
|
||||
get tokenType() {
|
||||
return this._tokenType;
|
||||
}
|
||||
get range() {
|
||||
return this._range;
|
||||
}
|
||||
constructor(offset, length, range, tokenType, hidden = false) {
|
||||
super();
|
||||
this._hidden = hidden;
|
||||
this._offset = offset;
|
||||
this._tokenType = tokenType;
|
||||
this._length = length;
|
||||
this._range = range;
|
||||
}
|
||||
}
|
||||
export class CompositeCstNodeImpl extends AbstractCstNode {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.content = new CstNodeContainer(this);
|
||||
}
|
||||
/** @deprecated use `content` instead. */
|
||||
get children() {
|
||||
return this.content;
|
||||
}
|
||||
get offset() {
|
||||
var _a, _b;
|
||||
return (_b = (_a = this.firstNonHiddenNode) === null || _a === void 0 ? void 0 : _a.offset) !== null && _b !== void 0 ? _b : 0;
|
||||
}
|
||||
get length() {
|
||||
return this.end - this.offset;
|
||||
}
|
||||
get end() {
|
||||
var _a, _b;
|
||||
return (_b = (_a = this.lastNonHiddenNode) === null || _a === void 0 ? void 0 : _a.end) !== null && _b !== void 0 ? _b : 0;
|
||||
}
|
||||
get range() {
|
||||
const firstNode = this.firstNonHiddenNode;
|
||||
const lastNode = this.lastNonHiddenNode;
|
||||
if (firstNode && lastNode) {
|
||||
if (this._rangeCache === undefined) {
|
||||
const { range: firstRange } = firstNode;
|
||||
const { range: lastRange } = lastNode;
|
||||
this._rangeCache = { start: firstRange.start, end: lastRange.end.line < firstRange.start.line ? firstRange.start : lastRange.end };
|
||||
}
|
||||
return this._rangeCache;
|
||||
}
|
||||
else {
|
||||
return { start: Position.create(0, 0), end: Position.create(0, 0) };
|
||||
}
|
||||
}
|
||||
get firstNonHiddenNode() {
|
||||
for (const child of this.content) {
|
||||
if (!child.hidden) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return this.content[0];
|
||||
}
|
||||
get lastNonHiddenNode() {
|
||||
for (let i = this.content.length - 1; i >= 0; i--) {
|
||||
const child = this.content[i];
|
||||
if (!child.hidden) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return this.content[this.content.length - 1];
|
||||
}
|
||||
}
|
||||
class CstNodeContainer extends Array {
|
||||
constructor(parent) {
|
||||
super();
|
||||
this.parent = parent;
|
||||
Object.setPrototypeOf(this, CstNodeContainer.prototype);
|
||||
}
|
||||
push(...items) {
|
||||
this.addParents(items);
|
||||
return super.push(...items);
|
||||
}
|
||||
unshift(...items) {
|
||||
this.addParents(items);
|
||||
return super.unshift(...items);
|
||||
}
|
||||
splice(start, count, ...items) {
|
||||
this.addParents(items);
|
||||
return super.splice(start, count, ...items);
|
||||
}
|
||||
addParents(items) {
|
||||
for (const item of items) {
|
||||
item.container = this.parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
export class RootCstNodeImpl extends CompositeCstNodeImpl {
|
||||
get text() {
|
||||
return this._text.substring(this.offset, this.end);
|
||||
}
|
||||
get fullText() {
|
||||
return this._text;
|
||||
}
|
||||
constructor(input) {
|
||||
super();
|
||||
this._text = '';
|
||||
this._text = input !== null && input !== void 0 ? input : '';
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=cst-node-builder.js.map
|
||||
Reference in New Issue
Block a user