Implement #[wasm_bindgen(extends = ...)]

This commit implements the `extends` attribute for `#[wasm_bindgen]` to
statically draw the inheritance hierarchy in the generated bindings, generating
appropriate `AsRef`, `AsMut`, and `From` implementations.
This commit is contained in:
Alex Crichton
2018-08-04 10:00:30 -07:00
parent 11553a1af2
commit 37db88ebfa
10 changed files with 331 additions and 4 deletions

View File

@ -17,6 +17,7 @@ use weedle;
use super::Result;
use util;
use util::camel_case_ident;
/// Collection of constructs that may use partial.
#[derive(Default)]
@ -36,6 +37,7 @@ pub(crate) struct InterfaceData<'src> {
pub(crate) partial: bool,
pub(crate) global: bool,
pub(crate) operations: BTreeMap<OperationId<'src>, OperationData<'src>>,
pub(crate) superclass: Option<&'src str>,
}
#[derive(PartialEq, Eq, PartialOrd, Ord)]
@ -146,6 +148,7 @@ impl<'src> FirstPass<'src, ()> for weedle::InterfaceDefinition<'src> {
.entry(self.identifier.0)
.or_insert_with(Default::default);
interface.partial = false;
interface.superclass = self.inheritance.map(|s| s.identifier.0);
}
if util::is_chrome_only(&self.attributes) {
@ -176,6 +179,7 @@ impl<'src> FirstPass<'src, ()> for weedle::PartialInterfaceDefinition<'src> {
partial: true,
operations: Default::default(),
global: false,
superclass: None,
},
);
@ -307,3 +311,27 @@ impl<'src> FirstPass<'src, ()> for weedle::TypedefDefinition<'src> {
Ok(())
}
}
impl<'a> FirstPassRecord<'a> {
pub fn all_superclasses<'me>(&'me self, interface: &str)
-> impl Iterator<Item = String> + 'me
{
let mut set = BTreeSet::new();
self.fill_superclasses(interface, &mut set);
set.into_iter()
}
fn fill_superclasses(&self, interface: &str, set: &mut BTreeSet<String>) {
let data = match self.interfaces.get(interface) {
Some(data) => data,
None => return,
};
let superclass = match &data.superclass {
Some(class) => class,
None => return,
};
if set.insert(camel_case_ident(superclass)) {
self.fill_superclasses(superclass, set);
}
}
}

View File

@ -39,6 +39,7 @@ use backend::defined::{ImportedTypeDefinitions, RemoveUndefinedImports};
use backend::util::{ident_ty, rust_ident, wrap_import_function};
use failure::ResultExt;
use heck::{ShoutySnakeCase};
use proc_macro2::{Ident, Span};
use weedle::argument::Argument;
use weedle::attribute::{ExtendedAttribute, ExtendedAttributeList};
@ -246,7 +247,10 @@ impl<'src> WebidlParse<'src, ()> for weedle::InterfaceDefinition<'src> {
name: rust_ident(camel_case_ident(self.identifier.0).as_str()),
attrs: Vec::new(),
doc_comment,
instanceof_shim: format!("__widl_instanceof_{}", self.name),
instanceof_shim: format!("__widl_instanceof_{}", self.identifier.0),
extends: first_pass.all_superclasses(self.identifier.0)
.map(|name| Ident::new(&name, Span::call_site()))
.collect(),
}),
});