1- //! FIXME: write short doc here
1+ //! See `TextTokenSource` docs.
22
3- use ra_parser:: Token as PToken ;
43use ra_parser:: TokenSource ;
54
65use crate :: { parsing:: lexer:: Token , SyntaxKind :: EOF , TextRange , TextSize } ;
76
7+ /// Implementation of `ra_parser::TokenSource` that takes tokens from source code text.
88pub ( crate ) struct TextTokenSource < ' t > {
99 text : & ' t str ,
10- /// start position of each token(expect whitespace and comment)
10+ /// token and its start position (non- whitespace/ comment tokens )
1111 /// ```non-rust
1212 /// struct Foo;
13- /// ^------^---
14- /// | | ^-
15- /// 0 7 10
13+ /// ^------^--^-
14+ /// | | \________
15+ /// | \____ \
16+ /// | \ |
17+ /// (struct, 0) (Foo, 7) (;, 10)
1618 /// ```
17- /// (token, start_offset): `[(struct, 0), (Foo, 7), (;, 10)]`
18- start_offsets : Vec < TextSize > ,
19- /// non-whitespace/comment tokens
20- /// ```non-rust
21- /// struct Foo {}
22- /// ^^^^^^ ^^^ ^^
23- /// ```
24- /// tokens: `[struct, Foo, {, }]`
25- tokens : Vec < Token > ,
19+ /// `[(struct, 0), (Foo, 7), (;, 10)]`
20+ token_offset_pairs : Vec < ( Token , TextSize ) > ,
2621
2722 /// Current token and position
28- curr : ( PToken , usize ) ,
23+ curr : ( ra_parser :: Token , usize ) ,
2924}
3025
3126impl < ' t > TokenSource for TextTokenSource < ' t > {
32- fn current ( & self ) -> PToken {
27+ fn current ( & self ) -> ra_parser :: Token {
3328 self . curr . 0
3429 }
3530
36- fn lookahead_nth ( & self , n : usize ) -> PToken {
37- mk_token ( self . curr . 1 + n, & self . start_offsets , & self . tokens )
31+ fn lookahead_nth ( & self , n : usize ) -> ra_parser :: Token {
32+ mk_token ( self . curr . 1 + n, & self . token_offset_pairs )
3833 }
3934
4035 fn bump ( & mut self ) {
@@ -43,45 +38,47 @@ impl<'t> TokenSource for TextTokenSource<'t> {
4338 }
4439
4540 let pos = self . curr . 1 + 1 ;
46- self . curr = ( mk_token ( pos, & self . start_offsets , & self . tokens ) , pos) ;
41+ self . curr = ( mk_token ( pos, & self . token_offset_pairs ) , pos) ;
4742 }
4843
4944 fn is_keyword ( & self , kw : & str ) -> bool {
50- let pos = self . curr . 1 ;
51- if pos >= self . tokens . len ( ) {
52- return false ;
53- }
54- let range = TextRange :: at ( self . start_offsets [ pos] , self . tokens [ pos] . len ) ;
55- self . text [ range] == * kw
45+ self . token_offset_pairs
46+ . get ( self . curr . 1 )
47+ . map ( |( token, offset) | & self . text [ TextRange :: at ( * offset, token. len ) ] == kw)
48+ . unwrap_or ( false )
5649 }
5750}
5851
59- fn mk_token ( pos : usize , start_offsets : & [ TextSize ] , tokens : & [ Token ] ) -> PToken {
60- let kind = tokens. get ( pos) . map ( |t| t. kind ) . unwrap_or ( EOF ) ;
61- let is_jointed_to_next = if pos + 1 < start_offsets. len ( ) {
62- start_offsets[ pos] + tokens[ pos] . len == start_offsets[ pos + 1 ]
63- } else {
64- false
52+ fn mk_token ( pos : usize , token_offset_pairs : & [ ( Token , TextSize ) ] ) -> ra_parser:: Token {
53+ let ( kind, is_jointed_to_next) = match token_offset_pairs. get ( pos) {
54+ Some ( ( token, offset) ) => (
55+ token. kind ,
56+ token_offset_pairs
57+ . get ( pos + 1 )
58+ . map ( |( _, next_offset) | offset + token. len == * next_offset)
59+ . unwrap_or ( false ) ,
60+ ) ,
61+ None => ( EOF , false ) ,
6562 } ;
66-
67- PToken { kind, is_jointed_to_next }
63+ ra_parser:: Token { kind, is_jointed_to_next }
6864}
6965
7066impl < ' t > TextTokenSource < ' t > {
7167 /// Generate input from tokens(expect comment and whitespace).
7268 pub fn new ( text : & ' t str , raw_tokens : & ' t [ Token ] ) -> TextTokenSource < ' t > {
73- let mut tokens = Vec :: new ( ) ;
74- let mut start_offsets = Vec :: new ( ) ;
75- let mut len = 0 . into ( ) ;
76- for & token in raw_tokens. iter ( ) {
77- if !token. kind . is_trivia ( ) {
78- tokens. push ( token) ;
79- start_offsets. push ( len) ;
80- }
81- len += token. len ;
82- }
69+ let token_offset_pairs: Vec < _ > = raw_tokens
70+ . iter ( )
71+ . filter_map ( {
72+ let mut len = 0 . into ( ) ;
73+ move |token| {
74+ let pair = if token. kind . is_trivia ( ) { None } else { Some ( ( * token, len) ) } ;
75+ len += token. len ;
76+ pair
77+ }
78+ } )
79+ . collect ( ) ;
8380
84- let first = mk_token ( 0 , & start_offsets , & tokens ) ;
85- TextTokenSource { text, start_offsets , tokens , curr : ( first, 0 ) }
81+ let first = mk_token ( 0 , & token_offset_pairs ) ;
82+ TextTokenSource { text, token_offset_pairs , curr : ( first, 0 ) }
8683 }
8784}
0 commit comments