about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume.gomez@huawei.com>2022-09-15 13:53:20 +0200
committerGuillaume Gomez <guillaume.gomez@huawei.com>2022-09-15 13:53:20 +0200
commitd3529ceb6c5eeaaecd3d88e97ad17740258772a8 (patch)
tree12b8d1f34d5cb8f59267626f2653cfa1ed4073d6
parenta528f68e79f464f47fd41dd503bbb14e8f34a8ea (diff)
downloadrust-d3529ceb6c5eeaaecd3d88e97ad17740258772a8.tar.gz
rust-d3529ceb6c5eeaaecd3d88e97ad17740258772a8.zip
Correctly handle parens
-rw-r--r--src/librustdoc/theme.rs28
-rw-r--r--src/librustdoc/theme/tests.rs18
2 files changed, 38 insertions, 8 deletions
diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs
index ce0cb6c4559..e7a26cb346e 100644
--- a/src/librustdoc/theme.rs
+++ b/src/librustdoc/theme.rs
@@ -17,19 +17,31 @@ pub(crate) struct CssPath {
 }
 
 /// When encountering a `"` or a `'`, returns the whole string, including the quote characters.
-fn get_string(iter: &mut Peekable<Chars<'_>>, string_start: char) -> String {
-    let mut s = String::with_capacity(2);
-
-    s.push(string_start);
+fn get_string(iter: &mut Peekable<Chars<'_>>, string_start: char, buffer: &mut String) {
+    buffer.push(string_start);
     while let Some(c) = iter.next() {
-        s.push(c);
+        buffer.push(c);
         if c == '\\' {
             iter.next();
         } else if c == string_start {
             break;
         }
     }
-    s
+}
+
+fn get_inside_paren(
+    iter: &mut Peekable<Chars<'_>>,
+    paren_start: char,
+    paren_end: char,
+    buffer: &mut String,
+) {
+    buffer.push(paren_start);
+    while let Some(c) = iter.next() {
+        handle_common_chars(c, buffer, iter);
+        if c == paren_end {
+            break;
+        }
+    }
 }
 
 /// Skips a `/*` comment.
@@ -52,9 +64,11 @@ fn skip_line_comment(iter: &mut Peekable<Chars<'_>>) {
 
 fn handle_common_chars(c: char, buffer: &mut String, iter: &mut Peekable<Chars<'_>>) {
     match c {
-        '"' | '\'' => buffer.push_str(&get_string(iter, c)),
+        '"' | '\'' => get_string(iter, c, buffer),
         '/' if iter.peek() == Some(&'*') => skip_comment(iter),
         '/' if iter.peek() == Some(&'/') => skip_line_comment(iter),
+        '(' => get_inside_paren(iter, c, ')', buffer),
+        '[' => get_inside_paren(iter, c, ']', buffer),
         _ => buffer.push(c),
     }
 }
diff --git a/src/librustdoc/theme/tests.rs b/src/librustdoc/theme/tests.rs
index ce1d77d98d7..08a174d27d3 100644
--- a/src/librustdoc/theme/tests.rs
+++ b/src/librustdoc/theme/tests.rs
@@ -138,7 +138,6 @@ fn test_media() {
     assert!(p.children.get("a:hover").is_some());
     assert!(p.children.get("b").is_some());
 
-    eprintln!("{:?}", paths);
     let p = paths.get("@media (max-width:1001px)");
     assert!(p.is_some());
     let p = p.unwrap();
@@ -169,3 +168,20 @@ fn test_css_variables() {
     get_differences(&other, &against, &mut ret);
     assert_eq!(ret, vec!["  Missing CSS variable `--b` in `:root`".to_owned()]);
 }
+
+#[test]
+fn test_weird_rule_value() {
+    let x = r#"
+a[text=("a")] {
+    b: url({;}.png);
+    c: #fff
+}
+"#;
+
+    let paths = load_css_paths(&x).unwrap();
+    let p = paths.get("a[text=(\"a\")]");
+    assert!(p.is_some());
+    let p = p.unwrap();
+    assert_eq!(p.rules.get("b"), Some(&"url({;}.png)".to_owned()));
+    assert_eq!(p.rules.get("c"), Some(&"#fff".to_owned()));
+}