Update syn to 0.15

New and faster parsers!
This commit is contained in:
Alex Crichton 2018-09-04 11:32:09 -07:00
parent e67397ec27
commit 8f9514d216
10 changed files with 123 additions and 129 deletions

View File

@ -20,5 +20,5 @@ log = "0.4"
proc-macro2 = "0.4.8"
quote = '0.6'
serde_json = "1.0"
syn = { version = '0.14', features = ['full', 'visit'] }
syn = { version = '0.15', features = ['full', 'visit'] }
wasm-bindgen-shared = { path = "../shared", version = "=0.2.20" }

View File

@ -233,6 +233,7 @@ impl ImportedTypes for syn::GenericArgument {
syn::GenericArgument::Type(ty) => ty.imported_types(f),
syn::GenericArgument::Binding(_) => {}, // TODO
syn::GenericArgument::Const(_) => {}, // TODO
syn::GenericArgument::Constraint(_) => {}, // TODO
}
}
}

View File

@ -1,5 +1,6 @@
use proc_macro2::*;
use quote::{ToTokens, TokenStreamExt};
use syn::parse::Error;
#[macro_export]
macro_rules! err_span {
@ -26,6 +27,7 @@ enum Repr {
text: String,
span: Option<(Span, Span)>,
},
SynError(Error),
Multi {
diagnostics: Vec<Diagnostic>,
}
@ -62,11 +64,20 @@ impl Diagnostic {
pub fn panic(&self) -> ! {
match &self.inner {
Repr::Single { text, .. } => panic!("{}", text),
Repr::SynError(error) => panic!("{}", error),
Repr::Multi { diagnostics } => diagnostics[0].panic(),
}
}
}
impl From<Error> for Diagnostic {
fn from(err: Error) -> Diagnostic {
Diagnostic {
inner: Repr::SynError(err),
}
}
}
fn extract_spans(node: &ToTokens) -> Option<(Span, Span)> {
let mut t = TokenStream::new();
node.to_tokens(&mut t);
@ -95,6 +106,9 @@ impl ToTokens for Diagnostic {
diagnostic.to_tokens(dst);
}
}
Repr::SynError(err) => {
err.to_compile_error().to_tokens(dst);
}
}
}
}

View File

@ -15,7 +15,7 @@ spans = ["wasm-bindgen-backend/spans"]
extra-traits = ["syn/extra-traits"]
[dependencies]
syn = { version = '0.14', features = ['full'] }
syn = { version = '0.15.0', features = ['full'] }
quote = '0.6'
proc-macro2 = "0.4.9"
wasm-bindgen-backend = { path = "../backend", version = "=0.2.20" }

View File

@ -20,8 +20,8 @@ mod parser;
/// Takes the parsed input from a `#[wasm_bindgen]` macro and returns the generated bindings
pub fn expand(attr: TokenStream, input: TokenStream) -> Result<TokenStream, Diagnostic> {
let item = syn_parse::<syn::Item>(input, "rust item")?;
let opts = syn_parse(attr, "#[wasm_bindgen] attribute options")?;
let item = syn::parse2::<syn::Item>(input)?;
let opts = syn::parse2(attr)?;
let mut tokens = proc_macro2::TokenStream::new();
let mut program = backend::ast::Program::default();
@ -29,10 +29,3 @@ pub fn expand(attr: TokenStream, input: TokenStream) -> Result<TokenStream, Diag
program.try_to_tokens(&mut tokens)?;
Ok(tokens)
}
fn syn_parse<T: syn::synom::Synom>(tokens: TokenStream, name: &str) -> Result<T, Diagnostic> {
syn::parse2(tokens.clone())
.map_err(|err| {
Diagnostic::span_error(&tokens, format!("error parsing {}: {}", name, err))
})
}

View File

@ -5,6 +5,7 @@ use proc_macro2::{Delimiter, Ident, Span, TokenStream, TokenTree};
use quote::ToTokens;
use shared;
use syn;
use syn::parse::{Parse, ParseStream, Result as SynResult};
/// Parsed attributes from a `#[wasm_bindgen(..)]`.
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
@ -39,7 +40,7 @@ impl BindgenAttrs {
if group.delimiter() != Delimiter::Parenthesis {
bail_span!(attr, "malformed #[wasm_bindgen] attribute");
}
super::syn_parse(group.stream(), "#[wasm_bindgen] attribute options")
Ok(syn::parse2(group.stream())?)
}
/// Get the first module attribute
@ -193,19 +194,15 @@ impl BindgenAttrs {
}
}
impl syn::synom::Synom for BindgenAttrs {
named!(parse -> Self, alt!(
do_parse!(
opts: call!(
syn::punctuated::Punctuated::<_, syn::token::Comma>::parse_terminated
) >>
(BindgenAttrs {
attrs: opts.into_iter().collect(),
})
) => { |s| s }
|
epsilon!() => { |_| BindgenAttrs { attrs: Vec::new() } }
));
impl Parse for BindgenAttrs {
fn parse(input: ParseStream) -> SynResult<Self> {
if input.is_empty() {
return Ok(BindgenAttrs { attrs: Vec::new() })
}
let opts = syn::punctuated::Punctuated::<_, syn::token::Comma>::parse_terminated(input)?;
Ok(BindgenAttrs { attrs: opts.into_iter().collect() })
}
}
/// The possible attributes in the `#[wasm_bindgen]`.
@ -230,109 +227,94 @@ pub enum BindgenAttr {
Variadic,
}
impl syn::synom::Synom for BindgenAttr {
named!(parse -> Self, alt!(
call!(term, "catch") => { |_| BindgenAttr::Catch }
|
call!(term, "constructor") => { |_| BindgenAttr::Constructor }
|
call!(term, "method") => { |_| BindgenAttr::Method }
|
do_parse!(
call!(term, "static_method_of") >>
punct!(=) >>
cls: call!(term2ident) >>
(cls)
)=> { BindgenAttr::StaticMethodOf }
|
do_parse!(
call!(term, "getter") >>
val: option!(do_parse!(
punct!(=) >>
s: call!(term2ident) >>
(s)
)) >>
(val)
)=> { BindgenAttr::Getter }
|
do_parse!(
call!(term, "setter") >>
val: option!(do_parse!(
punct!(=) >>
s: call!(term2ident) >>
(s)
)) >>
(val)
)=> { BindgenAttr::Setter }
|
call!(term, "indexing_getter") => { |_| BindgenAttr::IndexingGetter }
|
call!(term, "indexing_setter") => { |_| BindgenAttr::IndexingSetter }
|
call!(term, "indexing_deleter") => { |_| BindgenAttr::IndexingDeleter }
|
call!(term, "structural") => { |_| BindgenAttr::Structural }
|
call!(term, "readonly") => { |_| BindgenAttr::Readonly }
|
do_parse!(
call!(term, "js_namespace") >>
punct!(=) >>
ns: call!(term2ident) >>
(ns)
)=> { BindgenAttr::JsNamespace }
|
do_parse!(
call!(term, "module") >>
punct!(=) >>
s: syn!(syn::LitStr) >>
(s.value())
)=> { BindgenAttr::Module }
|
do_parse!(
call!(term, "js_name") >>
punct!(=) >>
name: alt!(
syn!(syn::LitStr) => { |s| s.value() }
|
call!(term2ident) => { |s| s.to_string() }
) >>
(name)
)=> { BindgenAttr::JsName }
|
do_parse!(
call!(term, "js_class") >>
punct!(=) >>
s: syn!(syn::LitStr) >>
(s.value())
)=> { BindgenAttr::JsClass }
|
do_parse!(
call!(term, "extends") >>
punct!(=) >>
ns: call!(term2ident) >>
(ns)
)=> { BindgenAttr::Extends }
|
call!(term, "variadic") => { |_| BindgenAttr::Variadic }
));
}
/// Consumes a `Ident` with the given name
fn term<'a>(cursor: syn::buffer::Cursor<'a>, name: &str) -> syn::synom::PResult<'a, ()> {
if let Some((ident, next)) = cursor.ident() {
if ident == name {
return Ok(((), next));
impl Parse for BindgenAttr {
fn parse(input: ParseStream) -> SynResult<Self> {
let original = input.fork();
let attr: Ident = input.parse()?;
if attr == "catch" {
return Ok(BindgenAttr::Catch)
}
if attr == "constructor" {
return Ok(BindgenAttr::Constructor)
}
if attr == "method" {
return Ok(BindgenAttr::Method)
}
if attr == "indexing_getter" {
return Ok(BindgenAttr::IndexingGetter)
}
if attr == "indexing_setter" {
return Ok(BindgenAttr::IndexingSetter)
}
if attr == "indexing_deleter" {
return Ok(BindgenAttr::IndexingDeleter)
}
if attr == "structural" {
return Ok(BindgenAttr::Structural)
}
if attr == "readonly" {
return Ok(BindgenAttr::Readonly)
}
if attr == "variadic" {
return Ok(BindgenAttr::Variadic)
}
if attr == "static_method_of" {
input.parse::<Token![=]>()?;
return Ok(BindgenAttr::StaticMethodOf(input.parse::<AnyIdent>()?.0))
}
if attr == "getter" {
if input.parse::<Token![=]>().is_ok() {
return Ok(BindgenAttr::Getter(Some(input.parse::<AnyIdent>()?.0)))
} else {
return Ok(BindgenAttr::Getter(None))
}
}
if attr == "setter" {
if input.parse::<Token![=]>().is_ok() {
return Ok(BindgenAttr::Setter(Some(input.parse::<AnyIdent>()?.0)))
} else {
return Ok(BindgenAttr::Setter(None))
}
}
if attr == "js_namespace" {
input.parse::<Token![=]>()?;
return Ok(BindgenAttr::JsNamespace(input.parse::<AnyIdent>()?.0))
}
if attr == "extends" {
input.parse::<Token![=]>()?;
return Ok(BindgenAttr::Extends(input.parse::<AnyIdent>()?.0))
}
if attr == "module" {
input.parse::<Token![=]>()?;
return Ok(BindgenAttr::Module(input.parse::<syn::LitStr>()?.value()))
}
if attr == "js_class" {
input.parse::<Token![=]>()?;
return Ok(BindgenAttr::JsClass(input.parse::<syn::LitStr>()?.value()))
}
if attr == "js_name" {
input.parse::<Token![=]>()?;
let val = match input.parse::<syn::LitStr>() {
Ok(str) => str.value(),
Err(_) => input.parse::<AnyIdent>()?.0.to_string(),
};
return Ok(BindgenAttr::JsName(val))
}
Err(original.error("unknown attribute"))
}
syn::parse_error()
}
/// Consumes a `Ident` and returns it.
fn term2ident<'a>(cursor: syn::buffer::Cursor<'a>) -> syn::synom::PResult<'a, Ident> {
match cursor.ident() {
Some(pair) => Ok(pair),
None => syn::parse_error(),
struct AnyIdent(Ident);
impl Parse for AnyIdent {
fn parse(input: ParseStream) -> SynResult<Self> {
input.step(|cursor| {
match cursor.ident() {
Some((ident, remaining)) => Ok((AnyIdent(ident), remaining)),
None => Err(cursor.error("expected an identifier")),
}
})
}
}
@ -841,6 +823,10 @@ impl<'a, 'b> MacroParse<()> for (&'a Ident, &'b mut syn::ImplItem) {
&*item,
"type definitions in impls aren't supported with #[wasm_bindgen]"
),
syn::ImplItem::Existential(_) => bail_span!(
&*item,
"existentials in impls aren't supported with #[wasm_bindgen]"
),
syn::ImplItem::Macro(_) => {
bail_span!(&*item, "macros in impls aren't supported");
}

View File

@ -1,4 +1,4 @@
error: error parsing #[wasm_bindgen] attribute options: failed to parse anything
error: unknown attribute
--> $DIR/attribute-fails-to-parse.rs:5:16
|
5 | #[wasm_bindgen(nonsense)]

View File

@ -1,10 +1,10 @@
error: error parsing #[wasm_bindgen] attribute options: failed to parse anything
error: unknown attribute
--> $DIR/invalid-attr.rs:5:16
|
5 | #[wasm_bindgen(x)]
| ^
error: error parsing #[wasm_bindgen] attribute options: failed to parse anything
error: unknown attribute
--> $DIR/invalid-attr.rs:10:20
|
10 | #[wasm_bindgen(y)]

View File

@ -10,6 +10,6 @@ serde_json = "1.0"
proc-macro2 = "0.4.8"
quote = "0.6"
syn = { version = "0.14", default-features = false }
syn = { version = "0.15", default-features = false }
wasm-bindgen = { path = "../..", default-features = false }
wasm-bindgen-backend = { path = "../backend", default-features = false }

View File

@ -18,6 +18,6 @@ heck = "0.3"
log = "0.4.1"
proc-macro2 = "0.4.8"
quote = '0.6'
syn = { version = '0.14', features = ['full'] }
syn = { version = '0.15', features = ['full'] }
wasm-bindgen-backend = { version = "=0.2.20", path = "../backend" }
weedle = "0.7"