@@ -6,7 +6,7 @@ use rustc_hash::FxHashMap;
6
6
use test_utils:: {
7
7
extract_range_or_offset, Fixture , RangeOrOffset , CURSOR_MARKER , ESCAPED_CURSOR_MARKER ,
8
8
} ;
9
- use tt:: token_id:: Subtree ;
9
+ use tt:: token_id:: { Leaf , Subtree , TokenTree } ;
10
10
use vfs:: { file_set:: FileSet , VfsPath } ;
11
11
12
12
use crate :: {
@@ -310,7 +310,7 @@ impl ChangeFixture {
310
310
}
311
311
}
312
312
313
- fn default_test_proc_macros ( ) -> [ ( String , ProcMacro ) ; 4 ] {
313
+ fn default_test_proc_macros ( ) -> [ ( String , ProcMacro ) ; 5 ] {
314
314
[
315
315
(
316
316
r#"
@@ -368,6 +368,20 @@ pub fn mirror(input: TokenStream) -> TokenStream {
368
368
expander : Arc :: new ( MirrorProcMacroExpander ) ,
369
369
} ,
370
370
) ,
371
+ (
372
+ r#"
373
+ #[proc_macro]
374
+ pub fn shorten(input: TokenStream) -> TokenStream {
375
+ loop {}
376
+ }
377
+ "#
378
+ . into ( ) ,
379
+ ProcMacro {
380
+ name : "shorten" . into ( ) ,
381
+ kind : crate :: ProcMacroKind :: FuncLike ,
382
+ expander : Arc :: new ( ShortenProcMacroExpander ) ,
383
+ } ,
384
+ ) ,
371
385
]
372
386
}
373
387
@@ -508,3 +522,47 @@ impl ProcMacroExpander for MirrorProcMacroExpander {
508
522
Ok ( traverse ( input) )
509
523
}
510
524
}
525
+
526
+ // Replaces every literal with an empty string literal and every identifier with its first letter,
527
+ // but retains all tokens' span. Useful for testing we don't assume token hasn't been modified by
528
+ // macros even if it retains its span.
529
+ #[ derive( Debug ) ]
530
+ struct ShortenProcMacroExpander ;
531
+ impl ProcMacroExpander for ShortenProcMacroExpander {
532
+ fn expand (
533
+ & self ,
534
+ input : & Subtree ,
535
+ _: Option < & Subtree > ,
536
+ _: & Env ,
537
+ ) -> Result < Subtree , ProcMacroExpansionError > {
538
+ return Ok ( traverse ( input) ) ;
539
+
540
+ fn traverse ( input : & Subtree ) -> Subtree {
541
+ let token_trees = input
542
+ . token_trees
543
+ . iter ( )
544
+ . map ( |it| match it {
545
+ TokenTree :: Leaf ( leaf) => tt:: TokenTree :: Leaf ( modify_leaf ( leaf) ) ,
546
+ TokenTree :: Subtree ( subtree) => tt:: TokenTree :: Subtree ( traverse ( subtree) ) ,
547
+ } )
548
+ . collect ( ) ;
549
+ Subtree { delimiter : input. delimiter , token_trees }
550
+ }
551
+
552
+ fn modify_leaf ( leaf : & Leaf ) -> Leaf {
553
+ let mut leaf = leaf. clone ( ) ;
554
+ match & mut leaf {
555
+ Leaf :: Literal ( it) => {
556
+ // XXX Currently replaces any literals with an empty string, but supporting
557
+ // "shortening" other literals would be nice.
558
+ it. text = "\" \" " . into ( ) ;
559
+ }
560
+ Leaf :: Punct ( _) => { }
561
+ Leaf :: Ident ( it) => {
562
+ it. text = it. text . chars ( ) . take ( 1 ) . collect ( ) ;
563
+ }
564
+ }
565
+ leaf
566
+ }
567
+ }
568
+ }
0 commit comments