Better spirv-attrib (#346)

* Feedback

* cleanup

* Cleanup

* cleanup

* Feedback

* fmt cmon man, I need to format my code manually? pffff

* More feedback! fmt is no longer useless as well

* removed newline

* more if guards

* removed import

* MORE feedback

* fromiterator is gone!

* Removed debug line
This commit is contained in:
Viktor Zoutman 2020-12-15 15:13:30 +01:00 committed by GitHub
parent aed5204f4a
commit 46c16d1d0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,16 +1,31 @@
#![cfg_attr(target_arch = "spirv", feature(register_attr), register_attr(spirv))]
use proc_macro::{Delimiter, Group, TokenStream, TokenTree};
use proc_macro::TokenStream;
use std::str::FromStr;
#[cfg(not(target_arch = "spirv"))]
#[proc_macro_attribute]
pub fn spirv(_attr: TokenStream, item: TokenStream) -> TokenStream {
let mut item_str = item.to_string();
while let Some(start) = item_str.find("#[spirv(") {
let end = item_str[start..item_str.len()].find(")]");
item_str.replace_range(start..start + end.unwrap() + 2, "");
let mut tokens = Vec::new();
for tt in item {
match tt {
TokenTree::Group(group) if group.delimiter() == Delimiter::Parenthesis => {
let mut sub_tokens = Vec::new();
for tt in group.stream() {
match tt {
TokenTree::Group(group)
if group.delimiter() == Delimiter::Bracket
&& matches!(group.stream().into_iter().next(), Some(TokenTree::Ident(ident)) if ident.to_string() == "spirv")
&& matches!(sub_tokens.last(), Some(TokenTree::Punct(p)) if p.as_char() == '#') =>
{
sub_tokens.pop();
}
_ => sub_tokens.push(tt),
}
}
tokens.push(TokenTree::from(Group::new(
Delimiter::Parenthesis,
sub_tokens.into_iter().collect(),
)));
}
_ => tokens.push(tt),
}
}
TokenStream::from_str(item_str.as_str()).unwrap()
tokens.into_iter().collect()
}