Store passthrough attributes for diagnostic lint levels

This commit is contained in:
David Tolnay 2020-12-30 16:18:05 -08:00
parent 20d980be78
commit 067638ea15
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
5 changed files with 67 additions and 24 deletions

View File

@ -51,6 +51,7 @@ fn sort_by_inner_namespace(apis: Vec<&Api>, depth: usize) -> NamespaceEntries {
#[cfg(test)]
mod tests {
use super::NamespaceEntries;
use crate::syntax::attrs::OtherAttrs;
use crate::syntax::namespace::Namespace;
use crate::syntax::{Api, Doc, ExternType, Lang, Lifetimes, Pair};
use proc_macro2::{Ident, Span};
@ -131,6 +132,7 @@ mod tests {
lang: Lang::Rust,
doc: Doc::new(),
derives: Vec::new(),
attrs: OtherAttrs::none(),
type_token: Token![type](Span::call_site()),
name: Pair {
namespace: ns,

View File

@ -39,7 +39,8 @@ pub struct Parser<'a> {
pub(crate) _more: (),
}
pub(super) fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser) {
pub(super) fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser) -> Vec<Attribute> {
let mut passthrough_attrs = Vec::new();
for attr in attrs {
if attr.path.is_ident("doc") {
match parse_doc_attribute.parse2(attr.tokens.clone()) {
@ -49,7 +50,10 @@ pub(super) fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser)
continue;
}
}
Err(err) => return cx.push(err),
Err(err) => {
cx.push(err);
break;
}
}
} else if attr.path.is_ident("derive") {
match attr.parse_args_with(|attr: ParseStream| parse_derive_attribute(cx, attr)) {
@ -59,7 +63,10 @@ pub(super) fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser)
continue;
}
}
Err(err) => return cx.push(err),
Err(err) => {
cx.push(err);
break;
}
}
} else if attr.path.is_ident("repr") {
match attr.parse_args_with(parse_repr_attribute) {
@ -69,7 +76,10 @@ pub(super) fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser)
continue;
}
}
Err(err) => return cx.push(err),
Err(err) => {
cx.push(err);
break;
}
}
} else if attr.path.is_ident("namespace") {
match parse_namespace_attribute.parse2(attr.tokens.clone()) {
@ -79,7 +89,10 @@ pub(super) fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser)
continue;
}
}
Err(err) => return cx.push(err),
Err(err) => {
cx.push(err);
break;
}
}
} else if attr.path.is_ident("cxx_name") {
match parse_function_alias_attribute.parse2(attr.tokens.clone()) {
@ -89,7 +102,10 @@ pub(super) fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser)
continue;
}
}
Err(err) => return cx.push(err),
Err(err) => {
cx.push(err);
break;
}
}
} else if attr.path.is_ident("rust_name") {
match parse_function_alias_attribute.parse2(attr.tokens.clone()) {
@ -99,7 +115,10 @@ pub(super) fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser)
continue;
}
}
Err(err) => return cx.push(err),
Err(err) => {
cx.push(err);
break;
}
}
} else if attr.path.is_ident("allow")
|| attr.path.is_ident("warn")
@ -107,10 +126,13 @@ pub(super) fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser)
|| attr.path.is_ident("forbid")
{
// https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes
passthrough_attrs.push(attr);
continue;
}
return cx.error(attr, "unsupported attribute");
cx.error(attr, "unsupported attribute");
break;
}
passthrough_attrs
}
fn parse_doc_attribute(input: ParseStream) -> Result<LitStr> {

View File

@ -298,12 +298,14 @@ impl PartialEq for Var {
fn eq(&self, other: &Var) -> bool {
let Var {
doc: _,
attrs: _,
visibility: _,
ident,
ty,
} = self;
let Var {
doc: _,
attrs: _,
visibility: _,
ident: ident2,
ty: ty2,
@ -316,6 +318,7 @@ impl Hash for Var {
fn hash<H: Hasher>(&self, state: &mut H) {
let Var {
doc: _,
attrs: _,
visibility: _,
ident,
ty,

View File

@ -1,7 +1,7 @@
// Functionality that is shared between the cxxbridge macro and the cmd.
pub mod atom;
mod attrs;
pub mod attrs;
pub mod check;
pub mod derive;
mod discriminant;
@ -32,7 +32,7 @@ use self::symbol::Symbol;
use proc_macro2::{Ident, Span};
use syn::punctuated::Punctuated;
use syn::token::{Brace, Bracket, Paren};
use syn::{Expr, Generics, Lifetime, LitInt, Token, Type as RustType};
use syn::{Attribute, Expr, Generics, Lifetime, LitInt, Token, Type as RustType};
pub use self::atom::Atom;
pub use self::derive::{Derive, Trait};
@ -72,6 +72,7 @@ pub struct ExternType {
pub lang: Lang,
pub doc: Doc,
pub derives: Vec<Derive>,
pub attrs: Vec<Attribute>,
pub type_token: Token![type],
pub name: Pair,
pub generics: Lifetimes,
@ -84,6 +85,7 @@ pub struct ExternType {
pub struct Struct {
pub doc: Doc,
pub derives: Vec<Derive>,
pub attrs: Vec<Attribute>,
pub visibility: Token![pub],
pub struct_token: Token![struct],
pub name: Pair,
@ -94,6 +96,7 @@ pub struct Struct {
pub struct Enum {
pub doc: Doc,
pub derives: Vec<Derive>,
pub attrs: Vec<Attribute>,
pub enum_token: Token![enum],
pub name: Pair,
pub brace_token: Brace,
@ -106,6 +109,7 @@ pub struct Enum {
pub struct ExternFn {
pub lang: Lang,
pub doc: Doc,
pub attrs: Vec<Attribute>,
pub name: Pair,
pub sig: Signature,
pub semi_token: Token![;],
@ -115,6 +119,7 @@ pub struct ExternFn {
pub struct TypeAlias {
pub doc: Doc,
pub derives: Vec<Derive>,
pub attrs: Vec<Attribute>,
pub type_token: Token![type],
pub name: Pair,
pub generics: Lifetimes,
@ -151,6 +156,7 @@ pub struct Signature {
pub struct Var {
pub doc: Doc,
pub attrs: Vec<Attribute>,
pub visibility: Token![pub],
pub ident: Ident,
pub ty: Type,
@ -170,6 +176,7 @@ pub struct Receiver {
pub struct Variant {
pub doc: Doc,
pub attrs: Vec<Attribute>,
pub name: Pair,
pub discriminant: Discriminant,
pub expr: Option<Expr>,

View File

@ -57,15 +57,14 @@ pub fn parse_items(
}
fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) -> Result<Api> {
let attrs = mem::take(&mut item.attrs);
let mut doc = Doc::new();
let mut derives = Vec::new();
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
attrs::parse(
let attrs = attrs::parse(
cx,
attrs,
mem::take(&mut item.attrs),
attrs::Parser {
doc: Some(&mut doc),
derives: Some(&mut derives),
@ -100,7 +99,7 @@ fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) ->
for field in named_fields.named {
let ident = field.ident.unwrap();
let mut doc = Doc::new();
attrs::parse(
let attrs = attrs::parse(
cx,
field.attrs,
attrs::Parser {
@ -123,6 +122,7 @@ fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) ->
});
fields.push(Var {
doc,
attrs,
visibility,
ident,
ty,
@ -142,6 +142,7 @@ fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) ->
Ok(Api::Struct(Struct {
doc,
derives,
attrs,
visibility,
struct_token,
name,
@ -157,7 +158,7 @@ fn parse_enum(cx: &mut Errors, item: ItemEnum, namespace: &Namespace) -> Result<
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
attrs::parse(
let attrs = attrs::parse(
cx,
item.attrs,
attrs::Parser {
@ -213,6 +214,7 @@ fn parse_enum(cx: &mut Errors, item: ItemEnum, namespace: &Namespace) -> Result<
Ok(Api::Enum(Enum {
doc,
derives,
attrs,
enum_token,
name,
brace_token,
@ -228,13 +230,12 @@ fn parse_variant(
mut variant: RustVariant,
discriminants: &mut DiscriminantSet,
) -> Result<Variant> {
let attrs = mem::take(&mut variant.attrs);
let mut doc = Doc::new();
let mut cxx_name = None;
let mut rust_name = None;
attrs::parse(
let attrs = attrs::parse(
cx,
attrs,
mem::take(&mut variant.attrs),
attrs::Parser {
doc: Some(&mut doc),
cxx_name: Some(&mut cxx_name),
@ -266,6 +267,7 @@ fn parse_variant(
Ok(Variant {
doc,
attrs,
name,
discriminant,
expr,
@ -403,7 +405,7 @@ fn parse_extern_type(
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
attrs::parse(
let attrs = attrs::parse(
cx,
foreign_type.attrs,
attrs::Parser {
@ -434,6 +436,7 @@ fn parse_extern_type(
lang,
doc,
derives,
attrs,
type_token,
name,
generics,
@ -451,14 +454,13 @@ fn parse_extern_fn(
trusted: bool,
namespace: &Namespace,
) -> Result<Api> {
let attrs = mem::take(&mut foreign_fn.attrs);
let mut doc = Doc::new();
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
attrs::parse(
let attrs = attrs::parse(
cx,
attrs,
mem::take(&mut foreign_fn.attrs),
attrs::Parser {
doc: Some(&mut doc),
namespace: Some(&mut namespace),
@ -542,9 +544,11 @@ fn parse_extern_fn(
let ty = parse_type(&arg.ty)?;
if ident != "self" {
let doc = Doc::new();
let attrs = Vec::new();
let visibility = Token![pub](ident.span());
args.push_value(Var {
doc,
attrs,
visibility,
ident,
ty,
@ -591,6 +595,7 @@ fn parse_extern_fn(
}(ExternFn {
lang,
doc,
attrs,
name,
sig: Signature {
unsafety,
@ -701,7 +706,7 @@ fn parse_type_alias(
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
attrs::parse(
let attrs = attrs::parse(
cx,
attrs,
attrs::Parser {
@ -725,6 +730,7 @@ fn parse_type_alias(
Ok(Api::TypeAlias(TypeAlias {
doc,
derives,
attrs,
type_token,
name,
generics,
@ -783,7 +789,7 @@ fn parse_extern_type_bounded(
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
attrs::parse(
let attrs = attrs::parse(
cx,
attrs,
attrs::Parser {
@ -805,6 +811,7 @@ fn parse_extern_type_bounded(
lang,
doc,
derives,
attrs,
type_token,
name,
generics,
@ -1115,9 +1122,11 @@ fn parse_type_fn(ty: &TypeBareFn) -> Result<Type> {
None => format_ident!("arg{}", i),
};
let doc = Doc::new();
let attrs = Vec::new();
let visibility = Token![pub](ident.span());
Ok(Var {
doc,
attrs,
visibility,
ident,
ty,