Skip to content

Commit 5188d5e

Browse files
author
bors-servo
authored
Auto merge of #264 - servo:those-without-syn, r=nox
Fix using the `match_ignore_ascii_case` macro inside another macro expansion
2 parents 2c5c2ef + ff98a34 commit 5188d5e

17 files changed

+178
-197
lines changed

.travis.yml

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ script:
99
- cargo build --verbose
1010
- cargo test --verbose
1111
- cargo doc --verbose
12-
- cargo test --features heapsize
1312
- cargo test --features dummy_match_byte
1413
- if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then cargo test --features bench; fi
1514
- if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then cargo test --features "bench dummy_match_byte"; fi

Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "cssparser"
3-
version = "0.26.0"
3+
version = "0.27.0"
44
authors = [ "Simon Sapin <simon.sapin@exyr.org>" ]
55

66
description = "Rust implementation of CSS Syntax Level 3"
@@ -10,6 +10,7 @@ readme = "README.md"
1010
keywords = ["css", "syntax", "parser"]
1111
license = "MPL-2.0"
1212
build = "build.rs"
13+
edition = "2018"
1314

1415
exclude = ["src/css-parsing-tests/**", "src/big-data-url.css"]
1516

@@ -19,9 +20,8 @@ difference = "2.0"
1920
encoding_rs = "0.8"
2021

2122
[dependencies]
22-
cssparser-macros = {path = "./macros", version = "0.4"}
23+
cssparser-macros = {path = "./macros", version = "0.5"}
2324
dtoa-short = "0.3"
24-
heapsize = {version = ">= 0.3, < 0.5", optional = true}
2525
itoa = "0.4"
2626
matches = "0.1"
2727
phf = {version = "0.8", features = ["macros"]}

build.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
#[macro_use]
6-
extern crate quote;
7-
#[macro_use]
8-
extern crate syn;
9-
extern crate proc_macro2;
10-
115
#[cfg(feature = "dummy_match_byte")]
126
mod codegen {
137
pub fn main() {}
@@ -19,7 +13,6 @@ mod match_byte;
1913

2014
#[cfg(not(feature = "dummy_match_byte"))]
2115
mod codegen {
22-
use match_byte;
2316
use std::env;
2417
use std::path::Path;
2518
use std::thread::Builder;
@@ -35,7 +28,7 @@ mod codegen {
3528
let handle = Builder::new()
3629
.stack_size(128 * 1024 * 1024)
3730
.spawn(move || {
38-
match_byte::expand(&input, &output);
31+
crate::match_byte::expand(&input, &output);
3932
})
4033
.unwrap();
4134

build/match_byte.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
use quote::ToTokens;
5+
use quote::{quote, ToTokens};
66
use std::fs::File;
77
use std::io::{Read, Write};
88
use std::path::Path;
99
use syn;
1010
use syn::fold::Fold;
1111
use syn::parse::{Parse, ParseStream, Result};
12+
use syn::{parse_quote, Token};
1213

1314
use proc_macro2::{Span, TokenStream};
1415

@@ -73,7 +74,12 @@ fn get_byte_from_expr_lit(expr: &Box<syn::Expr>) -> u8 {
7374
}
7475

7576
/// Parse a pattern and fill the table accordingly
76-
fn parse_pat_to_table<'a>(pat: &'a syn::Pat, case_id: u8, wildcard: &mut Option<&'a syn::Ident>, table: &mut [u8; 256]) {
77+
fn parse_pat_to_table<'a>(
78+
pat: &'a syn::Pat,
79+
case_id: u8,
80+
wildcard: &mut Option<&'a syn::Ident>,
81+
table: &mut [u8; 256],
82+
) {
7783
match pat {
7884
&syn::Pat::Lit(syn::PatLit { ref expr, .. }) => {
7985
let value = get_byte_from_expr_lit(expr);
@@ -108,7 +114,7 @@ fn parse_pat_to_table<'a>(pat: &'a syn::Pat, case_id: u8, wildcard: &mut Option<
108114
*byte = case_id;
109115
}
110116
}
111-
},
117+
}
112118
&syn::Pat::Or(syn::PatOr { ref cases, .. }) => {
113119
for case in cases {
114120
parse_pat_to_table(case, case_id, wildcard, table);

macros/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "cssparser-macros"
3-
version = "0.4.0"
3+
version = "0.5.0"
44
authors = ["Simon Sapin <simon.sapin@exyr.org>"]
55
description = "Procedural macros for cssparser"
66
documentation = "https://docs.rs/cssparser-macros/"

macros/lib.rs

+39-72
Original file line numberDiff line numberDiff line change
@@ -6,103 +6,72 @@ extern crate proc_macro;
66

77
use proc_macro::TokenStream;
88

9-
/// Input: a `match` expression.
10-
///
11-
/// Output: a `MAX_LENGTH` constant with the length of the longest string pattern.
12-
///
13-
/// Panic if the arms contain non-string patterns,
14-
/// or string patterns that contains ASCII uppercase letters.
9+
/// Implementation detail of the `match_ignore_ascii_case!` macro
1510
#[allow(non_snake_case)]
1611
#[proc_macro]
17-
pub fn cssparser_internal__assert_ascii_lowercase__max_len(input: TokenStream) -> TokenStream {
18-
let expr: syn::ExprMatch = syn::parse_macro_input!(input);
19-
let strings = expr
20-
.arms
21-
.iter()
22-
.flat_map(|arm| match arm.pat {
23-
syn::Pat::Or(ref p) => p.cases.iter().collect(),
24-
ref p => vec![p],
25-
})
26-
.filter_map(|pattern| {
27-
let expr = match pattern {
28-
syn::Pat::Lit(expr) => expr,
29-
syn::Pat::Wild(_) => return None,
30-
_ => panic!("expected string or wildcard pattern, got {:?}", pattern),
31-
};
32-
match *expr.expr {
33-
syn::Expr::Lit(syn::ExprLit {
34-
lit: syn::Lit::Str(ref lit),
35-
..
36-
}) => {
37-
assert_eq!(
38-
lit.value(),
39-
lit.value().to_ascii_lowercase(),
40-
"string patterns must be given in ASCII lowercase"
41-
);
42-
Some(lit)
43-
}
44-
_ => panic!("expected string pattern, got {:?}", expr),
45-
}
46-
});
47-
max_len(strings)
48-
}
49-
50-
/// Input: string literals with no separator
51-
///
52-
/// Output: a `MAX_LENGTH` constant with the length of the longest string.
53-
#[allow(non_snake_case)]
54-
#[proc_macro]
55-
pub fn cssparser_internal__max_len(input: TokenStream) -> TokenStream {
56-
struct Input(Vec<syn::LitStr>);
12+
pub fn cssparser_internal__match_ignore_ascii_case__support(input: TokenStream) -> TokenStream {
13+
struct Input {
14+
max_length: usize,
15+
}
5716

5817
impl syn::parse::Parse for Input {
5918
fn parse(input: syn::parse::ParseStream) -> syn::parse::Result<Self> {
60-
let mut strings = Vec::new();
19+
let mut max_length = 0;
6120
while !input.is_empty() {
62-
strings.push(input.parse()?)
21+
if input.peek(syn::Token![_]) {
22+
input.parse::<syn::Token![_]>().unwrap();
23+
continue;
24+
}
25+
let lit: syn::LitStr = input.parse()?;
26+
let value = lit.value();
27+
if value.to_ascii_lowercase() != value {
28+
return Err(syn::Error::new(lit.span(), "must be ASCII-lowercase"));
29+
}
30+
max_length = max_length.max(value.len());
6331
}
64-
Ok(Self(strings))
32+
Ok(Input { max_length })
6533
}
6634
}
6735

68-
let strings: Input = syn::parse_macro_input!(input);
69-
max_len(strings.0.iter())
70-
}
71-
72-
fn max_len<'a, I: Iterator<Item = &'a syn::LitStr>>(strings: I) -> TokenStream {
73-
let max_length = strings
74-
.map(|s| s.value().len())
75-
.max()
76-
.expect("expected at least one string");
77-
quote::quote!( pub(super) const MAX_LENGTH: usize = #max_length; ).into()
36+
let Input { max_length } = syn::parse_macro_input!(input);
37+
quote::quote!(
38+
pub(super) const MAX_LENGTH: usize = #max_length;
39+
)
40+
.into()
7841
}
7942

80-
/// Input: A type, followed by pairs of string literal keys and expression values. No separator.
81-
///
82-
/// Output: a rust-phf map, with keys ASCII-lowercased:
83-
/// ```text
84-
/// static MAP: &'static ::cssparser::phf::Map<&'static str, $ValueType> = …;
85-
/// ```
43+
/// Implementation detail of the `ascii_case_insensitive_phf_map!` macro
8644
#[allow(non_snake_case)]
8745
#[proc_macro]
88-
pub fn cssparser_internal__phf_map(input: TokenStream) -> TokenStream {
46+
pub fn cssparser_internal__ascii_case_insensitive_phf_map__support(
47+
input: TokenStream,
48+
) -> TokenStream {
8949
struct Input {
9050
value_type: syn::Type,
51+
max_key_length: usize,
9152
keys: Vec<syn::LitStr>,
9253
values: Vec<syn::Expr>,
9354
}
9455

9556
impl syn::parse::Parse for Input {
9657
fn parse(input: syn::parse::ParseStream) -> syn::parse::Result<Self> {
58+
let value_type = input.parse()?;
59+
let mut max_key_length = 0;
9760
let mut keys = Vec::new();
9861
let mut values = Vec::new();
99-
let value_type = input.parse()?;
10062
while !input.is_empty() {
101-
keys.push(input.parse()?);
63+
let key: syn::LitStr = input.parse()?;
64+
let key_value = key.value();
65+
max_key_length = max_key_length.max(key_value.len());
66+
keys.push(syn::LitStr::new(
67+
&key_value.to_ascii_lowercase(),
68+
key.span(),
69+
));
10270
values.push(input.parse()?);
10371
}
10472
Ok(Input {
10573
value_type,
74+
max_key_length,
10675
keys,
10776
values,
10877
})
@@ -111,14 +80,12 @@ pub fn cssparser_internal__phf_map(input: TokenStream) -> TokenStream {
11180

11281
let Input {
11382
value_type,
83+
max_key_length,
11484
keys,
11585
values,
11686
} = syn::parse_macro_input!(input);
117-
let keys = keys
118-
.iter()
119-
.map(|s| syn::LitStr::new(&s.value().to_ascii_lowercase(), s.span()));
120-
12187
quote::quote!(
88+
pub(super) const MAX_LENGTH: usize = #max_key_length;
12289
pub(super) static MAP: Map<&'static str, #value_type> = phf_map! {
12390
#(
12491
#keys => #values,

src/color.rs

-6
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,6 @@ impl<'de> Deserialize<'de> for RGBA {
101101
}
102102
}
103103

104-
#[cfg(feature = "heapsize")]
105-
known_heap_size!(0, RGBA);
106-
107104
impl ToCss for RGBA {
108105
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
109106
where
@@ -141,9 +138,6 @@ pub enum Color {
141138
RGBA(RGBA),
142139
}
143140

144-
#[cfg(feature = "heapsize")]
145-
known_heap_size!(0, Color);
146-
147141
impl ToCss for Color {
148142
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
149143
where

src/lib.rs

+18-47
Original file line numberDiff line numberDiff line change
@@ -67,56 +67,27 @@ fn parse_border_spacing(_context: &ParserContext, input: &mut Parser)
6767

6868
#![recursion_limit = "200"] // For color::parse_color_keyword
6969

70-
extern crate dtoa_short;
71-
extern crate itoa;
72-
#[macro_use]
73-
extern crate cssparser_macros;
74-
#[macro_use]
75-
extern crate matches;
76-
#[cfg(test)]
77-
extern crate difference;
78-
#[cfg(test)]
79-
extern crate encoding_rs;
80-
#[doc(hidden)]
81-
pub extern crate phf as _internal__phf;
82-
#[cfg(feature = "serde")]
83-
extern crate serde;
84-
#[cfg(test)]
85-
extern crate serde_json;
86-
#[cfg(feature = "heapsize")]
87-
#[macro_use]
88-
extern crate heapsize;
89-
extern crate smallvec;
90-
91-
pub use cssparser_macros::*;
92-
93-
pub use color::{
70+
pub use crate::color::{
9471
parse_color_keyword, AngleOrNumber, Color, ColorComponentParser, NumberOrPercentage, RGBA,
9572
};
96-
pub use cow_rc_str::CowRcStr;
97-
pub use from_bytes::{stylesheet_encoding, EncodingSupport};
98-
pub use nth::parse_nth;
99-
pub use parser::{BasicParseError, BasicParseErrorKind, ParseError, ParseErrorKind};
100-
pub use parser::{Delimiter, Delimiters, Parser, ParserInput, ParserState};
101-
pub use rules_and_declarations::parse_important;
102-
pub use rules_and_declarations::{parse_one_declaration, DeclarationListParser, DeclarationParser};
103-
pub use rules_and_declarations::{parse_one_rule, RuleListParser};
104-
pub use rules_and_declarations::{AtRuleParser, AtRuleType, QualifiedRuleParser};
105-
pub use serializer::{
106-
serialize_identifier, serialize_name, serialize_string, CssStringWriter, ToCss,
107-
TokenSerializationType,
108-
};
109-
pub use tokenizer::{SourceLocation, SourcePosition, Token};
110-
pub use unicode_range::UnicodeRange;
111-
112-
// For macros
73+
pub use crate::cow_rc_str::CowRcStr;
74+
pub use crate::from_bytes::{stylesheet_encoding, EncodingSupport};
11375
#[doc(hidden)]
114-
pub use macros::_internal__to_lowercase;
115-
116-
// For macros when used in this crate. Unsure how $crate works with procedural-masquerade.
117-
mod cssparser {
118-
pub use _internal__phf;
119-
}
76+
pub use crate::macros::_internal__to_lowercase;
77+
pub use crate::nth::parse_nth;
78+
pub use crate::parser::{BasicParseError, BasicParseErrorKind, ParseError, ParseErrorKind};
79+
pub use crate::parser::{Delimiter, Delimiters, Parser, ParserInput, ParserState};
80+
pub use crate::rules_and_declarations::{parse_important, parse_one_declaration};
81+
pub use crate::rules_and_declarations::{parse_one_rule, RuleListParser};
82+
pub use crate::rules_and_declarations::{AtRuleParser, AtRuleType, QualifiedRuleParser};
83+
pub use crate::rules_and_declarations::{DeclarationListParser, DeclarationParser};
84+
pub use crate::serializer::{serialize_identifier, serialize_name, serialize_string};
85+
pub use crate::serializer::{CssStringWriter, ToCss, TokenSerializationType};
86+
pub use crate::tokenizer::{SourceLocation, SourcePosition, Token};
87+
pub use crate::unicode_range::UnicodeRange;
88+
pub use cssparser_macros::*;
89+
#[doc(hidden)]
90+
pub use phf as _internal__phf;
12091

12192
#[macro_use]
12293
mod macros;

0 commit comments

Comments
 (0)