about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <nrc@ncameron.org>2018-03-19 08:55:35 +1300
committerGitHub <noreply@github.com>2018-03-19 08:55:35 +1300
commit56d2a08db0784659178fe13fbc767d8258a085f1 (patch)
tree1c28bc6def1a20dcaeb6ffe5d13c98f802e59111
parentb7bc720638c60950007c5fe7693ffdc522cec294 (diff)
parent1a969cff7fe3dc5cef4f36e1786db5dc22b6ed6a (diff)
Merge pull request #2541 from topecongiro/issue-2358
Skip name replacement in comments and strings 
-rw-r--r--src/macros.rs63
-rw-r--r--tests/source/macro_rules.rs16
-rw-r--r--tests/target/macro_rules.rs16
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,
+            ));
+        }
+    }};
+}