Vendor dependencies
Let's see how I like this workflow.
This commit is contained in:
parent
34d1830413
commit
9c435dc440
7500 changed files with 1665121 additions and 99 deletions
286
vendor/cxxbridge-macro/src/derive.rs
vendored
Normal file
286
vendor/cxxbridge-macro/src/derive.rs
vendored
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
use crate::syntax::{derive, Enum, Struct, Trait};
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
|
||||
pub use crate::syntax::derive::*;
|
||||
|
||||
pub fn expand_struct(strct: &Struct, actual_derives: &mut Option<TokenStream>) -> TokenStream {
|
||||
let mut expanded = TokenStream::new();
|
||||
let mut traits = Vec::new();
|
||||
|
||||
for derive in &strct.derives {
|
||||
let span = derive.span;
|
||||
match derive.what {
|
||||
Trait::Copy => expanded.extend(struct_copy(strct, span)),
|
||||
Trait::Clone => expanded.extend(struct_clone(strct, span)),
|
||||
Trait::Debug => expanded.extend(struct_debug(strct, span)),
|
||||
Trait::Default => expanded.extend(struct_default(strct, span)),
|
||||
Trait::Eq => traits.push(quote_spanned!(span=> ::cxx::core::cmp::Eq)),
|
||||
Trait::ExternType => unreachable!(),
|
||||
Trait::Hash => traits.push(quote_spanned!(span=> ::cxx::core::hash::Hash)),
|
||||
Trait::Ord => expanded.extend(struct_ord(strct, span)),
|
||||
Trait::PartialEq => traits.push(quote_spanned!(span=> ::cxx::core::cmp::PartialEq)),
|
||||
Trait::PartialOrd => expanded.extend(struct_partial_ord(strct, span)),
|
||||
Trait::Serialize => traits.push(quote_spanned!(span=> ::serde::Serialize)),
|
||||
Trait::Deserialize => traits.push(quote_spanned!(span=> ::serde::Deserialize)),
|
||||
}
|
||||
}
|
||||
|
||||
if traits.is_empty() {
|
||||
*actual_derives = None;
|
||||
} else {
|
||||
*actual_derives = Some(quote!(#[derive(#(#traits),*)]));
|
||||
}
|
||||
|
||||
expanded
|
||||
}
|
||||
|
||||
pub fn expand_enum(enm: &Enum, actual_derives: &mut Option<TokenStream>) -> TokenStream {
|
||||
let mut expanded = TokenStream::new();
|
||||
let mut traits = Vec::new();
|
||||
let mut has_copy = false;
|
||||
let mut has_clone = false;
|
||||
let mut has_eq = false;
|
||||
let mut has_partial_eq = false;
|
||||
|
||||
for derive in &enm.derives {
|
||||
let span = derive.span;
|
||||
match derive.what {
|
||||
Trait::Copy => {
|
||||
expanded.extend(enum_copy(enm, span));
|
||||
has_copy = true;
|
||||
}
|
||||
Trait::Clone => {
|
||||
expanded.extend(enum_clone(enm, span));
|
||||
has_clone = true;
|
||||
}
|
||||
Trait::Debug => expanded.extend(enum_debug(enm, span)),
|
||||
Trait::Default => unreachable!(),
|
||||
Trait::Eq => {
|
||||
traits.push(quote_spanned!(span=> ::cxx::core::cmp::Eq));
|
||||
has_eq = true;
|
||||
}
|
||||
Trait::ExternType => unreachable!(),
|
||||
Trait::Hash => traits.push(quote_spanned!(span=> ::cxx::core::hash::Hash)),
|
||||
Trait::Ord => expanded.extend(enum_ord(enm, span)),
|
||||
Trait::PartialEq => {
|
||||
traits.push(quote_spanned!(span=> ::cxx::core::cmp::PartialEq));
|
||||
has_partial_eq = true;
|
||||
}
|
||||
Trait::PartialOrd => expanded.extend(enum_partial_ord(enm, span)),
|
||||
Trait::Serialize => traits.push(quote_spanned!(span=> ::serde::Serialize)),
|
||||
Trait::Deserialize => traits.push(quote_spanned!(span=> ::serde::Deserialize)),
|
||||
}
|
||||
}
|
||||
|
||||
let span = enm.name.rust.span();
|
||||
if !has_copy {
|
||||
expanded.extend(enum_copy(enm, span));
|
||||
}
|
||||
if !has_clone {
|
||||
expanded.extend(enum_clone(enm, span));
|
||||
}
|
||||
if !has_eq {
|
||||
// Required to be derived in order for the enum's "variants" to be
|
||||
// usable in patterns.
|
||||
traits.push(quote!(::cxx::core::cmp::Eq));
|
||||
}
|
||||
if !has_partial_eq {
|
||||
traits.push(quote!(::cxx::core::cmp::PartialEq));
|
||||
}
|
||||
|
||||
*actual_derives = Some(quote!(#[derive(#(#traits),*)]));
|
||||
|
||||
expanded
|
||||
}
|
||||
|
||||
fn struct_copy(strct: &Struct, span: Span) -> TokenStream {
|
||||
let ident = &strct.name.rust;
|
||||
let generics = &strct.generics;
|
||||
|
||||
quote_spanned! {span=>
|
||||
impl #generics ::cxx::core::marker::Copy for #ident #generics {}
|
||||
}
|
||||
}
|
||||
|
||||
fn struct_clone(strct: &Struct, span: Span) -> TokenStream {
|
||||
let ident = &strct.name.rust;
|
||||
let generics = &strct.generics;
|
||||
|
||||
let body = if derive::contains(&strct.derives, Trait::Copy) {
|
||||
quote!(*self)
|
||||
} else {
|
||||
let fields = strct.fields.iter().map(|field| &field.name.rust);
|
||||
let values = strct.fields.iter().map(|field| {
|
||||
let ident = &field.name.rust;
|
||||
let ty = field.ty.to_token_stream();
|
||||
let span = ty.into_iter().last().unwrap().span();
|
||||
quote_spanned!(span=> &self.#ident)
|
||||
});
|
||||
quote_spanned!(span=> #ident {
|
||||
#(#fields: ::cxx::core::clone::Clone::clone(#values),)*
|
||||
})
|
||||
};
|
||||
|
||||
quote_spanned! {span=>
|
||||
impl #generics ::cxx::core::clone::Clone for #ident #generics {
|
||||
fn clone(&self) -> Self {
|
||||
#body
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn struct_debug(strct: &Struct, span: Span) -> TokenStream {
|
||||
let ident = &strct.name.rust;
|
||||
let generics = &strct.generics;
|
||||
let struct_name = ident.to_string();
|
||||
let fields = strct.fields.iter().map(|field| &field.name.rust);
|
||||
let field_names = fields.clone().map(Ident::to_string);
|
||||
|
||||
quote_spanned! {span=>
|
||||
impl #generics ::cxx::core::fmt::Debug for #ident #generics {
|
||||
fn fmt(&self, formatter: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {
|
||||
formatter.debug_struct(#struct_name)
|
||||
#(.field(#field_names, &self.#fields))*
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn struct_default(strct: &Struct, span: Span) -> TokenStream {
|
||||
let ident = &strct.name.rust;
|
||||
let generics = &strct.generics;
|
||||
let fields = strct.fields.iter().map(|field| &field.name.rust);
|
||||
|
||||
quote_spanned! {span=>
|
||||
#[allow(clippy::derivable_impls)] // different spans than the derived impl
|
||||
impl #generics ::cxx::core::default::Default for #ident #generics {
|
||||
fn default() -> Self {
|
||||
#ident {
|
||||
#(
|
||||
#fields: ::cxx::core::default::Default::default(),
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn struct_ord(strct: &Struct, span: Span) -> TokenStream {
|
||||
let ident = &strct.name.rust;
|
||||
let generics = &strct.generics;
|
||||
let fields = strct.fields.iter().map(|field| &field.name.rust);
|
||||
|
||||
quote_spanned! {span=>
|
||||
impl #generics ::cxx::core::cmp::Ord for #ident #generics {
|
||||
fn cmp(&self, other: &Self) -> ::cxx::core::cmp::Ordering {
|
||||
#(
|
||||
match ::cxx::core::cmp::Ord::cmp(&self.#fields, &other.#fields) {
|
||||
::cxx::core::cmp::Ordering::Equal => {}
|
||||
ordering => return ordering,
|
||||
}
|
||||
)*
|
||||
::cxx::core::cmp::Ordering::Equal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn struct_partial_ord(strct: &Struct, span: Span) -> TokenStream {
|
||||
let ident = &strct.name.rust;
|
||||
let generics = &strct.generics;
|
||||
|
||||
let body = if derive::contains(&strct.derives, Trait::Ord) {
|
||||
quote! {
|
||||
::cxx::core::option::Option::Some(::cxx::core::cmp::Ord::cmp(self, other))
|
||||
}
|
||||
} else {
|
||||
let fields = strct.fields.iter().map(|field| &field.name.rust);
|
||||
quote! {
|
||||
#(
|
||||
match ::cxx::core::cmp::PartialOrd::partial_cmp(&self.#fields, &other.#fields) {
|
||||
::cxx::core::option::Option::Some(::cxx::core::cmp::Ordering::Equal) => {}
|
||||
ordering => return ordering,
|
||||
}
|
||||
)*
|
||||
::cxx::core::option::Option::Some(::cxx::core::cmp::Ordering::Equal)
|
||||
}
|
||||
};
|
||||
|
||||
quote_spanned! {span=>
|
||||
impl #generics ::cxx::core::cmp::PartialOrd for #ident #generics {
|
||||
fn partial_cmp(&self, other: &Self) -> ::cxx::core::option::Option<::cxx::core::cmp::Ordering> {
|
||||
#body
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn enum_copy(enm: &Enum, span: Span) -> TokenStream {
|
||||
let ident = &enm.name.rust;
|
||||
|
||||
quote_spanned! {span=>
|
||||
impl ::cxx::core::marker::Copy for #ident {}
|
||||
}
|
||||
}
|
||||
|
||||
fn enum_clone(enm: &Enum, span: Span) -> TokenStream {
|
||||
let ident = &enm.name.rust;
|
||||
|
||||
quote_spanned! {span=>
|
||||
impl ::cxx::core::clone::Clone for #ident {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn enum_debug(enm: &Enum, span: Span) -> TokenStream {
|
||||
let ident = &enm.name.rust;
|
||||
let variants = enm.variants.iter().map(|variant| {
|
||||
let variant = &variant.name.rust;
|
||||
let name = variant.to_string();
|
||||
quote_spanned! {span=>
|
||||
#ident::#variant => formatter.write_str(#name),
|
||||
}
|
||||
});
|
||||
let fallback = format!("{}({{}})", ident);
|
||||
|
||||
quote_spanned! {span=>
|
||||
impl ::cxx::core::fmt::Debug for #ident {
|
||||
fn fmt(&self, formatter: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {
|
||||
match *self {
|
||||
#(#variants)*
|
||||
_ => ::cxx::core::write!(formatter, #fallback, self.repr),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn enum_ord(enm: &Enum, span: Span) -> TokenStream {
|
||||
let ident = &enm.name.rust;
|
||||
|
||||
quote_spanned! {span=>
|
||||
impl ::cxx::core::cmp::Ord for #ident {
|
||||
fn cmp(&self, other: &Self) -> ::cxx::core::cmp::Ordering {
|
||||
::cxx::core::cmp::Ord::cmp(&self.repr, &other.repr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn enum_partial_ord(enm: &Enum, span: Span) -> TokenStream {
|
||||
let ident = &enm.name.rust;
|
||||
|
||||
quote_spanned! {span=>
|
||||
impl ::cxx::core::cmp::PartialOrd for #ident {
|
||||
fn partial_cmp(&self, other: &Self) -> ::cxx::core::option::Option<::cxx::core::cmp::Ordering> {
|
||||
::cxx::core::cmp::PartialOrd::partial_cmp(&self.repr, &other.repr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue