@@ -12,6 +12,9 @@ use tt::buffer::{Cursor, TokenBuffer};
12
12
13
13
use crate :: { to_parser_input:: to_parser_input, tt_iter:: TtIter , TokenMap } ;
14
14
15
+ #[ cfg( test) ]
16
+ mod tests;
17
+
15
18
/// Convert the syntax node to a `TokenTree` (what macro
16
19
/// will consume).
17
20
pub fn syntax_node_to_token_tree ( node : & SyntaxNode ) -> ( tt:: Subtree , TokenMap ) {
@@ -228,7 +231,7 @@ fn convert_tokens<C: TokenConverter>(conv: &mut C) -> tt::Subtree {
228
231
}
229
232
230
233
let spacing = match conv. peek ( ) . map ( |next| next. kind ( conv) ) {
231
- Some ( kind) if !kind . is_trivia ( ) => tt:: Spacing :: Joint ,
234
+ Some ( kind) if is_single_token_op ( kind ) => tt:: Spacing :: Joint ,
232
235
_ => tt:: Spacing :: Alone ,
233
236
} ;
234
237
let char = match token. to_char ( conv) {
@@ -307,6 +310,35 @@ fn convert_tokens<C: TokenConverter>(conv: &mut C) -> tt::Subtree {
307
310
}
308
311
}
309
312
313
+ fn is_single_token_op ( kind : SyntaxKind ) -> bool {
314
+ matches ! (
315
+ kind,
316
+ EQ | L_ANGLE
317
+ | R_ANGLE
318
+ | BANG
319
+ | AMP
320
+ | PIPE
321
+ | TILDE
322
+ | AT
323
+ | DOT
324
+ | COMMA
325
+ | SEMICOLON
326
+ | COLON
327
+ | POUND
328
+ | DOLLAR
329
+ | QUESTION
330
+ | PLUS
331
+ | MINUS
332
+ | STAR
333
+ | SLASH
334
+ | PERCENT
335
+ | CARET
336
+ // LIFETIME_IDENT will be split into a sequence of `'` (a single quote) and an
337
+ // identifier.
338
+ | LIFETIME_IDENT
339
+ )
340
+ }
341
+
310
342
/// Returns the textual content of a doc comment block as a quoted string
311
343
/// That is, strips leading `///` (or `/**`, etc)
312
344
/// and strips the ending `*/`
@@ -591,10 +623,10 @@ impl SynToken {
591
623
}
592
624
593
625
impl SrcToken < Converter > for SynToken {
594
- fn kind ( & self , _ctx : & Converter ) -> SyntaxKind {
626
+ fn kind ( & self , ctx : & Converter ) -> SyntaxKind {
595
627
match self {
596
628
SynToken :: Ordinary ( token) => token. kind ( ) ,
597
- SynToken :: Punch ( token , _ ) => token . kind ( ) ,
629
+ SynToken :: Punch ( .. ) => SyntaxKind :: from_char ( self . to_char ( ctx ) . unwrap ( ) ) . unwrap ( ) ,
598
630
SynToken :: Synthetic ( token) => token. kind ,
599
631
}
600
632
}
@@ -651,7 +683,7 @@ impl TokenConverter for Converter {
651
683
}
652
684
653
685
let curr = self . current . clone ( ) ?;
654
- if !& self . range . contains_range ( curr. text_range ( ) ) {
686
+ if !self . range . contains_range ( curr. text_range ( ) ) {
655
687
return None ;
656
688
}
657
689
let ( new_current, new_synth) =
@@ -809,12 +841,15 @@ impl<'a> TtTreeSink<'a> {
809
841
let next = last. bump ( ) ;
810
842
if let (
811
843
Some ( tt:: buffer:: TokenTreeRef :: Leaf ( tt:: Leaf :: Punct ( curr) , _) ) ,
812
- Some ( tt:: buffer:: TokenTreeRef :: Leaf ( tt:: Leaf :: Punct ( _ ) , _) ) ,
844
+ Some ( tt:: buffer:: TokenTreeRef :: Leaf ( tt:: Leaf :: Punct ( next ) , _) ) ,
813
845
) = ( last. token_tree ( ) , next. token_tree ( ) )
814
846
{
815
847
// Note: We always assume the semi-colon would be the last token in
816
848
// other parts of RA such that we don't add whitespace here.
817
- if curr. spacing == tt:: Spacing :: Alone && curr. char != ';' {
849
+ //
850
+ // When `next` is a `Punct` of `'`, that's a part of a lifetime identifier so we don't
851
+ // need to add whitespace either.
852
+ if curr. spacing == tt:: Spacing :: Alone && curr. char != ';' && next. char != '\'' {
818
853
self . inner . token ( WHITESPACE , " " ) ;
819
854
self . text_pos += TextSize :: of ( ' ' ) ;
820
855
}
0 commit comments