diff options
| author | Nick Cameron <nrc@ncameron.org> | 2018-03-19 08:55:35 +1300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-03-19 08:55:35 +1300 |
| commit | 56d2a08db0784659178fe13fbc767d8258a085f1 (patch) | |
| tree | 1c28bc6def1a20dcaeb6ffe5d13c98f802e59111 | |
| parent | b7bc720638c60950007c5fe7693ffdc522cec294 (diff) | |
| parent | 1a969cff7fe3dc5cef4f36e1786db5dc22b6ed6a (diff) | |
Merge pull request #2541 from topecongiro/issue-2358
Skip name replacement in comments and strings
| -rw-r--r-- | src/macros.rs | 63 | ||||
| -rw-r--r-- | tests/source/macro_rules.rs | 16 | ||||
| -rw-r--r-- | tests/target/macro_rules.rs | 16 |
3 files changed, 63 insertions, 32 deletions
diff --git a/src/macros.rs b/src/macros.rs index b260e15501f..030988e5195 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -33,7 +33,8 @@ use syntax::tokenstream::{Cursor, ThinTokenStream, TokenStream, TokenTree}; use syntax::util::ThinVec; use codemap::SpanUtils; -use comment::{contains_comment, remove_trailing_white_spaces, FindUncommented}; +use comment::{contains_comment, remove_trailing_white_spaces, CharClasses, FindUncommented, + FullCodeCharKind}; use expr::rewrite_array; use lists::{itemize_list, write_list, ListFormatting}; use overflow; @@ -399,6 +400,28 @@ pub fn rewrite_macro_def( Some(result) } +fn register_metavariable( + map: &mut HashMap<String, String>, + result: &mut String, + name: &str, + dollar_count: usize, +) { + let mut new_name = String::new(); + let mut old_name = String::new(); + + old_name.push('$'); + for _ in 0..(dollar_count - 1) { + new_name.push('$'); + old_name.push('$'); + } + new_name.push('z'); + new_name.push_str(&name); + old_name.push_str(&name); + + result.push_str(&new_name); + map.insert(old_name, new_name); +} + // Replaces `$foo` with `zfoo`. We must check for name overlap to ensure we // aren't causing problems. // 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>)> { let mut dollar_count = 0; let mut cur_name = String::new(); - for c in input.chars() { - if c == '$' { + for (kind, c) in CharClasses::new(input.chars()) { + if kind != FullCodeCharKind::Normal { + result.push(c); + } else if c == '$' { dollar_count += 1; } else if dollar_count == 0 { result.push(c); } else if !c.is_alphanumeric() && !cur_name.is_empty() { // Terminates a name following one or more dollars. - let mut new_name = String::new(); - let mut old_name = String::new(); - old_name.push('$'); - for _ in 0..(dollar_count - 1) { - new_name.push('$'); - old_name.push('$'); - } - new_name.push('z'); - new_name.push_str(&cur_name); - old_name.push_str(&cur_name); - - result.push_str(&new_name); - substs.insert(old_name, new_name); + register_metavariable(&mut substs, &mut result, &cur_name, dollar_count); result.push(c); - dollar_count = 0; - cur_name = String::new(); + cur_name.clear(); } else if c == '(' && cur_name.is_empty() { // FIXME: Support macro def with repeat. return None; @@ -442,21 +454,8 @@ fn replace_names(input: &str) -> Option<(String, HashMap<String, String>)> { } } - // FIXME: duplicate code if !cur_name.is_empty() { - let mut new_name = String::new(); - let mut old_name = String::new(); - old_name.push('$'); - for _ in 0..(dollar_count - 1) { - new_name.push('$'); - old_name.push('$'); - } - new_name.push('z'); - new_name.push_str(&cur_name); - old_name.push_str(&cur_name); - - result.push_str(&new_name); - substs.insert(old_name, new_name); + register_metavariable(&mut substs, &mut result, &cur_name, dollar_count); } debug!("replace_names `{}` {:?}", result, substs); diff --git a/tests/source/macro_rules.rs b/tests/source/macro_rules.rs index dba1d78f0dd..ea3cefa8738 100644 --- a/tests/source/macro_rules.rs +++ b/tests/source/macro_rules.rs @@ -112,3 +112,19 @@ macro foo($type_name: ident, $docs: expr) { #[derive(Debug, Clone, Copy)] pub struct $type_name; } + +// #2538 +macro_rules! add_message_to_notes { + ($msg:expr) => {{ + let mut lines = message.lines(); + notes.push_str(&format!("\n{}: {}", level, lines.next().unwrap())); + for line in lines { + notes.push_str(&format!( + "\n{:indent$}{line}", + "", + indent = level.len() + 2, + line = line, + )); + } + }} +} diff --git a/tests/target/macro_rules.rs b/tests/target/macro_rules.rs index 2136784dec7..bc9c6aa4022 100644 --- a/tests/target/macro_rules.rs +++ b/tests/target/macro_rules.rs @@ -103,3 +103,19 @@ macro foo($type_name: ident, $docs: expr) { #[derive(Debug, Clone, Copy)] pub struct $type_name; } + +// #2538 +macro_rules! add_message_to_notes { + ($msg: expr) => {{ + let mut lines = message.lines(); + notes.push_str(&format!("\n{}: {}", level, lines.next().unwrap())); + for line in lines { + notes.push_str(&format!( + "\n{:indent$}{line}", + "", + indent = level.len() + 2, + line = line, + )); + } + }}; +} |
