Skip to content
Permalink
Browse files

style: Add support for deriving ToShmem.

  • Loading branch information...
heycam authored and emilio committed Mar 30, 2019
1 parent d8a7582 commit f6ef35c5d323bef6fdc3d9fbd6048d4a350ef2cb
@@ -69,6 +69,7 @@ style_traits = {path = "../style_traits"}
servo_url = {path = "../url", optional = true}
thin-slice = "0.1.0"
to_shmem = {path = "../to_shmem"}
to_shmem_derive = {path = "../to_shmem_derive"}
time = "0.1"
uluru = "0.3"
unicode-bidi = "0.3"
@@ -100,6 +100,8 @@ extern crate style_traits;
extern crate thin_slice;
extern crate time;
extern crate to_shmem;
#[macro_use]
extern crate to_shmem_derive;
extern crate uluru;
extern crate unicode_bidi;
#[allow(unused_extern_crates)]
@@ -0,0 +1,18 @@
[package]
name = "to_shmem_derive"
version = "0.0.1"
authors = ["The Servo Project Developers"]
license = "MPL-2.0"
publish = false

[lib]
path = "lib.rs"
proc-macro = true

[dependencies]
darling = "0.8"
derive_common = { path = "../derive_common" }
proc-macro2 = "0.4"
quote = "0.6"
syn = { version = "0.15", features = ["visit"] }
synstructure = "0.10"
@@ -0,0 +1,26 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#![recursion_limit = "128"]

#[macro_use]
extern crate darling;
extern crate derive_common;
extern crate proc_macro;
extern crate proc_macro2;
#[macro_use]
extern crate quote;
#[macro_use]
extern crate syn;
extern crate synstructure;

use proc_macro::TokenStream;

mod to_shmem;

#[proc_macro_derive(ToShmem, attributes(shmem))]
pub fn derive_to_shmem(stream: TokenStream) -> TokenStream {
let input = syn::parse(stream).unwrap();
to_shmem::derive(input).into()
}
@@ -0,0 +1,74 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use derive_common::cg;
use proc_macro2::TokenStream;
use syn;
use synstructure::{BindStyle, Structure};

pub fn derive(mut input: syn::DeriveInput) -> TokenStream {
let mut where_clause = input.generics.where_clause.take();
let attrs = cg::parse_input_attrs::<ShmemInputAttrs>(&input);
if !attrs.no_bounds {
for param in input.generics.type_params() {
cg::add_predicate(
&mut where_clause,
parse_quote!(#param: ::to_shmem::ToShmem),
);
}
}
for variant in Structure::new(&input).variants() {
for binding in variant.bindings() {
let attrs = cg::parse_field_attrs::<ShmemFieldAttrs>(&binding.ast());
if attrs.field_bound {
let ty = &binding.ast().ty;
cg::add_predicate(
&mut where_clause,
parse_quote!(#ty: ::to_shmem::ToShmem),
)
}
}
}

input.generics.where_clause = where_clause;

let match_body = cg::fmap_match(&input, BindStyle::Ref, |binding| {
quote! {
::std::mem::ManuallyDrop::into_inner(
::to_shmem::ToShmem::to_shmem(#binding, builder)
)
}
});

let name = &input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();

quote! {
impl #impl_generics ::to_shmem::ToShmem for #name #ty_generics #where_clause {
#[allow(unused_variables)]
fn to_shmem(
&self,
builder: &mut ::to_shmem::SharedMemoryBuilder,
) -> ::std::mem::ManuallyDrop<Self> {
::std::mem::ManuallyDrop::new(
match *self {
#match_body
}
)
}
}
}
}

#[darling(attributes(shmem), default)]
#[derive(Default, FromDeriveInput)]
pub struct ShmemInputAttrs {
pub no_bounds: bool,
}

#[darling(attributes(shmem), default)]
#[derive(Default, FromField)]
pub struct ShmemFieldAttrs {
pub field_bound: bool,
}

0 comments on commit f6ef35c

Please sign in to comment.
You can’t perform that action at this time.