@@ -207,6 +207,59 @@ impl<'a> Node<'a> {
207207 pub fn is_comment ( & self ) -> bool {
208208 matches ! ( self . kind( ) , SyntaxKind :: C_COMMENT | SyntaxKind :: SQL_COMMENT )
209209 }
210+
211+ /// Return the rightmost token in the subtree of this node
212+ /// this is not tree-sitter's API
213+ pub fn last_token ( & self ) -> Option < Node < ' a > > {
214+ match & self . node_or_token {
215+ NodeOrToken :: Node ( node) => node. last_token ( ) . map ( |token| Node {
216+ input : self . input ,
217+ range_map : Rc :: clone ( & self . range_map ) ,
218+ node_or_token : NodeOrToken :: Token ( token) ,
219+ } ) ,
220+ NodeOrToken :: Token ( token) => Some ( Node {
221+ input : self . input ,
222+ range_map : Rc :: clone ( & self . range_map ) ,
223+ node_or_token : NodeOrToken :: Token ( token) ,
224+ } ) ,
225+ }
226+ }
227+
228+ /// Returns an iterator over all descendant nodes (not including tokens)
229+ /// this is not tree-sitter's API
230+ pub fn descendants ( & self ) -> impl Iterator < Item = Node < ' a > > {
231+ struct Descendants < ' a > {
232+ input : & ' a str ,
233+ range_map : Rc < HashMap < TextRange , Range > > ,
234+ iter : Box < dyn Iterator < Item = & ' a ResolvedNode > + ' a > ,
235+ }
236+
237+ impl < ' a > Iterator for Descendants < ' a > {
238+ type Item = Node < ' a > ;
239+
240+ fn next ( & mut self ) -> Option < Self :: Item > {
241+ self . iter . next ( ) . map ( |node| Node {
242+ input : self . input ,
243+ range_map : Rc :: clone ( & self . range_map ) ,
244+ node_or_token : NodeOrToken :: Node ( node) ,
245+ } )
246+ }
247+ }
248+
249+ if let Some ( node) = self . node_or_token . as_node ( ) {
250+ Descendants {
251+ input : self . input ,
252+ range_map : Rc :: clone ( & self . range_map ) ,
253+ iter : Box :: new ( node. descendants ( ) ) ,
254+ }
255+ } else {
256+ Descendants {
257+ input : self . input ,
258+ range_map : Rc :: clone ( & self . range_map ) ,
259+ iter : Box :: new ( std:: iter:: empty ( ) ) ,
260+ }
261+ }
262+ }
210263}
211264
212265impl < ' a > From < Node < ' a > > for TreeCursor < ' a > {
@@ -513,4 +566,36 @@ from
513566
514567 assert_eq ! ( stmt_count, 2 ) ;
515568 }
569+
570+ #[ test]
571+ fn test_last_token_returns_rightmost_token ( ) {
572+ let src = "SELECT u.*, (v).id, name;" ;
573+ let tree = parse ( src) . unwrap ( ) ;
574+ let root = tree. root_node ( ) ;
575+
576+ let target_list = root
577+ . descendants ( )
578+ . find ( |node| node. kind ( ) == SyntaxKind :: target_list)
579+ . expect ( "should find target_list" ) ;
580+
581+ // last token of the target_list is returned
582+ let last_token = target_list. last_token ( ) . expect ( "should have last token" ) ;
583+ assert_eq ! ( last_token. text( ) , "name" ) ;
584+
585+ let target_els = target_list
586+ . children ( )
587+ . into_iter ( )
588+ . filter ( |node| node. kind ( ) == SyntaxKind :: target_el)
589+ . collect :: < Vec < _ > > ( ) ;
590+
591+ let mut last_tokens = target_els
592+ . iter ( )
593+ . map ( |node| node. last_token ( ) . expect ( "should have last token" ) ) ;
594+
595+ // last token of each target_el is returned
596+ assert_eq ! ( last_tokens. next( ) . unwrap( ) . text( ) , "*" ) ;
597+ assert_eq ! ( last_tokens. next( ) . unwrap( ) . text( ) , "id" ) ;
598+ assert_eq ! ( last_tokens. next( ) . unwrap( ) . text( ) , "name" ) ;
599+ assert ! ( last_tokens. next( ) . is_none( ) ) ;
600+ }
516601}
0 commit comments