1- use crate :: green:: NodeCacheNodeEntryMut ;
21use crate :: {
32 cow_mut:: CowMut ,
4- green:: { GreenElement , NodeCache } ,
3+ green:: { GreenElement , LiveSet , NodeCache , NodeCacheNodeEntryMut } ,
54 syntax:: TriviaPiece ,
65 GreenNode , Language , NodeOrToken , ParsedChildren , SyntaxFactory , SyntaxKind , SyntaxNode ,
76} ;
@@ -17,6 +16,7 @@ pub struct TreeBuilder<'cache, L: Language, S: SyntaxFactory<Kind = L::Kind>> {
1716 cache : CowMut < ' cache , NodeCache > ,
1817 parents : Vec < ( L :: Kind , usize ) > ,
1918 children : Vec < ( u64 , GreenElement ) > ,
19+ live_set : Option < LiveSet > ,
2020 ph : PhantomData < S > ,
2121}
2222
@@ -26,6 +26,7 @@ impl<L: Language, S: SyntaxFactory<Kind = L::Kind>> Default for TreeBuilder<'_,
2626 cache : CowMut :: default ( ) ,
2727 parents : Vec :: default ( ) ,
2828 children : Vec :: default ( ) ,
29+ live_set : None ,
2930 ph : PhantomData ,
3031 }
3132 }
@@ -40,10 +41,16 @@ impl<L: Language, S: SyntaxFactory<Kind = L::Kind>> TreeBuilder<'_, L, S> {
4041 /// Reusing `NodeCache` between different [TreeBuilder]`s saves memory.
4142 /// It allows to structurally share underlying trees.
4243 pub fn with_cache ( cache : & mut NodeCache ) -> TreeBuilder < ' _ , L , S > {
44+ let has_cached_nodes = !cache. is_empty ( ) ;
4345 TreeBuilder {
4446 cache : CowMut :: Borrowed ( cache) ,
4547 parents : Vec :: new ( ) ,
4648 children : Vec :: new ( ) ,
49+ // We don't need to track the set of live nodes and tokens if the
50+ // cache was initially empty, as it means all the entries present
51+ // in the cache at the end of the parsing session were inserted by
52+ // this instance of the TreeBuilder
53+ live_set : has_cached_nodes. then ( LiveSet :: default) ,
4754 ph : PhantomData ,
4855 }
4956 }
@@ -67,7 +74,9 @@ impl<L: Language, S: SyntaxFactory<Kind = L::Kind>> TreeBuilder<'_, L, S> {
6774 /// Adds new token to the current branch.
6875 #[ inline]
6976 pub fn token ( & mut self , kind : L :: Kind , text : & str ) -> & mut Self {
70- let ( hash, token) = self . cache . token ( kind. to_raw ( ) , text) ;
77+ let ( hash, token) = self
78+ . cache
79+ . token ( kind. to_raw ( ) , text, self . live_set . as_mut ( ) ) ;
7180 self . children . push ( ( hash, token. into ( ) ) ) ;
7281 self
7382 }
@@ -81,9 +90,13 @@ impl<L: Language, S: SyntaxFactory<Kind = L::Kind>> TreeBuilder<'_, L, S> {
8190 leading : & [ TriviaPiece ] ,
8291 trailing : & [ TriviaPiece ] ,
8392 ) {
84- let ( hash, token) = self
85- . cache
86- . token_with_trivia ( kind. to_raw ( ) , text, leading, trailing) ;
93+ let ( hash, token) = self . cache . token_with_trivia (
94+ kind. to_raw ( ) ,
95+ text,
96+ leading,
97+ trailing,
98+ self . live_set . as_mut ( ) ,
99+ ) ;
87100 self . children . push ( ( hash, token. into ( ) ) ) ;
88101 }
89102
@@ -103,7 +116,7 @@ impl<L: Language, S: SyntaxFactory<Kind = L::Kind>> TreeBuilder<'_, L, S> {
103116 let raw_kind = kind. to_raw ( ) ;
104117
105118 let slots = & self . children [ first_child..] ;
106- let node_entry = self . cache . node ( raw_kind, slots) ;
119+ let node_entry = self . cache . node ( raw_kind, slots, self . live_set . as_mut ( ) ) ;
107120
108121 let mut build_node = || {
109122 let children = ParsedChildren :: new ( & mut self . children , first_child) ;
@@ -184,13 +197,19 @@ impl<L: Language, S: SyntaxFactory<Kind = L::Kind>> TreeBuilder<'_, L, S> {
184197 /// are paired!
185198 #[ inline]
186199 #[ must_use]
187- pub fn finish ( self ) -> SyntaxNode < L > {
188- SyntaxNode :: new_root ( self . finish_green ( ) )
200+ pub fn finish ( mut self ) -> SyntaxNode < L > {
201+ let root = SyntaxNode :: new_root ( self . finish_green ( ) ) ;
202+
203+ if let Some ( live_set) = self . live_set . take ( ) {
204+ self . cache . evict_unreachable ( live_set) ;
205+ }
206+
207+ root
189208 }
190209
191210 // For tests
192211 #[ must_use]
193- pub ( crate ) fn finish_green ( mut self ) -> GreenNode {
212+ pub ( crate ) fn finish_green ( & mut self ) -> GreenNode {
194213 assert_eq ! ( self . children. len( ) , 1 ) ;
195214 match self . children . pop ( ) . unwrap ( ) . 1 {
196215 NodeOrToken :: Node ( node) => node,
0 commit comments