Skip to content

Rewrite procedural macro based on the enum discriminant trick #123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Feb 28, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Clean up macros’ doc-comments.
  • Loading branch information
SimonSapin committed Feb 27, 2017
commit b1b6ed9a80e305074668bbd2565af4da23a6584c
21 changes: 15 additions & 6 deletions macros/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ extern crate syn;
use std::ascii::AsciiExt;

define_proc_macros! {
/// Panic if any string contains ASCII uppercase letters.
/// Emit a `MAX_LENGTH` constant with the length of the longest string.
/// Input: the arms of a `match` expression.
///
/// Output: a `MAX_LENGTH` constant with the length of the longest string pattern.
///
/// Panic if the arms contain non-string patterns,
/// or string patterns that contains ASCII uppercase letters.
#[allow(non_snake_case)]
pub fn cssparser_internal__assert_ascii_lowercase__max_len(input: &str) -> String {
let expr = syn::parse_expr(&format!("match x {{ {} }}", input)).unwrap();
Expand Down Expand Up @@ -45,17 +49,22 @@ define_proc_macros! {
}))
}

/// Emit a `MAX_LENGTH` constant with the length of the longest string.
/// Input: string literals with no separator
///
/// Output: a `MAX_LENGTH` constant with the length of the longest string.
#[allow(non_snake_case)]
pub fn cssparser_internal__max_len(input: &str) -> String {
max_len(syn::parse_token_trees(input).unwrap().iter().map(|tt| string_literal(tt).len()))
}

/// Input: parsed as token trees. The first TT is a type. (Can be wrapped in parens.)
/// following TTs are grouped in pairs, each pair being a key as a string literal
/// and the corresponding value as a const expression.
///
/// Output: a rust-phf map, with keys ASCII-lowercased:
/// ```
/// static MAP: &'static ::phf::Map<&'static str, $ValueType> = …;
/// static MAP: &'static ::cssparser::phf::Map<&'static str, $ValueType> = …;
/// ```
///
/// Map keys are ASCII-lowercased.
#[allow(non_snake_case)]
pub fn cssparser_internal__phf_map(input: &str) -> String {
let token_trees = syn::parse_token_trees(input).unwrap();
Expand Down
21 changes: 11 additions & 10 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/// See docs of the `procedural-masquarade` crate.
define_invoke_proc_macro!(cssparser_internal__invoke_proc_macro);

/// Expands to an expression equivalent to a `match` with string patterns,
/// but matching is case-insensitive in the ASCII range.
/// Expands to a `match` expression with string patterns,
/// matching case-insensitively in the ASCII range.
///
/// The patterns must not contain ASCII upper case letters. (They must be already be lower-cased.)
///
Expand Down Expand Up @@ -63,7 +64,7 @@ macro_rules! match_ignore_ascii_case {
/// ```rust
/// #[macro_use] extern crate cssparser;
///
/// # fn main() {} // Make doctest not wrap everythig in its own main
/// # fn main() {} // Make doctest not wrap everything in its own main
///
/// fn color_rgb(input: &str) -> Option<(u8, u8, u8)> {
/// ascii_case_insensitive_phf_map! {
Expand Down Expand Up @@ -99,18 +100,18 @@ macro_rules! ascii_case_insensitive_phf_map {
///
/// **This macro is not part of the public API. It can change or be removed between any versions.**
///
/// * Check at compile-time that none of the `$string`s contain ASCII uppercase letters
/// * Define a local variable named `$output` to the result of calling `_internal__to_lowercase`
/// with a stack-allocated buffer as long as the longest `$string`.
/// Define a local variable named `$output`
/// and assign it the result of calling `_internal__to_lowercase`
/// with a stack-allocated buffer of length `$BUFFER_SIZE`.
#[macro_export]
#[doc(hidden)]
macro_rules! cssparser_internal__to_lowercase {
($input: expr, $MAX_LENGTH: expr => $output: ident) => {
($input: expr, $BUFFER_SIZE: expr => $output: ident) => {
// mem::uninitialized() is ok because `buffer` is only used in `_internal__to_lowercase`,
// which initializes with `copy_from_slice` the part of the buffer it uses,
// before it uses it.
#[allow(unsafe_code)]
let mut buffer: [u8; $MAX_LENGTH] = unsafe {
let mut buffer: [u8; $BUFFER_SIZE] = unsafe {
::std::mem::uninitialized()
};
let input: &str = $input;
Expand All @@ -122,8 +123,8 @@ macro_rules! cssparser_internal__to_lowercase {
///
/// **This function is not part of the public API. It can change or be removed between any verisons.**
///
/// Return `input`, lower-cased, unless larger than `buffer`
/// which is used temporary space for lower-casing a copy of `input` if necessary.
/// If `input` is larger than buffer, return `None`.
/// Otherwise, return `input` ASCII-lowercased, using `buffer` as temporary space if necessary.
#[doc(hidden)]
#[allow(non_snake_case)]
pub fn _internal__to_lowercase<'a>(buffer: &'a mut [u8], input: &'a str) -> Option<&'a str> {
Expand Down