Skip to content

Commit 56d2a08

Browse files
authored
Merge pull request #2541 from topecongiro/issue-2358
Skip name replacement in comments and strings
2 parents b7bc720 + 1a969cf commit 56d2a08

File tree

3 files changed

+63
-32
lines changed

3 files changed

+63
-32
lines changed

src/macros.rs

+31-32
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ use syntax::tokenstream::{Cursor, ThinTokenStream, TokenStream, TokenTree};
3333
use syntax::util::ThinVec;
3434

3535
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};
3738
use expr::rewrite_array;
3839
use lists::{itemize_list, write_list, ListFormatting};
3940
use overflow;
@@ -399,6 +400,28 @@ pub fn rewrite_macro_def(
399400
Some(result)
400401
}
401402

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+
402425
// Replaces `$foo` with `zfoo`. We must check for name overlap to ensure we
403426
// aren't causing problems.
404427
// 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>)> {
409432
let mut dollar_count = 0;
410433
let mut cur_name = String::new();
411434

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 == '$' {
414439
dollar_count += 1;
415440
} else if dollar_count == 0 {
416441
result.push(c);
417442
} else if !c.is_alphanumeric() && !cur_name.is_empty() {
418443
// 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);
432445

433446
result.push(c);
434-
435447
dollar_count = 0;
436-
cur_name = String::new();
448+
cur_name.clear();
437449
} else if c == '(' && cur_name.is_empty() {
438450
// FIXME: Support macro def with repeat.
439451
return None;
@@ -442,21 +454,8 @@ fn replace_names(input: &str) -> Option<(String, HashMap<String, String>)> {
442454
}
443455
}
444456

445-
// FIXME: duplicate code
446457
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);
460459
}
461460

462461
debug!("replace_names `{}` {:?}", result, substs);

tests/source/macro_rules.rs

+16
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,19 @@ macro foo($type_name: ident, $docs: expr) {
112112
#[derive(Debug, Clone, Copy)]
113113
pub struct $type_name;
114114
}
115+
116+
// #2538
117+
macro_rules! add_message_to_notes {
118+
($msg:expr) => {{
119+
let mut lines = message.lines();
120+
notes.push_str(&format!("\n{}: {}", level, lines.next().unwrap()));
121+
for line in lines {
122+
notes.push_str(&format!(
123+
"\n{:indent$}{line}",
124+
"",
125+
indent = level.len() + 2,
126+
line = line,
127+
));
128+
}
129+
}}
130+
}

tests/target/macro_rules.rs

+16
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,19 @@ macro foo($type_name: ident, $docs: expr) {
103103
#[derive(Debug, Clone, Copy)]
104104
pub struct $type_name;
105105
}
106+
107+
// #2538
108+
macro_rules! add_message_to_notes {
109+
($msg: expr) => {{
110+
let mut lines = message.lines();
111+
notes.push_str(&format!("\n{}: {}", level, lines.next().unwrap()));
112+
for line in lines {
113+
notes.push_str(&format!(
114+
"\n{:indent$}{line}",
115+
"",
116+
indent = level.len() + 2,
117+
line = line,
118+
));
119+
}
120+
}};
121+
}

0 commit comments

Comments
 (0)