@@ -6,7 +6,7 @@ use rustc_hash::FxHashMap;
66use test_utils:: {
77 extract_range_or_offset, Fixture , RangeOrOffset , CURSOR_MARKER , ESCAPED_CURSOR_MARKER ,
88} ;
9- use tt:: token_id:: Subtree ;
9+ use tt:: token_id:: { Leaf , Subtree , TokenTree } ;
1010use vfs:: { file_set:: FileSet , VfsPath } ;
1111
1212use crate :: {
@@ -310,7 +310,7 @@ impl ChangeFixture {
310310 }
311311}
312312
313- fn default_test_proc_macros ( ) -> [ ( String , ProcMacro ) ; 4 ] {
313+ fn default_test_proc_macros ( ) -> [ ( String , ProcMacro ) ; 5 ] {
314314 [
315315 (
316316 r#"
@@ -368,6 +368,20 @@ pub fn mirror(input: TokenStream) -> TokenStream {
368368 expander : Arc :: new ( MirrorProcMacroExpander ) ,
369369 } ,
370370 ) ,
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+ ) ,
371385 ]
372386}
373387
@@ -508,3 +522,47 @@ impl ProcMacroExpander for MirrorProcMacroExpander {
508522 Ok ( traverse ( input) )
509523 }
510524}
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