@@ -9,15 +9,14 @@ import type { Range } from 'vscode-languageserver-types';
99import type { AbstractElement } from '../languages/generated/ast.js' ;
1010import type { AstNode , CompositeCstNode , CstNode , LeafCstNode , RootCstNode } from '../syntax-tree.js' ;
1111import { Position } from 'vscode-languageserver-types' ;
12- import { isCompositeCstNode } from '../syntax-tree.js' ;
1312import { tokenToRange } from '../utils/cst-utils.js' ;
1413
1514export class CstNodeBuilder {
1615
1716 private rootNode ! : RootCstNodeImpl ;
1817 private nodeStack : CompositeCstNodeImpl [ ] = [ ] ;
1918
20- private get current ( ) : CompositeCstNodeImpl {
19+ get current ( ) : CompositeCstNodeImpl {
2120 return this . nodeStack [ this . nodeStack . length - 1 ] ?? this . rootNode ;
2221 }
2322
@@ -37,8 +36,8 @@ export class CstNodeBuilder {
3736 return compositeNode ;
3837 }
3938
40- buildLeafNode ( token : IToken , feature : AbstractElement ) : LeafCstNode {
41- const leafNode = new LeafCstNodeImpl ( token . startOffset , token . image . length , tokenToRange ( token ) , token . tokenType , false ) ;
39+ buildLeafNode ( token : IToken , feature ? : AbstractElement ) : LeafCstNode {
40+ const leafNode = new LeafCstNodeImpl ( token . startOffset , token . image . length , tokenToRange ( token ) , token . tokenType , ! feature ) ;
4241 leafNode . grammarSource = feature ;
4342 leafNode . root = this . rootNode ;
4443 this . current . content . push ( leafNode ) ;
@@ -55,6 +54,33 @@ export class CstNodeBuilder {
5554 }
5655 }
5756
57+ addHiddenNode ( token : IToken ) : void {
58+ const leafNode = new LeafCstNodeImpl ( token . startOffset , token . image . length , tokenToRange ( token ) , token . tokenType , true ) ;
59+ leafNode . root = this . rootNode ;
60+ let current : CompositeCstNode = this . current ;
61+ let added = false ;
62+ // If we are within a composite node, we add the hidden node to the content
63+ if ( current . content . length > 0 ) {
64+ current . content . push ( leafNode ) ;
65+ return ;
66+ }
67+ while ( current . container ) {
68+ const index = current . container . content . indexOf ( current ) ;
69+ if ( index > 0 ) {
70+ // Add the hidden node before the current node
71+ current . container . content . splice ( index , 0 , leafNode ) ;
72+ added = true ;
73+ break ;
74+ }
75+ current = current . container ;
76+ }
77+ // If we arrive at the root node, we add the hidden node at the beginning
78+ // This is the case if the hidden node is the first node in the tree
79+ if ( ! added ) {
80+ this . rootNode . content . unshift ( leafNode ) ;
81+ }
82+ }
83+
5884 construct ( item : { $type : string | symbol | undefined , $cstNode : CstNode } ) : void {
5985 const current : CstNode = this . current ;
6086 // The specified item could be a datatype ($type is symbol) or a fragment ($type is undefined)
@@ -70,34 +96,6 @@ export class CstNodeBuilder {
7096 this . removeNode ( node ) ;
7197 }
7298 }
73-
74- addHiddenTokens ( hiddenTokens : IToken [ ] ) : void {
75- for ( const token of hiddenTokens ) {
76- const hiddenNode = new LeafCstNodeImpl ( token . startOffset , token . image . length , tokenToRange ( token ) , token . tokenType , true ) ;
77- hiddenNode . root = this . rootNode ;
78- this . addHiddenToken ( this . rootNode , hiddenNode ) ;
79- }
80- }
81-
82- private addHiddenToken ( node : CompositeCstNode , token : LeafCstNode ) : void {
83- const { offset : tokenStart , end : tokenEnd } = token ;
84-
85- for ( let i = 0 ; i < node . content . length ; i ++ ) {
86- const child = node . content [ i ] ;
87- const { offset : childStart , end : childEnd } = child ;
88- if ( isCompositeCstNode ( child ) && tokenStart > childStart && tokenEnd < childEnd ) {
89- this . addHiddenToken ( child , token ) ;
90- return ;
91- } else if ( tokenEnd <= childStart ) {
92- node . content . splice ( i , 0 , token ) ;
93- return ;
94- }
95- }
96-
97- // We know that we haven't found a suited position for the token
98- // So we simply add it to the end of the current node
99- node . content . push ( token ) ;
100- }
10199}
102100
103101export abstract class AbstractCstNode implements CstNode {
@@ -107,7 +105,7 @@ export abstract class AbstractCstNode implements CstNode {
107105 abstract get range ( ) : Range ;
108106
109107 container ?: CompositeCstNode ;
110- grammarSource : AbstractElement ;
108+ grammarSource ? : AbstractElement ;
111109 root : RootCstNode ;
112110 private _astNode ?: AstNode ;
113111
@@ -117,7 +115,7 @@ export abstract class AbstractCstNode implements CstNode {
117115 }
118116
119117 /** @deprecated use `grammarSource` instead. */
120- get feature ( ) : AbstractElement {
118+ get feature ( ) : AbstractElement | undefined {
121119 return this . grammarSource ;
122120 }
123121
0 commit comments