Skip to content
This repository has been archived by the owner on Dec 27, 2022. It is now read-only.

Commit

Permalink
Remove assumptions about whitespace between tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Mar 19, 2021
1 parent f16b7d1 commit 4df5a94
Showing 1 changed file with 76 additions and 34 deletions.
110 changes: 76 additions & 34 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,25 +282,46 @@ macro_rules! proc_macro_expr_impl {
#[proc_macro_derive($func)]
pub fn $func(input: $func::TokenStream) -> $func::TokenStream {
let source = input.to_string();
let source = source.trim();
let mut tokens = source.trim();

let prefix = "#[allow(unused)]\nenum ProcMacroHack {";
let suffix = "}";
assert!(source.starts_with(prefix));
assert!(source.ends_with(suffix));
let source = &source[prefix.len() .. source.len() - suffix.len()].trim();
for &prefix in &[
"#",
"[",
"allow",
"(",
"unused",
")",
"]",
"enum",
"ProcMacroHack",
"{",
"Input",
"=",
"(",
"stringify",
"!",
"(",
] {
assert!(tokens.starts_with(prefix));
tokens = &tokens[prefix.len()..].trim();
}

let prefix = "Input =";
let suffix = "0).1,";
assert!(source.starts_with(prefix));
assert!(source.ends_with(suffix));
let source = &source[prefix.len() .. source.len() - suffix.len()].trim();

let prefix = "(stringify!(";
let suffix = "),";
assert!(source.starts_with(prefix));
assert!(source.ends_with(suffix));
let tokens = &source[prefix.len() .. source.len() - suffix.len()].trim();
for &suffix in &[
"}",
",",
"1",
".",
")",
"0",
",",
")",
] {
if suffix == "," && !tokens.ends_with(suffix) {
continue;
}
assert!(tokens.ends_with(suffix));
tokens = &tokens[..tokens.len() - suffix.len()].trim();
}

fn func($input: &str) -> String $body

Expand Down Expand Up @@ -350,25 +371,46 @@ macro_rules! proc_macro_item_impl {
#[proc_macro_derive($func)]
pub fn $func(input: $func::TokenStream) -> $func::TokenStream {
let source = input.to_string();
let source = source.trim();

let prefix = "#[allow(unused)]\nenum ProcMacroHack {";
let suffix = "}";
assert!(source.starts_with(prefix));
assert!(source.ends_with(suffix));
let source = &source[prefix.len() .. source.len() - suffix.len()].trim();
let mut tokens = source.trim();

let prefix = "Input =";
let suffix = "0).1,";
assert!(source.starts_with(prefix));
assert!(source.ends_with(suffix));
let source = &source[prefix.len() .. source.len() - suffix.len()].trim();
for &prefix in &[
"#",
"[",
"allow",
"(",
"unused",
")",
"]",
"enum",
"ProcMacroHack",
"{",
"Input",
"=",
"(",
"stringify",
"!",
"(",
] {
assert!(tokens.starts_with(prefix));
tokens = &tokens[prefix.len()..].trim();
}

let prefix = "(stringify!(";
let suffix = "),";
assert!(source.starts_with(prefix));
assert!(source.ends_with(suffix));
let tokens = &source[prefix.len() .. source.len() - suffix.len()].trim();
for &suffix in &[
"}",
",",
"1",
".",
")",
"0",
",",
")",
] {
if suffix == "," && !tokens.ends_with(suffix) {
continue;
}
assert!(tokens.ends_with(suffix));
tokens = &tokens[..tokens.len() - suffix.len()].trim();
}

fn func($input: &str) -> String $body

Expand Down

0 comments on commit 4df5a94

Please sign in to comment.