Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Anton Danilkin
2018-09-07 13:46:20 +03:00
46 changed files with 1293 additions and 360 deletions

View File

@ -34,6 +34,7 @@ pub(crate) struct FirstPassRecord<'src> {
pub(crate) namespaces: BTreeMap<&'src str, NamespaceData<'src>>,
pub(crate) includes: BTreeMap<&'src str, BTreeSet<&'src str>>,
pub(crate) dictionaries: BTreeMap<&'src str, DictionaryData<'src>>,
pub(crate) callbacks: BTreeSet<&'src str>,
}
/// We need to collect interface data during the first pass, to be used later.
@ -136,12 +137,9 @@ impl<'src> FirstPass<'src, ()> for weedle::Definition<'src> {
Namespace(namespace) => namespace.first_pass(record, ()),
PartialNamespace(namespace) => namespace.first_pass(record, ()),
Typedef(typedef) => typedef.first_pass(record, ()),
Callback(callback) => callback.first_pass(record, ()),
Implements(_) => Ok(()),
Callback(..) => {
warn!("Unsupported WebIDL Callback definition: {:?}", self);
Ok(())
}
CallbackInterface(..) => {
warn!("Unsupported WebIDL CallbackInterface definition: {:?}", self);
Ok(())
@ -684,6 +682,13 @@ impl<'src> FirstPass<'src, &'src str> for weedle::namespace::OperationNamespaceM
}
}
impl<'src> FirstPass<'src, ()> for weedle::CallbackDefinition<'src> {
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, _: ()) -> Result<()> {
record.callbacks.insert(self.identifier.0);
Ok(())
}
}
impl<'a> FirstPassRecord<'a> {
pub fn all_superclasses<'me>(&'me self, interface: &str)
-> impl Iterator<Item = String> + 'me

View File

@ -28,6 +28,7 @@ pub(crate) enum IdlType<'a> {
Object,
Symbol,
Error,
Callback,
ArrayBuffer,
DataView,
@ -293,6 +294,8 @@ impl<'a> ToIdlType<'a> for Identifier<'a> {
Some(IdlType::Dictionary(self.0))
} else if record.enums.contains_key(self.0) {
Some(IdlType::Enum(self.0))
} else if record.callbacks.contains(self.0) {
Some(IdlType::Callback)
} else {
warn!("Unrecognized type: {}", self.0);
None
@ -364,6 +367,7 @@ impl<'a> IdlType<'a> {
IdlType::Object => dst.push_str("object"),
IdlType::Symbol => dst.push_str("symbol"),
IdlType::Error => dst.push_str("error"),
IdlType::Callback => dst.push_str("callback"),
IdlType::ArrayBuffer => dst.push_str("array_buffer"),
IdlType::DataView => dst.push_str("data_view"),
@ -426,6 +430,17 @@ impl<'a> IdlType<'a> {
/// Converts to syn type if possible.
pub(crate) fn to_syn_type(&self, pos: TypePosition) -> Option<syn::Type> {
let anyref = |ty| {
Some(match pos {
TypePosition::Argument => shared_ref(ty, false),
TypePosition::Return => ty,
})
};
let js_sys = |name: &str| {
let path = vec![rust_ident("js_sys"), rust_ident(name)];
let ty = leading_colon_path_ty(path);
anyref(ty)
};
match self {
IdlType::Boolean => Some(ident_ty(raw_ident("bool"))),
IdlType::Byte => Some(ident_ty(raw_ident("i8"))),
@ -446,17 +461,11 @@ impl<'a> IdlType<'a> {
TypePosition::Argument => Some(shared_ref(ident_ty(raw_ident("str")), false)),
TypePosition::Return => Some(ident_ty(raw_ident("String"))),
},
IdlType::Object => {
let path = vec![rust_ident("js_sys"), rust_ident("Object")];
Some(leading_colon_path_ty(path))
},
IdlType::Object => js_sys("Object"),
IdlType::Symbol => None,
IdlType::Error => None,
IdlType::ArrayBuffer => {
let path = vec![rust_ident("js_sys"), rust_ident("ArrayBuffer")];
Some(leading_colon_path_ty(path))
},
IdlType::ArrayBuffer => js_sys("ArrayBuffer"),
IdlType::DataView => None,
IdlType::Int8Array => Some(array("i8", pos, false)),
IdlType::Uint8Array => Some(array("u8", pos, false)),
@ -469,10 +478,7 @@ impl<'a> IdlType<'a> {
IdlType::Float32Array => Some(array("f32", pos, false)),
IdlType::Float64Array => Some(array("f64", pos, false)),
IdlType::ArrayBufferView | IdlType::BufferSource => {
let path = vec![rust_ident("js_sys"), rust_ident("Object")];
Some(leading_colon_path_ty(path))
},
IdlType::ArrayBufferView | IdlType::BufferSource => js_sys("Object"),
IdlType::Interface(name)
| IdlType::Dictionary(name) => {
let ty = ident_ty(rust_ident(camel_case_ident(name).as_str()));
@ -487,15 +493,7 @@ impl<'a> IdlType<'a> {
IdlType::Nullable(idl_type) => Some(option_ty(idl_type.to_syn_type(pos)?)),
IdlType::FrozenArray(_idl_type) => None,
IdlType::Sequence(_idl_type) => None,
IdlType::Promise(_idl_type) => {
let path = vec![rust_ident("js_sys"), rust_ident("Promise")];
let ty = leading_colon_path_ty(path);
if pos == TypePosition::Argument {
Some(shared_ref(ty, false))
} else {
Some(ty)
}
}
IdlType::Promise(_idl_type) => js_sys("Promise"),
IdlType::Record(_idl_type_from, _idl_type_to) => None,
IdlType::Union(idl_types) => {
// Handles union types in all places except operation argument types.
@ -521,9 +519,10 @@ impl<'a> IdlType<'a> {
IdlType::Any => {
let path = vec![rust_ident("wasm_bindgen"), rust_ident("JsValue")];
Some(leading_colon_path_ty(path))
anyref(leading_colon_path_ty(path))
},
IdlType::Void => None,
IdlType::Callback => js_sys("Function"),
}
}
@ -577,9 +576,12 @@ impl<'a> IdlType<'a> {
.iter()
.flat_map(|idl_type| idl_type.flatten())
.collect(),
IdlType::ArrayBufferView | IdlType::BufferSource =>
vec![IdlType::Object, IdlType::Uint8ArrayMut],
IdlType::ArrayBufferView => {
vec![IdlType::ArrayBufferView, IdlType::Uint8ArrayMut]
}
IdlType::BufferSource => {
vec![IdlType::BufferSource, IdlType::Uint8ArrayMut]
}
idl_type @ _ => vec![idl_type.clone()],
}
}

View File

@ -138,7 +138,7 @@ fn builtin_idents() -> BTreeSet<Ident> {
vec![
"str", "char", "bool", "JsValue", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64",
"usize", "isize", "f32", "f64", "Result", "String", "Box", "Vec", "Option",
"ArrayBuffer", "Object", "Promise",
"ArrayBuffer", "Object", "Promise", "Function",
].into_iter()
.map(|id| proc_macro2::Ident::new(id, proc_macro2::Span::call_site())),
)