Bug 1474793 - Part 9: Add support for deriving ToShmem. r=emilio

Depends on D17188

Differential Revision: https://phabricator.services.mozilla.com/D17189

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Cameron McCormack 2019-03-30 00:16:08 +00:00
parent c1d7542bbd
commit 8c9949aa66
6 changed files with 134 additions and 0 deletions

13
Cargo.lock generated
View File

@ -2735,6 +2735,7 @@ dependencies = [
"thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"to_shmem 0.0.1",
"to_shmem_derive 0.0.1",
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"uluru 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2940,6 +2941,18 @@ dependencies = [
name = "to_shmem"
version = "0.0.1"
[[package]]
name = "to_shmem_derive"
version = "0.0.1"
dependencies = [
"darling 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_common 0.0.1",
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio"
version = "0.1.7"

View File

@ -70,6 +70,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"

View File

@ -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)]

View File

@ -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"

View File

@ -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()
}

View File

@ -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,
}