@@ -33,7 +33,8 @@ use syntax::tokenstream::{Cursor, ThinTokenStream, TokenStream, TokenTree};
33
33
use syntax:: util:: ThinVec ;
34
34
35
35
use codemap:: SpanUtils ;
36
- use comment:: { contains_comment, remove_trailing_white_spaces, FindUncommented } ;
36
+ use comment:: { contains_comment, remove_trailing_white_spaces, CharClasses , FindUncommented ,
37
+ FullCodeCharKind } ;
37
38
use expr:: rewrite_array;
38
39
use lists:: { itemize_list, write_list, ListFormatting } ;
39
40
use overflow;
@@ -399,6 +400,28 @@ pub fn rewrite_macro_def(
399
400
Some ( result)
400
401
}
401
402
403
+ fn register_metavariable (
404
+ map : & mut HashMap < String , String > ,
405
+ result : & mut String ,
406
+ name : & str ,
407
+ dollar_count : usize ,
408
+ ) {
409
+ let mut new_name = String :: new ( ) ;
410
+ let mut old_name = String :: new ( ) ;
411
+
412
+ old_name. push ( '$' ) ;
413
+ for _ in 0 ..( dollar_count - 1 ) {
414
+ new_name. push ( '$' ) ;
415
+ old_name. push ( '$' ) ;
416
+ }
417
+ new_name. push ( 'z' ) ;
418
+ new_name. push_str ( & name) ;
419
+ old_name. push_str ( & name) ;
420
+
421
+ result. push_str ( & new_name) ;
422
+ map. insert ( old_name, new_name) ;
423
+ }
424
+
402
425
// Replaces `$foo` with `zfoo`. We must check for name overlap to ensure we
403
426
// aren't causing problems.
404
427
// This should also work for escaped `$` variables, where we leave earlier `$`s.
@@ -409,31 +432,20 @@ fn replace_names(input: &str) -> Option<(String, HashMap<String, String>)> {
409
432
let mut dollar_count = 0 ;
410
433
let mut cur_name = String :: new ( ) ;
411
434
412
- for c in input. chars ( ) {
413
- if c == '$' {
435
+ for ( kind, c) in CharClasses :: new ( input. chars ( ) ) {
436
+ if kind != FullCodeCharKind :: Normal {
437
+ result. push ( c) ;
438
+ } else if c == '$' {
414
439
dollar_count += 1 ;
415
440
} else if dollar_count == 0 {
416
441
result. push ( c) ;
417
442
} else if !c. is_alphanumeric ( ) && !cur_name. is_empty ( ) {
418
443
// Terminates a name following one or more dollars.
419
- let mut new_name = String :: new ( ) ;
420
- let mut old_name = String :: new ( ) ;
421
- old_name. push ( '$' ) ;
422
- for _ in 0 ..( dollar_count - 1 ) {
423
- new_name. push ( '$' ) ;
424
- old_name. push ( '$' ) ;
425
- }
426
- new_name. push ( 'z' ) ;
427
- new_name. push_str ( & cur_name) ;
428
- old_name. push_str ( & cur_name) ;
429
-
430
- result. push_str ( & new_name) ;
431
- substs. insert ( old_name, new_name) ;
444
+ register_metavariable ( & mut substs, & mut result, & cur_name, dollar_count) ;
432
445
433
446
result. push ( c) ;
434
-
435
447
dollar_count = 0 ;
436
- cur_name = String :: new ( ) ;
448
+ cur_name. clear ( ) ;
437
449
} else if c == '(' && cur_name. is_empty ( ) {
438
450
// FIXME: Support macro def with repeat.
439
451
return None ;
@@ -442,21 +454,8 @@ fn replace_names(input: &str) -> Option<(String, HashMap<String, String>)> {
442
454
}
443
455
}
444
456
445
- // FIXME: duplicate code
446
457
if !cur_name. is_empty ( ) {
447
- let mut new_name = String :: new ( ) ;
448
- let mut old_name = String :: new ( ) ;
449
- old_name. push ( '$' ) ;
450
- for _ in 0 ..( dollar_count - 1 ) {
451
- new_name. push ( '$' ) ;
452
- old_name. push ( '$' ) ;
453
- }
454
- new_name. push ( 'z' ) ;
455
- new_name. push_str ( & cur_name) ;
456
- old_name. push_str ( & cur_name) ;
457
-
458
- result. push_str ( & new_name) ;
459
- substs. insert ( old_name, new_name) ;
458
+ register_metavariable ( & mut substs, & mut result, & cur_name, dollar_count) ;
460
459
}
461
460
462
461
debug ! ( "replace_names `{}` {:?}" , result, substs) ;
0 commit comments