mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-20 16:26:33 +00:00
cargo +nightly fmt --all
Rustfmt all the things!
This commit is contained in:
@ -8,16 +8,16 @@ pub type Result<T> = ::std::result::Result<T, Error>;
|
||||
#[derive(Debug, Fail, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub enum ErrorKind {
|
||||
/// Failed to open a WebIDL file.
|
||||
#[fail(display="opening WebIDL file")]
|
||||
#[fail(display = "opening WebIDL file")]
|
||||
OpeningWebIDLFile,
|
||||
/// Failed to read a WebIDL file.
|
||||
#[fail(display="reading WebIDL file")]
|
||||
#[fail(display = "reading WebIDL file")]
|
||||
ReadingWebIDLFile,
|
||||
/// Failed to parse a WebIDL file.
|
||||
#[fail(display="parsing WebIDL source text at {}", _0)]
|
||||
#[fail(display = "parsing WebIDL source text at {}", _0)]
|
||||
ParsingWebIDLSourcePos(usize),
|
||||
/// Failed to parse a WebIDL file.
|
||||
#[fail(display="parsing WebIDL source text")]
|
||||
#[fail(display = "parsing WebIDL source text")]
|
||||
ParsingWebIDLSource,
|
||||
}
|
||||
|
||||
@ -52,7 +52,9 @@ impl Error {
|
||||
|
||||
impl From<ErrorKind> for Error {
|
||||
fn from(kind: ErrorKind) -> Error {
|
||||
Error { inner: Context::new(kind) }
|
||||
Error {
|
||||
inner: Context::new(kind),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,5 +63,3 @@ impl From<Context<ErrorKind>> for Error {
|
||||
Error { inner: inner }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,17 +11,17 @@ use std::cmp::Ordering;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use proc_macro2::Ident;
|
||||
use weedle::{DictionaryDefinition, PartialDictionaryDefinition};
|
||||
use weedle::CallbackInterfaceDefinition;
|
||||
use weedle;
|
||||
use weedle::argument::Argument;
|
||||
use weedle::attribute::*;
|
||||
use weedle::interface::*;
|
||||
use weedle::mixin::*;
|
||||
use weedle;
|
||||
use weedle::CallbackInterfaceDefinition;
|
||||
use weedle::{DictionaryDefinition, PartialDictionaryDefinition};
|
||||
|
||||
use super::Result;
|
||||
use util::camel_case_ident;
|
||||
use util;
|
||||
use util::camel_case_ident;
|
||||
|
||||
/// Collection of constructs that may use partial.
|
||||
#[derive(Default)]
|
||||
@ -154,7 +154,9 @@ impl<'src> FirstPass<'src, ()> for weedle::DictionaryDefinition<'src> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
record.dictionaries.entry(self.identifier.0)
|
||||
record
|
||||
.dictionaries
|
||||
.entry(self.identifier.0)
|
||||
.or_default()
|
||||
.definition = Some(self);
|
||||
Ok(())
|
||||
@ -167,7 +169,9 @@ impl<'src> FirstPass<'src, ()> for weedle::PartialDictionaryDefinition<'src> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
record.dictionaries.entry(self.identifier.0)
|
||||
record
|
||||
.dictionaries
|
||||
.entry(self.identifier.0)
|
||||
.or_default()
|
||||
.partials
|
||||
.push(self);
|
||||
@ -182,7 +186,10 @@ impl<'src> FirstPass<'src, ()> for weedle::EnumDefinition<'src> {
|
||||
}
|
||||
|
||||
if record.enums.insert(self.identifier.0, self).is_some() {
|
||||
info!("Encountered multiple enum declarations: {}", self.identifier.0);
|
||||
info!(
|
||||
"Encountered multiple enum declarations: {}",
|
||||
self.identifier.0
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -223,7 +230,7 @@ fn first_pass_operation<'src>(
|
||||
is_static: bool,
|
||||
) {
|
||||
if util::is_chrome_only(attrs) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
let mut names = Vec::with_capacity(arguments.len());
|
||||
@ -240,29 +247,32 @@ fn first_pass_operation<'src>(
|
||||
.get_mut(self_name)
|
||||
.expect(&format!("not found {} interface", self_name));
|
||||
&mut x.operations
|
||||
},
|
||||
}
|
||||
FirstPassOperationType::Mixin => {
|
||||
let x = record
|
||||
.mixins
|
||||
.get_mut(self_name)
|
||||
.expect(&format!("not found {} mixin", self_name));
|
||||
&mut x.operations
|
||||
},
|
||||
}
|
||||
FirstPassOperationType::Namespace => {
|
||||
let x = record
|
||||
.namespaces
|
||||
.get_mut(self_name)
|
||||
.expect(&format!("not found {} namespace", self_name));
|
||||
&mut x.operations
|
||||
},
|
||||
}
|
||||
};
|
||||
let mut args = Vec::with_capacity(arguments.len());
|
||||
for argument in arguments {
|
||||
let (name, ty, optional, variadic) = match argument {
|
||||
Argument::Single(single) =>
|
||||
(single.identifier.0, &single.type_.type_, single.optional.is_some(), false),
|
||||
Argument::Variadic(variadic) =>
|
||||
(variadic.identifier.0, &variadic.type_, false, true),
|
||||
Argument::Single(single) => (
|
||||
single.identifier.0,
|
||||
&single.type_.type_,
|
||||
single.optional.is_some(),
|
||||
false,
|
||||
),
|
||||
Argument::Variadic(variadic) => (variadic.identifier.0, &variadic.type_, false, true),
|
||||
};
|
||||
args.push(Arg {
|
||||
name,
|
||||
@ -289,26 +299,22 @@ impl<'src> FirstPass<'src, ()> for weedle::InterfaceDefinition<'src> {
|
||||
}
|
||||
|
||||
if util::is_no_interface_object(&self.attributes) {
|
||||
info!("Skipping because of `NoInterfaceObject` attribute: {:?}", self.identifier.0);
|
||||
info!(
|
||||
"Skipping because of `NoInterfaceObject` attribute: {:?}",
|
||||
self.identifier.0
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
{
|
||||
let interface_data = record
|
||||
.interfaces
|
||||
.entry(self.identifier.0)
|
||||
.or_default();
|
||||
let interface_data = record.interfaces.entry(self.identifier.0).or_default();
|
||||
interface_data.partial = false;
|
||||
interface_data.superclass = self.inheritance.map(|s| s.identifier.0);
|
||||
interface_data.definition_attributes = self.attributes.as_ref();
|
||||
}
|
||||
if let Some(attrs) = &self.attributes {
|
||||
for attr in attrs.body.list.iter() {
|
||||
process_interface_attribute(
|
||||
record,
|
||||
self.identifier.0,
|
||||
attr,
|
||||
);
|
||||
process_interface_attribute(record, self.identifier.0, attr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,18 +329,19 @@ impl<'src> FirstPass<'src, ()> for weedle::InterfaceDefinition<'src> {
|
||||
fn process_interface_attribute<'src>(
|
||||
record: &mut FirstPassRecord<'src>,
|
||||
self_name: &'src str,
|
||||
attr: &'src ExtendedAttribute<'src>
|
||||
attr: &'src ExtendedAttribute<'src>,
|
||||
) {
|
||||
let ident = weedle::common::Identifier(self_name);
|
||||
let non_null = weedle::types::MayBeNull { type_: ident, q_mark: None };
|
||||
let non_null = weedle::types::MayBeNull {
|
||||
type_: ident,
|
||||
q_mark: None,
|
||||
};
|
||||
let non_any = weedle::types::NonAnyType::Identifier(non_null);
|
||||
let single = weedle::types::SingleType::NonAny(non_any);
|
||||
let ty = weedle::types::Type::Single(single);
|
||||
let return_ty = weedle::types::ReturnType::Type(ty);
|
||||
match attr {
|
||||
ExtendedAttribute::ArgList(list)
|
||||
if list.identifier.0 == "Constructor" =>
|
||||
{
|
||||
ExtendedAttribute::ArgList(list) if list.identifier.0 == "Constructor" => {
|
||||
first_pass_operation(
|
||||
record,
|
||||
FirstPassOperationType::Interface,
|
||||
@ -358,14 +365,14 @@ fn process_interface_attribute<'src>(
|
||||
false,
|
||||
);
|
||||
}
|
||||
ExtendedAttribute::NamedArgList(list)
|
||||
if list.lhs_identifier.0 == "NamedConstructor" =>
|
||||
{
|
||||
ExtendedAttribute::NamedArgList(list) if list.lhs_identifier.0 == "NamedConstructor" => {
|
||||
first_pass_operation(
|
||||
record,
|
||||
FirstPassOperationType::Interface,
|
||||
self_name,
|
||||
&[OperationId::Constructor(IgnoreTraits(list.rhs_identifier.0))],
|
||||
&[OperationId::Constructor(IgnoreTraits(
|
||||
list.rhs_identifier.0,
|
||||
))],
|
||||
&list.args.body.list,
|
||||
&return_ty,
|
||||
&None,
|
||||
@ -384,12 +391,10 @@ impl<'src> FirstPass<'src, ()> for weedle::PartialInterfaceDefinition<'src> {
|
||||
record
|
||||
.interfaces
|
||||
.entry(self.identifier.0)
|
||||
.or_insert_with(||
|
||||
InterfaceData {
|
||||
partial: true,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
.or_insert_with(|| InterfaceData {
|
||||
partial: true,
|
||||
..Default::default()
|
||||
});
|
||||
for member in &self.members.body {
|
||||
member.first_pass(record, self.identifier.0)?;
|
||||
}
|
||||
@ -398,19 +403,20 @@ impl<'src> FirstPass<'src, ()> for weedle::PartialInterfaceDefinition<'src> {
|
||||
}
|
||||
|
||||
impl<'src> FirstPass<'src, &'src str> for weedle::interface::InterfaceMember<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, self_name: &'src str) -> Result<()> {
|
||||
fn first_pass(
|
||||
&'src self,
|
||||
record: &mut FirstPassRecord<'src>,
|
||||
self_name: &'src str,
|
||||
) -> Result<()> {
|
||||
match self {
|
||||
InterfaceMember::Attribute(attr) => {
|
||||
attr.first_pass(record, self_name)
|
||||
}
|
||||
InterfaceMember::Operation(op) => {
|
||||
op.first_pass(record, self_name)
|
||||
}
|
||||
InterfaceMember::Attribute(attr) => attr.first_pass(record, self_name),
|
||||
InterfaceMember::Operation(op) => op.first_pass(record, self_name),
|
||||
InterfaceMember::Const(const_) => {
|
||||
if util::is_chrome_only(&const_.attributes) {
|
||||
return Ok(());
|
||||
}
|
||||
record.interfaces
|
||||
record
|
||||
.interfaces
|
||||
.get_mut(self_name)
|
||||
.unwrap()
|
||||
.consts
|
||||
@ -427,7 +433,10 @@ impl<'src> FirstPass<'src, &'src str> for weedle::interface::InterfaceMember<'sr
|
||||
Ok(())
|
||||
}
|
||||
InterfaceMember::Stringifier(_) => {
|
||||
warn!("Unsupported WebIDL Stringifier interface member: {:?}", self);
|
||||
warn!(
|
||||
"Unsupported WebIDL Stringifier interface member: {:?}",
|
||||
self
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
InterfaceMember::Setlike(_) => {
|
||||
@ -439,11 +448,15 @@ impl<'src> FirstPass<'src, &'src str> for weedle::interface::InterfaceMember<'sr
|
||||
}
|
||||
|
||||
impl<'src> FirstPass<'src, &'src str> for weedle::interface::OperationInterfaceMember<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, self_name: &'src str) -> Result<()> {
|
||||
fn first_pass(
|
||||
&'src self,
|
||||
record: &mut FirstPassRecord<'src>,
|
||||
self_name: &'src str,
|
||||
) -> Result<()> {
|
||||
let is_static = match self.modifier {
|
||||
Some(StringifierOrStatic::Stringifier(_)) => {
|
||||
warn!("Unsupported webidl stringifier: {:?}", self);
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
Some(StringifierOrStatic::Static(_)) => true,
|
||||
None => false,
|
||||
@ -455,7 +468,7 @@ impl<'src> FirstPass<'src, &'src str> for weedle::interface::OperationInterfaceM
|
||||
Special::Getter(_) => ids.push(OperationId::IndexingGetter),
|
||||
Special::Setter(_) => ids.push(OperationId::IndexingSetter),
|
||||
Special::Deleter(_) => ids.push(OperationId::IndexingDeleter),
|
||||
Special::LegacyCaller(_) => {},
|
||||
Special::LegacyCaller(_) => {}
|
||||
};
|
||||
}
|
||||
first_pass_operation(
|
||||
@ -473,12 +486,17 @@ impl<'src> FirstPass<'src, &'src str> for weedle::interface::OperationInterfaceM
|
||||
}
|
||||
|
||||
impl<'src> FirstPass<'src, &'src str> for weedle::interface::AttributeInterfaceMember<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, self_name: &'src str) -> Result<()> {
|
||||
fn first_pass(
|
||||
&'src self,
|
||||
record: &mut FirstPassRecord<'src>,
|
||||
self_name: &'src str,
|
||||
) -> Result<()> {
|
||||
if util::is_chrome_only(&self.attributes) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
record.interfaces
|
||||
record
|
||||
.interfaces
|
||||
.get_mut(self_name)
|
||||
.unwrap()
|
||||
.attributes
|
||||
@ -487,17 +505,14 @@ impl<'src> FirstPass<'src, &'src str> for weedle::interface::AttributeInterfaceM
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> FirstPass<'src, ()> for weedle::InterfaceMixinDefinition<'src>{
|
||||
impl<'src> FirstPass<'src, ()> for weedle::InterfaceMixinDefinition<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, (): ()) -> Result<()> {
|
||||
if util::is_chrome_only(&self.attributes) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
{
|
||||
let mixin_data = record
|
||||
.mixins
|
||||
.entry(self.identifier.0)
|
||||
.or_default();
|
||||
let mixin_data = record.mixins.entry(self.identifier.0).or_default();
|
||||
mixin_data.partial = false;
|
||||
mixin_data.definition_attributes = self.attributes.as_ref();
|
||||
}
|
||||
@ -519,12 +534,10 @@ impl<'src> FirstPass<'src, ()> for weedle::PartialInterfaceMixinDefinition<'src>
|
||||
record
|
||||
.mixins
|
||||
.entry(self.identifier.0)
|
||||
.or_insert_with(||
|
||||
MixinData {
|
||||
partial: true,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
.or_insert_with(|| MixinData {
|
||||
partial: true,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
for member in &self.members.body {
|
||||
member.first_pass(record, self.identifier.0)?;
|
||||
@ -535,7 +548,11 @@ impl<'src> FirstPass<'src, ()> for weedle::PartialInterfaceMixinDefinition<'src>
|
||||
}
|
||||
|
||||
impl<'src> FirstPass<'src, &'src str> for weedle::mixin::MixinMember<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, self_name: &'src str) -> Result<()> {
|
||||
fn first_pass(
|
||||
&'src self,
|
||||
record: &mut FirstPassRecord<'src>,
|
||||
self_name: &'src str,
|
||||
) -> Result<()> {
|
||||
match self {
|
||||
MixinMember::Operation(op) => op.first_pass(record, self_name),
|
||||
MixinMember::Attribute(a) => a.first_pass(record, self_name),
|
||||
@ -543,11 +560,7 @@ impl<'src> FirstPass<'src, &'src str> for weedle::mixin::MixinMember<'src> {
|
||||
if util::is_chrome_only(&a.attributes) {
|
||||
return Ok(());
|
||||
}
|
||||
record.mixins
|
||||
.get_mut(self_name)
|
||||
.unwrap()
|
||||
.consts
|
||||
.push(a);
|
||||
record.mixins.get_mut(self_name).unwrap().consts.push(a);
|
||||
Ok(())
|
||||
}
|
||||
MixinMember::Stringifier(_) => {
|
||||
@ -559,10 +572,14 @@ impl<'src> FirstPass<'src, &'src str> for weedle::mixin::MixinMember<'src> {
|
||||
}
|
||||
|
||||
impl<'src> FirstPass<'src, &'src str> for weedle::mixin::OperationMixinMember<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, self_name: &'src str) -> Result<()> {
|
||||
fn first_pass(
|
||||
&'src self,
|
||||
record: &mut FirstPassRecord<'src>,
|
||||
self_name: &'src str,
|
||||
) -> Result<()> {
|
||||
if self.stringifier.is_some() {
|
||||
warn!("Unsupported webidl stringifier: {:?}", self);
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
first_pass_operation(
|
||||
@ -580,11 +597,16 @@ impl<'src> FirstPass<'src, &'src str> for weedle::mixin::OperationMixinMember<'s
|
||||
}
|
||||
|
||||
impl<'src> FirstPass<'src, &'src str> for weedle::mixin::AttributeMixinMember<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, self_name: &'src str) -> Result<()> {
|
||||
fn first_pass(
|
||||
&'src self,
|
||||
record: &mut FirstPassRecord<'src>,
|
||||
self_name: &'src str,
|
||||
) -> Result<()> {
|
||||
if util::is_chrome_only(&self.attributes) {
|
||||
return Ok(());
|
||||
}
|
||||
record.mixins
|
||||
record
|
||||
.mixins
|
||||
.get_mut(self_name)
|
||||
.unwrap()
|
||||
.attributes
|
||||
@ -599,8 +621,15 @@ impl<'src> FirstPass<'src, ()> for weedle::TypedefDefinition<'src> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if record.typedefs.insert(self.identifier.0, &self.type_.type_).is_some() {
|
||||
info!("Encountered multiple typedef declarations: {}", self.identifier.0);
|
||||
if record
|
||||
.typedefs
|
||||
.insert(self.identifier.0, &self.type_.type_)
|
||||
.is_some()
|
||||
{
|
||||
info!(
|
||||
"Encountered multiple typedef declarations: {}",
|
||||
self.identifier.0
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -610,13 +639,10 @@ impl<'src> FirstPass<'src, ()> for weedle::TypedefDefinition<'src> {
|
||||
impl<'src> FirstPass<'src, ()> for weedle::NamespaceDefinition<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, (): ()) -> Result<()> {
|
||||
if util::is_chrome_only(&self.attributes) {
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
record
|
||||
.namespaces
|
||||
.entry(self.identifier.0)
|
||||
.or_default();
|
||||
record.namespaces.entry(self.identifier.0).or_default();
|
||||
|
||||
for member in &self.members.body {
|
||||
member.first_pass(record, self.identifier.0)?;
|
||||
@ -629,13 +655,10 @@ impl<'src> FirstPass<'src, ()> for weedle::NamespaceDefinition<'src> {
|
||||
impl<'src> FirstPass<'src, ()> for weedle::PartialNamespaceDefinition<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, (): ()) -> Result<()> {
|
||||
if util::is_chrome_only(&self.attributes) {
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
record
|
||||
.namespaces
|
||||
.entry(self.identifier.0)
|
||||
.or_default();
|
||||
record.namespaces.entry(self.identifier.0).or_default();
|
||||
|
||||
for member in &self.members.body {
|
||||
member.first_pass(record, self.identifier.0)?;
|
||||
@ -646,18 +669,24 @@ impl<'src> FirstPass<'src, ()> for weedle::PartialNamespaceDefinition<'src> {
|
||||
}
|
||||
|
||||
impl<'src> FirstPass<'src, &'src str> for weedle::namespace::NamespaceMember<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, self_name: &'src str) -> Result<()> {
|
||||
fn first_pass(
|
||||
&'src self,
|
||||
record: &mut FirstPassRecord<'src>,
|
||||
self_name: &'src str,
|
||||
) -> Result<()> {
|
||||
match self {
|
||||
weedle::namespace::NamespaceMember::Operation(op) => {
|
||||
op.first_pass(record, self_name)
|
||||
}
|
||||
weedle::namespace::NamespaceMember::Operation(op) => op.first_pass(record, self_name),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> FirstPass<'src, &'src str> for weedle::namespace::OperationNamespaceMember<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, self_name: &'src str) -> Result<()> {
|
||||
fn first_pass(
|
||||
&'src self,
|
||||
record: &mut FirstPassRecord<'src>,
|
||||
self_name: &'src str,
|
||||
) -> Result<()> {
|
||||
first_pass_operation(
|
||||
record,
|
||||
FirstPassOperationType::Namespace,
|
||||
@ -682,12 +711,14 @@ impl<'src> FirstPass<'src, ()> for weedle::CallbackDefinition<'src> {
|
||||
impl<'src> FirstPass<'src, ()> for weedle::CallbackInterfaceDefinition<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, _: ()) -> Result<()> {
|
||||
if util::is_chrome_only(&self.attributes) {
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
if self.inheritance.is_some() {
|
||||
warn!("skipping callback interface with inheritance: {}",
|
||||
self.identifier.0);
|
||||
return Ok(())
|
||||
warn!(
|
||||
"skipping callback interface with inheritance: {}",
|
||||
self.identifier.0
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
let data = CallbackInterfaceData {
|
||||
definition: self,
|
||||
@ -699,9 +730,7 @@ impl<'src> FirstPass<'src, ()> for weedle::CallbackInterfaceDefinition<'src> {
|
||||
}
|
||||
|
||||
impl<'a> FirstPassRecord<'a> {
|
||||
pub fn all_superclasses<'me>(&'me self, interface: &str)
|
||||
-> impl Iterator<Item = String> + 'me
|
||||
{
|
||||
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()
|
||||
@ -723,9 +752,10 @@ impl<'a> FirstPassRecord<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn all_mixins<'me>(&'me self, interface: &str)
|
||||
-> impl Iterator<Item = &'me MixinData<'a>> + 'me
|
||||
{
|
||||
pub fn all_mixins<'me>(
|
||||
&'me self,
|
||||
interface: &str,
|
||||
) -> impl Iterator<Item = &'me MixinData<'a>> + 'me {
|
||||
let mut set = Vec::new();
|
||||
self.fill_mixins(interface, interface, &mut set);
|
||||
set.into_iter()
|
||||
@ -752,7 +782,9 @@ impl<'a> FirstPassRecord<'a> {
|
||||
pub struct IgnoreTraits<T>(pub T);
|
||||
|
||||
impl<T> PartialEq for IgnoreTraits<T> {
|
||||
fn eq(&self, _other: &IgnoreTraits<T>) -> bool { true }
|
||||
fn eq(&self, _other: &IgnoreTraits<T>) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Eq for IgnoreTraits<T> {}
|
||||
|
@ -6,7 +6,7 @@ use weedle::term;
|
||||
use weedle::types::*;
|
||||
|
||||
use first_pass::FirstPassRecord;
|
||||
use util::{TypePosition, camel_case_ident, snake_case_ident, shared_ref, option_ty, array};
|
||||
use util::{array, camel_case_ident, option_ty, shared_ref, snake_case_ident, TypePosition};
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
|
||||
pub(crate) enum IdlType<'a> {
|
||||
@ -49,7 +49,10 @@ pub(crate) enum IdlType<'a> {
|
||||
Interface(&'a str),
|
||||
Dictionary(&'a str),
|
||||
Enum(&'a str),
|
||||
CallbackInterface { name: &'a str, single_function: bool },
|
||||
CallbackInterface {
|
||||
name: &'a str,
|
||||
single_function: bool,
|
||||
},
|
||||
|
||||
Nullable(Box<IdlType<'a>>),
|
||||
FrozenArray(Box<IdlType<'a>>),
|
||||
@ -132,13 +135,17 @@ impl<'a> ToIdlType<'a> for NonAnyType<'a> {
|
||||
|
||||
impl<'a> ToIdlType<'a> for SequenceType<'a> {
|
||||
fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option<IdlType<'a>> {
|
||||
Some(IdlType::Sequence(Box::new(self.generics.body.to_idl_type(record)?)))
|
||||
Some(IdlType::Sequence(Box::new(
|
||||
self.generics.body.to_idl_type(record)?,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToIdlType<'a> for FrozenArrayType<'a> {
|
||||
fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option<IdlType<'a>> {
|
||||
Some(IdlType::FrozenArray(Box::new(self.generics.body.to_idl_type(record)?)))
|
||||
Some(IdlType::FrozenArray(Box::new(
|
||||
self.generics.body.to_idl_type(record)?,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,7 +162,9 @@ impl<'a, T: ToIdlType<'a>> ToIdlType<'a> for MayBeNull<T> {
|
||||
|
||||
impl<'a> ToIdlType<'a> for PromiseType<'a> {
|
||||
fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option<IdlType<'a>> {
|
||||
Some(IdlType::Promise(Box::new(self.generics.body.to_idl_type(record)?)))
|
||||
Some(IdlType::Promise(Box::new(
|
||||
self.generics.body.to_idl_type(record)?,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,12 +239,10 @@ impl<'a> ToIdlType<'a> for DoubleType {
|
||||
|
||||
impl<'a> ToIdlType<'a> for RecordType<'a> {
|
||||
fn to_idl_type(&self, record: &FirstPassRecord<'a>) -> Option<IdlType<'a>> {
|
||||
Some(
|
||||
IdlType::Record(
|
||||
Box::new(self.generics.body.0.to_idl_type(record)?),
|
||||
Box::new(self.generics.body.2.to_idl_type(record)?)
|
||||
)
|
||||
)
|
||||
Some(IdlType::Record(
|
||||
Box::new(self.generics.body.0.to_idl_type(record)?),
|
||||
Box::new(self.generics.body.2.to_idl_type(record)?),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,13 +382,9 @@ impl<'a> IdlType<'a> {
|
||||
IdlType::UnsignedLong => dst.push_str("u32"),
|
||||
IdlType::LongLong => dst.push_str("i64"),
|
||||
IdlType::UnsignedLongLong => dst.push_str("u64"),
|
||||
| IdlType::Float
|
||||
| IdlType::UnrestrictedFloat => dst.push_str("f32"),
|
||||
| IdlType::Double
|
||||
| IdlType::UnrestrictedDouble => dst.push_str("f64"),
|
||||
| IdlType::DomString
|
||||
| IdlType::ByteString
|
||||
| IdlType::UsvString => dst.push_str("str"),
|
||||
IdlType::Float | IdlType::UnrestrictedFloat => dst.push_str("f32"),
|
||||
IdlType::Double | IdlType::UnrestrictedDouble => dst.push_str("f64"),
|
||||
IdlType::DomString | IdlType::ByteString | IdlType::UsvString => dst.push_str("str"),
|
||||
IdlType::Object => dst.push_str("object"),
|
||||
IdlType::Symbol => dst.push_str("symbol"),
|
||||
IdlType::Error => dst.push_str("error"),
|
||||
@ -405,32 +408,30 @@ impl<'a> IdlType<'a> {
|
||||
IdlType::Interface(name) => dst.push_str(&snake_case_ident(name)),
|
||||
IdlType::Dictionary(name) => dst.push_str(&snake_case_ident(name)),
|
||||
IdlType::Enum(name) => dst.push_str(&snake_case_ident(name)),
|
||||
IdlType::CallbackInterface { name, .. } => {
|
||||
dst.push_str(&snake_case_ident(name))
|
||||
}
|
||||
IdlType::CallbackInterface { name, .. } => dst.push_str(&snake_case_ident(name)),
|
||||
|
||||
IdlType::Nullable(idl_type) => {
|
||||
dst.push_str("opt_");
|
||||
idl_type.push_snake_case_name(dst);
|
||||
},
|
||||
}
|
||||
IdlType::FrozenArray(idl_type) => {
|
||||
idl_type.push_snake_case_name(dst);
|
||||
dst.push_str("_frozen_array");
|
||||
},
|
||||
}
|
||||
IdlType::Sequence(idl_type) => {
|
||||
idl_type.push_snake_case_name(dst);
|
||||
dst.push_str("_sequence");
|
||||
},
|
||||
}
|
||||
IdlType::Promise(idl_type) => {
|
||||
idl_type.push_snake_case_name(dst);
|
||||
dst.push_str("_promise");
|
||||
},
|
||||
}
|
||||
IdlType::Record(idl_type_from, idl_type_to) => {
|
||||
dst.push_str("record_from_");
|
||||
idl_type_from.push_snake_case_name(dst);
|
||||
dst.push_str("_to_");
|
||||
idl_type_to.push_snake_case_name(dst);
|
||||
},
|
||||
}
|
||||
IdlType::Union(idl_types) => {
|
||||
dst.push_str("union_of_");
|
||||
let mut first = true;
|
||||
@ -442,7 +443,7 @@ impl<'a> IdlType<'a> {
|
||||
}
|
||||
idl_type.push_snake_case_name(dst);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
IdlType::Any => dst.push_str("any"),
|
||||
IdlType::Void => dst.push_str("void"),
|
||||
@ -483,16 +484,13 @@ impl<'a> IdlType<'a> {
|
||||
//
|
||||
// Perhaps one day we'll bind to u64/i64 here, but we need `BigInt`
|
||||
// to see more usage!
|
||||
IdlType::LongLong |
|
||||
IdlType::UnsignedLongLong => Some(ident_ty(raw_ident("f64"))),
|
||||
IdlType::LongLong | IdlType::UnsignedLongLong => Some(ident_ty(raw_ident("f64"))),
|
||||
|
||||
IdlType::Float => Some(ident_ty(raw_ident("f32"))),
|
||||
IdlType::UnrestrictedFloat => Some(ident_ty(raw_ident("f32"))),
|
||||
IdlType::Double => Some(ident_ty(raw_ident("f64"))),
|
||||
IdlType::UnrestrictedDouble => Some(ident_ty(raw_ident("f64"))),
|
||||
| IdlType::DomString
|
||||
| IdlType::ByteString
|
||||
| IdlType::UsvString => match pos {
|
||||
IdlType::DomString | IdlType::ByteString | IdlType::UsvString => match pos {
|
||||
TypePosition::Argument => Some(shared_ref(ident_ty(raw_ident("str")), false)),
|
||||
TypePosition::Return => Some(ident_ty(raw_ident("String"))),
|
||||
},
|
||||
@ -519,7 +517,7 @@ impl<'a> IdlType<'a> {
|
||||
| IdlType::CallbackInterface { name, .. } => {
|
||||
let ty = ident_ty(rust_ident(camel_case_ident(name).as_str()));
|
||||
anyref(ty)
|
||||
},
|
||||
}
|
||||
IdlType::Enum(name) => Some(ident_ty(rust_ident(camel_case_ident(name).as_str()))),
|
||||
|
||||
IdlType::Nullable(idl_type) => {
|
||||
@ -532,11 +530,14 @@ impl<'a> IdlType<'a> {
|
||||
// it's up to users to dispatch and/or create instances
|
||||
// appropriately.
|
||||
if let syn::Type::Path(path) = &inner {
|
||||
if path.qself.is_none() &&
|
||||
path.path.segments.last().map(|p| p.value().ident == "JsValue")
|
||||
.unwrap_or(false)
|
||||
if path.qself.is_none() && path
|
||||
.path
|
||||
.segments
|
||||
.last()
|
||||
.map(|p| p.value().ident == "JsValue")
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return Some(inner.clone())
|
||||
return Some(inner.clone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -570,24 +571,20 @@ impl<'a> IdlType<'a> {
|
||||
// Such an enum, however, might have a relatively high
|
||||
// overhead in creating it from a JS value, but would be
|
||||
// cheap to convert from a variant back to a JS value.
|
||||
if idl_types
|
||||
.iter()
|
||||
.all(|idl_type|
|
||||
match idl_type {
|
||||
IdlType::Interface(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
) {
|
||||
if idl_types.iter().all(|idl_type| match idl_type {
|
||||
IdlType::Interface(..) => true,
|
||||
_ => false,
|
||||
}) {
|
||||
IdlType::Object.to_syn_type(pos)
|
||||
} else {
|
||||
IdlType::Any.to_syn_type(pos)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
IdlType::Any => {
|
||||
let path = vec![rust_ident("wasm_bindgen"), rust_ident("JsValue")];
|
||||
anyref(leading_colon_path_ty(path))
|
||||
},
|
||||
}
|
||||
IdlType::Void => None,
|
||||
IdlType::Callback => js_sys("Function"),
|
||||
}
|
||||
@ -629,33 +626,26 @@ impl<'a> IdlType<'a> {
|
||||
let mut idl_types = Vec::new();
|
||||
for idl_type_from in idl_type_from.flatten() {
|
||||
for idl_type_to in idl_type_to.flatten() {
|
||||
idl_types.push(
|
||||
IdlType::Record(
|
||||
Box::new(idl_type_from.clone()),
|
||||
Box::new(idl_type_to.clone())
|
||||
)
|
||||
);
|
||||
idl_types.push(IdlType::Record(
|
||||
Box::new(idl_type_from.clone()),
|
||||
Box::new(idl_type_to.clone()),
|
||||
));
|
||||
}
|
||||
}
|
||||
idl_types
|
||||
},
|
||||
}
|
||||
IdlType::Union(idl_types) => idl_types
|
||||
.iter()
|
||||
.flat_map(|idl_type| idl_type.flatten())
|
||||
.collect(),
|
||||
IdlType::ArrayBufferView => {
|
||||
vec![IdlType::ArrayBufferView, IdlType::Uint8ArrayMut]
|
||||
}
|
||||
IdlType::BufferSource => {
|
||||
vec![IdlType::BufferSource, IdlType::Uint8ArrayMut]
|
||||
}
|
||||
IdlType::LongLong => {
|
||||
vec![IdlType::Long, IdlType::Double]
|
||||
}
|
||||
IdlType::UnsignedLongLong => {
|
||||
vec![IdlType::UnsignedLong, IdlType::Double]
|
||||
}
|
||||
IdlType::CallbackInterface { name, single_function: true } => {
|
||||
IdlType::ArrayBufferView => vec![IdlType::ArrayBufferView, IdlType::Uint8ArrayMut],
|
||||
IdlType::BufferSource => vec![IdlType::BufferSource, IdlType::Uint8ArrayMut],
|
||||
IdlType::LongLong => vec![IdlType::Long, IdlType::Double],
|
||||
IdlType::UnsignedLongLong => vec![IdlType::UnsignedLong, IdlType::Double],
|
||||
IdlType::CallbackInterface {
|
||||
name,
|
||||
single_function: true,
|
||||
} => {
|
||||
// According to the webidl spec [1] single-function callback
|
||||
// interfaces can also be replaced in arguments with simply a
|
||||
// single callable function, which we map to a `Callback`.
|
||||
@ -663,7 +653,10 @@ impl<'a> IdlType<'a> {
|
||||
// [1]: https://heycam.github.io/webidl/#es-user-objects
|
||||
vec![
|
||||
IdlType::Callback,
|
||||
IdlType::CallbackInterface { name, single_function: false },
|
||||
IdlType::CallbackInterface {
|
||||
name,
|
||||
single_function: false,
|
||||
},
|
||||
]
|
||||
}
|
||||
idl_type @ _ => vec![idl_type.clone()],
|
||||
@ -678,26 +671,15 @@ fn idl_type_flatten_test() {
|
||||
assert_eq!(
|
||||
Union(vec![
|
||||
Interface("Node"),
|
||||
Union(vec![
|
||||
Sequence(
|
||||
Box::new(Long),
|
||||
),
|
||||
Interface("Event"),
|
||||
]),
|
||||
Nullable(
|
||||
Box::new(Union(vec![
|
||||
Interface("XMLHttpRequest"),
|
||||
DomString,
|
||||
])),
|
||||
),
|
||||
Sequence(
|
||||
Box::new(Union(vec![
|
||||
Sequence(
|
||||
Box::new(Double),
|
||||
),
|
||||
Interface("NodeList"),
|
||||
])),
|
||||
),
|
||||
Union(vec![Sequence(Box::new(Long),), Interface("Event"),]),
|
||||
Nullable(Box::new(Union(vec![
|
||||
Interface("XMLHttpRequest"),
|
||||
DomString,
|
||||
])),),
|
||||
Sequence(Box::new(Union(vec![
|
||||
Sequence(Box::new(Double),),
|
||||
Interface("NodeList"),
|
||||
])),),
|
||||
]).flatten(),
|
||||
vec![
|
||||
Interface("Node"),
|
||||
@ -726,10 +708,9 @@ fn clamped(t: syn::Type) -> syn::Type {
|
||||
qself: None,
|
||||
path: syn::Path {
|
||||
leading_colon: Some(Default::default()),
|
||||
segments: vec![
|
||||
Ident::new("wasm_bindgen", Span::call_site()).into(),
|
||||
seg,
|
||||
].into_iter().collect(),
|
||||
segments: vec![Ident::new("wasm_bindgen", Span::call_site()).into(), seg]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
},
|
||||
}.into()
|
||||
}
|
||||
|
@ -24,31 +24,34 @@ extern crate syn;
|
||||
extern crate wasm_bindgen_backend as backend;
|
||||
extern crate weedle;
|
||||
|
||||
mod error;
|
||||
mod first_pass;
|
||||
mod idl_type;
|
||||
mod util;
|
||||
mod error;
|
||||
|
||||
use std::collections::{BTreeSet, HashSet};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use backend::TryToTokens;
|
||||
use backend::ast;
|
||||
use backend::defined::ImportedTypeReferences;
|
||||
use backend::defined::{ImportedTypeDefinitions, RemoveUndefinedImports};
|
||||
use backend::util::{ident_ty, rust_ident, raw_ident, wrap_import_function};
|
||||
use backend::util::{ident_ty, raw_ident, rust_ident, wrap_import_function};
|
||||
use backend::TryToTokens;
|
||||
use proc_macro2::{Ident, Span};
|
||||
use quote::ToTokens;
|
||||
use weedle::attribute::{ExtendedAttributeList};
|
||||
use weedle::attribute::ExtendedAttributeList;
|
||||
use weedle::dictionary::DictionaryMember;
|
||||
use weedle::interface::InterfaceMember;
|
||||
|
||||
use first_pass::{FirstPass, FirstPassRecord, OperationId, InterfaceData};
|
||||
use first_pass::{OperationData, CallbackInterfaceData};
|
||||
use util::{public, webidl_const_v_to_backend_const_v, TypePosition, camel_case_ident, shouty_snake_case_ident, snake_case_ident, mdn_doc};
|
||||
use first_pass::{CallbackInterfaceData, OperationData};
|
||||
use first_pass::{FirstPass, FirstPassRecord, InterfaceData, OperationId};
|
||||
use idl_type::ToIdlType;
|
||||
use util::{
|
||||
camel_case_ident, mdn_doc, public, shouty_snake_case_ident, snake_case_ident,
|
||||
webidl_const_v_to_backend_const_v, TypePosition,
|
||||
};
|
||||
|
||||
pub use error::{Error, ErrorKind, Result};
|
||||
|
||||
@ -58,25 +61,22 @@ struct Program {
|
||||
}
|
||||
|
||||
/// Parse a string of WebIDL source text into a wasm-bindgen AST.
|
||||
fn parse(webidl_source: &str, allowed_types: Option<&[&str]>)
|
||||
-> Result<Program>
|
||||
{
|
||||
fn parse(webidl_source: &str, allowed_types: Option<&[&str]>) -> Result<Program> {
|
||||
let definitions = match weedle::parse(webidl_source) {
|
||||
Ok(def) => def,
|
||||
Err(e) => {
|
||||
return Err(match &e {
|
||||
weedle::Err::Incomplete(needed) => {
|
||||
format_err!("needed {:?} more bytes", needed)
|
||||
.context(ErrorKind::ParsingWebIDLSource).into()
|
||||
}
|
||||
weedle::Err::Error(cx) |
|
||||
weedle::Err::Failure(cx) => {
|
||||
weedle::Err::Incomplete(needed) => format_err!("needed {:?} more bytes", needed)
|
||||
.context(ErrorKind::ParsingWebIDLSource)
|
||||
.into(),
|
||||
weedle::Err::Error(cx) | weedle::Err::Failure(cx) => {
|
||||
let remaining = match cx {
|
||||
weedle::Context::Code(remaining, _) => remaining,
|
||||
};
|
||||
let pos = webidl_source.len() - remaining.len();
|
||||
format_err!("failed to parse WebIDL")
|
||||
.context(ErrorKind::ParsingWebIDLSourcePos(pos)).into()
|
||||
.context(ErrorKind::ParsingWebIDLSourcePos(pos))
|
||||
.into()
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -88,14 +88,10 @@ fn parse(webidl_source: &str, allowed_types: Option<&[&str]>)
|
||||
let mut program = Default::default();
|
||||
let mut submodules = Vec::new();
|
||||
|
||||
let allowed_types = allowed_types.map(|list| {
|
||||
list.iter().cloned().collect::<HashSet<_>>()
|
||||
});
|
||||
let filter = |name: &str| {
|
||||
match &allowed_types {
|
||||
Some(set) => set.contains(name),
|
||||
None => true,
|
||||
}
|
||||
let allowed_types = allowed_types.map(|list| list.iter().cloned().collect::<HashSet<_>>());
|
||||
let filter = |name: &str| match &allowed_types {
|
||||
Some(set) => set.contains(name),
|
||||
None => true,
|
||||
};
|
||||
|
||||
for (name, e) in first_pass_record.enums.iter() {
|
||||
@ -130,10 +126,8 @@ fn parse(webidl_source: &str, allowed_types: Option<&[&str]>)
|
||||
// `AsRef` and such implementations.
|
||||
for import in program.imports.iter_mut() {
|
||||
if let backend::ast::ImportKind::Type(t) = &mut import.kind {
|
||||
t.extends.retain(|n| {
|
||||
first_pass_record.builtin_idents.contains(n) ||
|
||||
filter(&n.to_string())
|
||||
});
|
||||
t.extends
|
||||
.retain(|n| first_pass_record.builtin_idents.contains(n) || filter(&n.to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,10 +139,7 @@ fn parse(webidl_source: &str, allowed_types: Option<&[&str]>)
|
||||
|
||||
/// Compile the given WebIDL source text into Rust source text containing
|
||||
/// `wasm-bindgen` bindings to the things described in the WebIDL.
|
||||
pub fn compile(
|
||||
webidl_source: &str,
|
||||
allowed_types: Option<&[&str]>,
|
||||
) -> Result<String> {
|
||||
pub fn compile(webidl_source: &str, allowed_types: Option<&[&str]>) -> Result<String> {
|
||||
let ast = parse(webidl_source, allowed_types)?;
|
||||
Ok(compile_ast(ast))
|
||||
}
|
||||
@ -156,11 +147,34 @@ pub fn compile(
|
||||
fn builtin_idents() -> BTreeSet<Ident> {
|
||||
BTreeSet::from_iter(
|
||||
vec![
|
||||
"str", "char", "bool", "JsValue", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64",
|
||||
"usize", "isize", "f32", "f64", "Result", "String", "Vec", "Option",
|
||||
"Array", "ArrayBuffer", "Object", "Promise", "Function", "Clamped",
|
||||
"str",
|
||||
"char",
|
||||
"bool",
|
||||
"JsValue",
|
||||
"u8",
|
||||
"i8",
|
||||
"u16",
|
||||
"i16",
|
||||
"u32",
|
||||
"i32",
|
||||
"u64",
|
||||
"i64",
|
||||
"usize",
|
||||
"isize",
|
||||
"f32",
|
||||
"f64",
|
||||
"Result",
|
||||
"String",
|
||||
"Vec",
|
||||
"Option",
|
||||
"Array",
|
||||
"ArrayBuffer",
|
||||
"Object",
|
||||
"Promise",
|
||||
"Function",
|
||||
"Clamped",
|
||||
].into_iter()
|
||||
.map(|id| proc_macro2::Ident::new(id, proc_macro2::Span::call_site())),
|
||||
.map(|id| proc_macro2::Ident::new(id, proc_macro2::Span::call_site())),
|
||||
)
|
||||
}
|
||||
|
||||
@ -188,17 +202,20 @@ fn compile_ast(mut ast: Program) -> String {
|
||||
m.imported_type_references(&mut cb);
|
||||
}
|
||||
}
|
||||
let changed =
|
||||
ast.main.remove_undefined_imports(&|id| defined.contains(id)) ||
|
||||
ast.submodules.iter_mut().any(|(_, m)| {
|
||||
m.remove_undefined_imports(&|id| defined.contains(id))
|
||||
});
|
||||
let changed = ast
|
||||
.main
|
||||
.remove_undefined_imports(&|id| defined.contains(id))
|
||||
|| ast
|
||||
.submodules
|
||||
.iter_mut()
|
||||
.any(|(_, m)| m.remove_undefined_imports(&|id| defined.contains(id)));
|
||||
if !changed {
|
||||
break
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Some(path) = track {
|
||||
let contents = all_definitions.into_iter()
|
||||
let contents = all_definitions
|
||||
.into_iter()
|
||||
.filter(|def| !builtin.contains(def))
|
||||
.map(|s| format!("{} = []", s))
|
||||
.collect::<Vec<_>>()
|
||||
@ -229,7 +246,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
fn append_enum(
|
||||
&self,
|
||||
program: &mut backend::ast::Program,
|
||||
enum_: &'src weedle::EnumDefinition<'src>
|
||||
enum_: &'src weedle::EnumDefinition<'src>,
|
||||
) {
|
||||
let variants = &enum_.values.body.list;
|
||||
program.imports.push(backend::ast::Import {
|
||||
@ -246,8 +263,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
} else {
|
||||
rust_ident("None")
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
}).collect(),
|
||||
variant_values: variants.iter().map(|v| v.0.to_string()).collect(),
|
||||
rust_attrs: vec![parse_quote!(#[derive(Copy, Clone, PartialEq, Debug)])],
|
||||
}),
|
||||
@ -267,7 +283,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
};
|
||||
let mut fields = Vec::new();
|
||||
if !self.append_dictionary_members(def.identifier.0, &mut fields) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
program.dictionaries.push(ast::Dictionary {
|
||||
@ -289,7 +305,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
// > non-inherited members ...
|
||||
if let Some(parent) = &definition.inheritance {
|
||||
if !self.append_dictionary_members(parent.identifier.0, dst) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -313,7 +329,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
// avoid generating bindings for the field and keep
|
||||
// going otherwise.
|
||||
if member.required.is_some() {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -324,7 +340,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
// now!
|
||||
dst[start..].sort_by_key(|f| f.name.clone());
|
||||
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
|
||||
fn dictionary_field(
|
||||
@ -332,31 +348,35 @@ impl<'src> FirstPassRecord<'src> {
|
||||
field: &'src DictionaryMember<'src>,
|
||||
) -> Option<ast::DictionaryField> {
|
||||
// use argument position now as we're just binding setters
|
||||
let ty = field.type_.to_idl_type(self)?.to_syn_type(TypePosition::Argument)?;
|
||||
let ty = field
|
||||
.type_
|
||||
.to_idl_type(self)?
|
||||
.to_syn_type(TypePosition::Argument)?;
|
||||
|
||||
// Slice types aren't supported because they don't implement
|
||||
// `Into<JsValue>`
|
||||
match ty {
|
||||
syn::Type::Reference(ref i) =>
|
||||
match &*i.elem {
|
||||
syn::Type::Slice(_) => return None,
|
||||
_ => ()
|
||||
}
|
||||
syn::Type::Reference(ref i) => match &*i.elem {
|
||||
syn::Type::Slice(_) => return None,
|
||||
_ => (),
|
||||
},
|
||||
syn::Type::Path(ref path, ..) =>
|
||||
// check that our inner don't contains slices either
|
||||
// check that our inner don't contains slices either
|
||||
{
|
||||
for seg in path.path.segments.iter() {
|
||||
if let syn::PathArguments::AngleBracketed(ref arg) = seg.arguments {
|
||||
for elem in &arg.args {
|
||||
if let syn::GenericArgument::Type(syn::Type::Reference(ref i)) = elem {
|
||||
match &*i.elem {
|
||||
syn::Type::Slice(_) => return None,
|
||||
_ => ()
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
|
||||
// Similarly i64/u64 aren't supported because they don't
|
||||
@ -366,7 +386,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
any_64bit = any_64bit || i == "u64" || i == "i64";
|
||||
});
|
||||
if any_64bit {
|
||||
return None
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(ast::DictionaryField {
|
||||
@ -387,7 +407,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
self.append_ns_member(&mut ret, name, id, data);
|
||||
}
|
||||
|
||||
return ret
|
||||
return ret;
|
||||
}
|
||||
|
||||
fn append_ns_member(
|
||||
@ -399,13 +419,13 @@ impl<'src> FirstPassRecord<'src> {
|
||||
) {
|
||||
let name = match id {
|
||||
OperationId::Operation(Some(name)) => name,
|
||||
OperationId::Constructor(_) |
|
||||
OperationId::Operation(None) |
|
||||
OperationId::IndexingGetter |
|
||||
OperationId::IndexingSetter |
|
||||
OperationId::IndexingDeleter => {
|
||||
OperationId::Constructor(_)
|
||||
| OperationId::Operation(None)
|
||||
| OperationId::IndexingGetter
|
||||
| OperationId::IndexingSetter
|
||||
| OperationId::IndexingDeleter => {
|
||||
warn!("Unsupported unnamed operation: on {:?}", self_name);
|
||||
return
|
||||
return;
|
||||
}
|
||||
};
|
||||
let doc_comment = format!(
|
||||
@ -422,13 +442,11 @@ impl<'src> FirstPassRecord<'src> {
|
||||
let mut doc = Some(doc_comment.clone());
|
||||
self.append_required_features_doc(&import_function, &mut doc, extra);
|
||||
import_function.doc_comment = doc;
|
||||
module.imports.push(
|
||||
backend::ast::Import {
|
||||
module: None,
|
||||
js_namespace: Some(raw_ident(self_name)),
|
||||
kind: backend::ast::ImportKind::Function(import_function),
|
||||
}
|
||||
);
|
||||
module.imports.push(backend::ast::Import {
|
||||
module: None,
|
||||
js_namespace: Some(raw_ident(self_name)),
|
||||
kind: backend::ast::ImportKind::Function(import_function),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,12 +466,10 @@ impl<'src> FirstPassRecord<'src> {
|
||||
None => {
|
||||
warn!(
|
||||
"Cannot convert const type to syn type: {:?} in {:?} on {:?}",
|
||||
idl_type,
|
||||
member,
|
||||
self_name
|
||||
idl_type, member, self_name
|
||||
);
|
||||
return
|
||||
},
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
program.consts.push(backend::ast::Const {
|
||||
@ -471,11 +487,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
name: &'src str,
|
||||
data: &InterfaceData<'src>,
|
||||
) {
|
||||
let mut doc_comment = Some(format!(
|
||||
"The `{}` object\n\n{}",
|
||||
name,
|
||||
mdn_doc(name, None),
|
||||
));
|
||||
let mut doc_comment = Some(format!("The `{}` object\n\n{}", name, mdn_doc(name, None),));
|
||||
let derive = syn::Attribute {
|
||||
pound_token: Default::default(),
|
||||
style: syn::AttrStyle::Outer,
|
||||
@ -495,10 +507,11 @@ impl<'src> FirstPassRecord<'src> {
|
||||
let extra = camel_case_ident(name);
|
||||
let extra = &[&extra[..]];
|
||||
self.append_required_features_doc(&import_type, &mut doc_comment, extra);
|
||||
import_type.extends = self.all_superclasses(name)
|
||||
.map(|name| Ident::new(&name, Span::call_site()))
|
||||
.chain(Some(Ident::new("Object", Span::call_site())))
|
||||
.collect();
|
||||
import_type.extends = self
|
||||
.all_superclasses(name)
|
||||
.map(|name| Ident::new(&name, Span::call_site()))
|
||||
.chain(Some(Ident::new("Object", Span::call_site())))
|
||||
.collect();
|
||||
import_type.doc_comment = doc_comment;
|
||||
|
||||
program.imports.push(backend::ast::Import {
|
||||
@ -611,9 +624,8 @@ impl<'src> FirstPassRecord<'src> {
|
||||
id: &OperationId<'src>,
|
||||
op_data: &OperationData<'src>,
|
||||
) {
|
||||
let import_function_kind = |opkind| {
|
||||
self.import_function_kind(self_name, op_data.is_static, opkind)
|
||||
};
|
||||
let import_function_kind =
|
||||
|opkind| self.import_function_kind(self_name, op_data.is_static, opkind);
|
||||
let kind = match id {
|
||||
OperationId::Constructor(ctor_name) => {
|
||||
let self_ty = ident_ty(rust_ident(&camel_case_ident(self_name)));
|
||||
@ -623,9 +635,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
kind: backend::ast::MethodKind::Constructor,
|
||||
}
|
||||
}
|
||||
OperationId::Operation(_) => {
|
||||
import_function_kind(backend::ast::OperationKind::Regular)
|
||||
}
|
||||
OperationId::Operation(_) => import_function_kind(backend::ast::OperationKind::Regular),
|
||||
OperationId::IndexingGetter => {
|
||||
import_function_kind(backend::ast::OperationKind::IndexingGetter)
|
||||
}
|
||||
@ -637,24 +647,15 @@ impl<'src> FirstPassRecord<'src> {
|
||||
}
|
||||
};
|
||||
let doc = match id {
|
||||
OperationId::Constructor(_) |
|
||||
OperationId::Operation(None) => Some(String::new()),
|
||||
OperationId::Operation(Some(name)) => {
|
||||
Some(format!(
|
||||
"The `{}()` method\n\n{}",
|
||||
name,
|
||||
mdn_doc(self_name, Some(name))
|
||||
))
|
||||
}
|
||||
OperationId::IndexingGetter => {
|
||||
Some(format!("The indexing getter\n\n"))
|
||||
}
|
||||
OperationId::IndexingSetter => {
|
||||
Some(format!("The indexing setter\n\n"))
|
||||
}
|
||||
OperationId::IndexingDeleter => {
|
||||
Some(format!("The indexing deleter\n\n"))
|
||||
}
|
||||
OperationId::Constructor(_) | OperationId::Operation(None) => Some(String::new()),
|
||||
OperationId::Operation(Some(name)) => Some(format!(
|
||||
"The `{}()` method\n\n{}",
|
||||
name,
|
||||
mdn_doc(self_name, Some(name))
|
||||
)),
|
||||
OperationId::IndexingGetter => Some(format!("The indexing getter\n\n")),
|
||||
OperationId::IndexingSetter => Some(format!("The indexing setter\n\n")),
|
||||
OperationId::IndexingDeleter => Some(format!("The indexing deleter\n\n")),
|
||||
};
|
||||
let attrs = data.definition_attributes;
|
||||
for mut method in self.create_imports(attrs, kind, id, op_data) {
|
||||
@ -675,7 +676,8 @@ impl<'src> FirstPassRecord<'src> {
|
||||
Some(doc) => doc,
|
||||
None => return,
|
||||
};
|
||||
let mut required = extra.iter()
|
||||
let mut required = extra
|
||||
.iter()
|
||||
.map(|s| Ident::new(s, Span::call_site()))
|
||||
.collect::<BTreeSet<_>>();
|
||||
item.imported_type_references(&mut |f| {
|
||||
@ -684,9 +686,10 @@ impl<'src> FirstPassRecord<'src> {
|
||||
}
|
||||
});
|
||||
if required.len() == 0 {
|
||||
return
|
||||
return;
|
||||
}
|
||||
let list = required.iter()
|
||||
let list = required
|
||||
.iter()
|
||||
.map(|ident| format!("`{}`", ident))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
@ -714,13 +717,14 @@ impl<'src> FirstPassRecord<'src> {
|
||||
fields.push(ast::DictionaryField {
|
||||
required: false,
|
||||
name: rust_ident(&snake_case_ident(identifier)),
|
||||
ty: idl_type::IdlType::Callback.to_syn_type(pos)
|
||||
.unwrap(),
|
||||
ty: idl_type::IdlType::Callback.to_syn_type(pos).unwrap(),
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
warn!("skipping callback interface member on {}",
|
||||
item.definition.identifier.0);
|
||||
warn!(
|
||||
"skipping callback interface member on {}",
|
||||
item.definition.identifier.0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,10 @@ use heck::{CamelCase, ShoutySnakeCase, SnakeCase};
|
||||
use proc_macro2::{Ident, Span};
|
||||
use syn;
|
||||
use weedle;
|
||||
use weedle::attribute::{ExtendedAttributeList, ExtendedAttribute};
|
||||
use weedle::attribute::{ExtendedAttribute, ExtendedAttributeList};
|
||||
use weedle::literal::{ConstValue, FloatLit, IntegerLit};
|
||||
|
||||
use first_pass::{FirstPassRecord, OperationId, OperationData, Signature};
|
||||
use first_pass::{FirstPassRecord, OperationData, OperationId, Signature};
|
||||
use idl_type::{IdlType, ToIdlType};
|
||||
|
||||
/// For variadic operations an overload with a `js_sys::Array` argument is generated alongside with
|
||||
@ -24,7 +24,11 @@ pub(crate) fn shared_ref(ty: syn::Type, mutable: bool) -> syn::Type {
|
||||
syn::TypeReference {
|
||||
and_token: Default::default(),
|
||||
lifetime: None,
|
||||
mutability: if mutable { Some(syn::token::Mut::default()) } else { None },
|
||||
mutability: if mutable {
|
||||
Some(syn::token::Mut::default())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
elem: Box::new(ty),
|
||||
}.into()
|
||||
}
|
||||
@ -66,30 +70,25 @@ pub fn mdn_doc(class: &str, method: Option<&str>) -> String {
|
||||
pub(crate) fn array(base_ty: &str, pos: TypePosition) -> syn::Type {
|
||||
match pos {
|
||||
TypePosition::Argument => {
|
||||
shared_ref(slice_ty(ident_ty(raw_ident(base_ty))), /*mutable =*/ true)
|
||||
}
|
||||
TypePosition::Return => {
|
||||
vec_ty(ident_ty(raw_ident(base_ty)))
|
||||
shared_ref(
|
||||
slice_ty(ident_ty(raw_ident(base_ty))),
|
||||
/*mutable =*/ true,
|
||||
)
|
||||
}
|
||||
TypePosition::Return => vec_ty(ident_ty(raw_ident(base_ty))),
|
||||
}
|
||||
}
|
||||
|
||||
/// Map a webidl const value to the correct wasm-bindgen const value
|
||||
pub fn webidl_const_v_to_backend_const_v(v: &ConstValue) -> backend::ast::ConstValue {
|
||||
use std::f64::{NEG_INFINITY, INFINITY, NAN};
|
||||
use backend::ast;
|
||||
use std::f64::{INFINITY, NAN, NEG_INFINITY};
|
||||
|
||||
match *v {
|
||||
ConstValue::Boolean(b) => ast::ConstValue::BooleanLiteral(b.0),
|
||||
ConstValue::Float(FloatLit::NegInfinity(_)) => {
|
||||
ast::ConstValue::FloatLiteral(NEG_INFINITY)
|
||||
}
|
||||
ConstValue::Float(FloatLit::Infinity(_)) => {
|
||||
ast::ConstValue::FloatLiteral(INFINITY)
|
||||
}
|
||||
ConstValue::Float(FloatLit::NaN(_)) => {
|
||||
ast::ConstValue::FloatLiteral(NAN)
|
||||
}
|
||||
ConstValue::Float(FloatLit::NegInfinity(_)) => ast::ConstValue::FloatLiteral(NEG_INFINITY),
|
||||
ConstValue::Float(FloatLit::Infinity(_)) => ast::ConstValue::FloatLiteral(INFINITY),
|
||||
ConstValue::Float(FloatLit::NaN(_)) => ast::ConstValue::FloatLiteral(NAN),
|
||||
ConstValue::Float(FloatLit::Value(s)) => {
|
||||
ast::ConstValue::FloatLiteral(s.0.parse().unwrap())
|
||||
}
|
||||
@ -101,7 +100,7 @@ pub fn webidl_const_v_to_backend_const_v(v: &ConstValue) -> backend::ast::ConstV
|
||||
(false, orig_text)
|
||||
};
|
||||
if text == "0" {
|
||||
return ast::ConstValue::SignedIntegerLiteral(0)
|
||||
return ast::ConstValue::SignedIntegerLiteral(0);
|
||||
}
|
||||
let text = &text[offset..];
|
||||
let n = u64::from_str_radix(text, base)
|
||||
@ -119,7 +118,7 @@ pub fn webidl_const_v_to_backend_const_v(v: &ConstValue) -> backend::ast::ConstV
|
||||
};
|
||||
match lit {
|
||||
IntegerLit::Hex(h) => mklit(h.0, 16, 2), // leading 0x
|
||||
IntegerLit::Oct(h) => mklit(h.0, 8, 1), // leading 0
|
||||
IntegerLit::Oct(h) => mklit(h.0, 8, 1), // leading 0
|
||||
IntegerLit::Dec(h) => mklit(h.0, 10, 0),
|
||||
}
|
||||
}
|
||||
@ -183,9 +182,7 @@ pub(crate) fn vec_ty(t: syn::Type) -> syn::Type {
|
||||
let arguments = syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments {
|
||||
colon2_token: None,
|
||||
lt_token: Default::default(),
|
||||
args: FromIterator::from_iter(vec![
|
||||
syn::GenericArgument::Type(t),
|
||||
]),
|
||||
args: FromIterator::from_iter(vec![syn::GenericArgument::Type(t)]),
|
||||
gt_token: Default::default(),
|
||||
});
|
||||
|
||||
@ -231,7 +228,10 @@ impl<'src> FirstPassRecord<'src> {
|
||||
catch: bool,
|
||||
variadic: bool,
|
||||
doc_comment: Option<String>,
|
||||
) -> Option<backend::ast::ImportFunction> where 'src: 'a {
|
||||
) -> Option<backend::ast::ImportFunction>
|
||||
where
|
||||
'src: 'a,
|
||||
{
|
||||
// Convert all of the arguments from their IDL type to a `syn` type,
|
||||
// ready to pass to the backend.
|
||||
//
|
||||
@ -239,15 +239,18 @@ impl<'src> FirstPassRecord<'src> {
|
||||
// but this type isn't actually used so it's just here for show mostly.
|
||||
let mut arguments = if let &backend::ast::ImportFunctionKind::Method {
|
||||
ref ty,
|
||||
kind: backend::ast::MethodKind::Operation(
|
||||
backend::ast::Operation {
|
||||
kind:
|
||||
backend::ast::MethodKind::Operation(backend::ast::Operation {
|
||||
is_static: false, ..
|
||||
}
|
||||
),
|
||||
}),
|
||||
..
|
||||
} = &kind {
|
||||
} = &kind
|
||||
{
|
||||
let mut res = Vec::with_capacity(idl_arguments.size_hint().0 + 1);
|
||||
res.push(simple_fn_arg(raw_ident("self_"), shared_ref(ty.clone(), false)));
|
||||
res.push(simple_fn_arg(
|
||||
raw_ident("self_"),
|
||||
shared_ref(ty.clone(), false),
|
||||
));
|
||||
res
|
||||
} else {
|
||||
Vec::with_capacity(idl_arguments.size_hint().0)
|
||||
@ -260,10 +263,9 @@ impl<'src> FirstPassRecord<'src> {
|
||||
None => {
|
||||
warn!(
|
||||
"Unsupported argument type: {:?} on {:?}",
|
||||
idl_type,
|
||||
rust_name
|
||||
idl_type, rust_name
|
||||
);
|
||||
return None
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let syn_type = if variadic && i == arguments_count - 1 {
|
||||
@ -280,17 +282,11 @@ impl<'src> FirstPassRecord<'src> {
|
||||
// attribute here to use a `Result` in Rust.
|
||||
let ret = match ret {
|
||||
IdlType::Void => None,
|
||||
ret @ _ => {
|
||||
match ret.to_syn_type(TypePosition::Return) {
|
||||
Some(ret) => Some(ret),
|
||||
None => {
|
||||
warn!(
|
||||
"Unsupported return type: {:?} on {:?}",
|
||||
ret,
|
||||
rust_name
|
||||
);
|
||||
return None
|
||||
}
|
||||
ret @ _ => match ret.to_syn_type(TypePosition::Return) {
|
||||
Some(ret) => Some(ret),
|
||||
None => {
|
||||
warn!("Unsupported return type: {:?} on {:?}", ret, rust_name);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
};
|
||||
@ -350,7 +346,11 @@ impl<'src> FirstPassRecord<'src> {
|
||||
is_structural(attrs.as_ref(), container_attrs),
|
||||
throws(attrs),
|
||||
false,
|
||||
Some(format!("The `{}` getter\n\n{}", name, mdn_doc(self_name, Some(name)))),
|
||||
Some(format!(
|
||||
"The `{}` getter\n\n{}",
|
||||
name,
|
||||
mdn_doc(self_name, Some(name))
|
||||
)),
|
||||
)
|
||||
}
|
||||
|
||||
@ -376,7 +376,11 @@ impl<'src> FirstPassRecord<'src> {
|
||||
is_structural(attrs.as_ref(), container_attrs),
|
||||
throws(attrs),
|
||||
false,
|
||||
Some(format!("The `{}` setter\n\n{}", name, mdn_doc(self_name, Some(name)))),
|
||||
Some(format!(
|
||||
"The `{}` setter\n\n{}",
|
||||
name,
|
||||
mdn_doc(self_name, Some(name))
|
||||
)),
|
||||
)
|
||||
}
|
||||
|
||||
@ -404,9 +408,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
kind: backend::ast::ImportFunctionKind,
|
||||
id: &OperationId<'src>,
|
||||
data: &OperationData<'src>,
|
||||
)
|
||||
-> Vec<backend::ast::ImportFunction>
|
||||
{
|
||||
) -> Vec<backend::ast::ImportFunction> {
|
||||
// First up, prune all signatures that reference unsupported arguments.
|
||||
// We won't consider these until said arguments are implemented.
|
||||
//
|
||||
@ -416,14 +418,12 @@ impl<'src> FirstPassRecord<'src> {
|
||||
// signature where that and all remaining optional arguments are
|
||||
// undefined.
|
||||
let mut signatures = Vec::new();
|
||||
'outer:
|
||||
for signature in data.signatures.iter() {
|
||||
'outer: for signature in data.signatures.iter() {
|
||||
let mut idl_args = Vec::with_capacity(signature.args.len());
|
||||
for (i, arg) in signature.args.iter().enumerate() {
|
||||
if arg.optional {
|
||||
assert!(
|
||||
signature
|
||||
.args[i..]
|
||||
signature.args[i..]
|
||||
.iter()
|
||||
.all(|arg| arg.optional || arg.variadic),
|
||||
"Not optional or variadic argument after optional argument: {:?}",
|
||||
@ -503,7 +503,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
OperationId::Operation(Some(s)) => (*s, false, false),
|
||||
OperationId::Operation(None) => {
|
||||
warn!("unsupported unnamed operation");
|
||||
return Vec::new()
|
||||
return Vec::new();
|
||||
}
|
||||
OperationId::IndexingGetter => ("get", true, false),
|
||||
OperationId::IndexingSetter => ("set", true, false),
|
||||
@ -551,7 +551,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
// then there's nothing to disambiguate so we don't modify the
|
||||
// name.
|
||||
if !any_different {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
if first {
|
||||
rust_name.push_str("_with_");
|
||||
@ -574,46 +574,58 @@ impl<'src> FirstPassRecord<'src> {
|
||||
rust_name.push_str(&snake_case_ident(arg_name));
|
||||
}
|
||||
}
|
||||
let structural = force_structural || is_structural(signature.orig.attrs.as_ref(), container_attrs);
|
||||
let structural =
|
||||
force_structural || is_structural(signature.orig.attrs.as_ref(), container_attrs);
|
||||
let catch = force_throws || throws(&signature.orig.attrs);
|
||||
let variadic = signature.args.len() == signature.orig.args.len()
|
||||
&& signature.orig.args.last().map(|arg| arg.variadic).unwrap_or(false);
|
||||
ret.extend(self.create_one_function(
|
||||
name,
|
||||
&rust_name,
|
||||
signature.args.iter()
|
||||
.zip(&signature.orig.args)
|
||||
.map(|(idl_type, orig_arg)| (orig_arg.name, idl_type)),
|
||||
&ret_ty,
|
||||
kind.clone(),
|
||||
structural,
|
||||
catch,
|
||||
variadic,
|
||||
None,
|
||||
));
|
||||
let variadic = signature.args.len() == signature.orig.args.len() && signature
|
||||
.orig
|
||||
.args
|
||||
.last()
|
||||
.map(|arg| arg.variadic)
|
||||
.unwrap_or(false);
|
||||
ret.extend(
|
||||
self.create_one_function(
|
||||
name,
|
||||
&rust_name,
|
||||
signature
|
||||
.args
|
||||
.iter()
|
||||
.zip(&signature.orig.args)
|
||||
.map(|(idl_type, orig_arg)| (orig_arg.name, idl_type)),
|
||||
&ret_ty,
|
||||
kind.clone(),
|
||||
structural,
|
||||
catch,
|
||||
variadic,
|
||||
None,
|
||||
),
|
||||
);
|
||||
if !variadic {
|
||||
continue;
|
||||
}
|
||||
let last_idl_type = &signature.args[signature.args.len() - 1];
|
||||
let last_name = signature.orig.args[signature.args.len() - 1].name;
|
||||
for i in 0..=MAX_VARIADIC_ARGUMENTS_COUNT {
|
||||
ret.extend(self.create_one_function(
|
||||
name,
|
||||
&format!("{}_{}", rust_name, i),
|
||||
signature.args[..signature.args.len() - 1].iter()
|
||||
.zip(&signature.orig.args)
|
||||
.map(|(idl_type, orig_arg)| (orig_arg.name.to_string(), idl_type))
|
||||
.chain((1..=i).map(|j| (format!("{}_{}", last_name, j), last_idl_type)))
|
||||
.collect::<Vec<_>>()
|
||||
.iter()
|
||||
.map(|(name, idl_type)| (&name[..], idl_type.clone())),
|
||||
&ret_ty,
|
||||
kind.clone(),
|
||||
structural,
|
||||
catch,
|
||||
false,
|
||||
None,
|
||||
));
|
||||
ret.extend(
|
||||
self.create_one_function(
|
||||
name,
|
||||
&format!("{}_{}", rust_name, i),
|
||||
signature.args[..signature.args.len() - 1]
|
||||
.iter()
|
||||
.zip(&signature.orig.args)
|
||||
.map(|(idl_type, orig_arg)| (orig_arg.name.to_string(), idl_type))
|
||||
.chain((1..=i).map(|j| (format!("{}_{}", last_name, j), last_idl_type)))
|
||||
.collect::<Vec<_>>()
|
||||
.iter()
|
||||
.map(|(name, idl_type)| (&name[..], idl_type.clone())),
|
||||
&ret_ty,
|
||||
kind.clone(),
|
||||
structural,
|
||||
catch,
|
||||
false,
|
||||
None,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -659,9 +671,9 @@ pub fn is_structural(
|
||||
item_attrs: Option<&ExtendedAttributeList>,
|
||||
container_attrs: Option<&ExtendedAttributeList>,
|
||||
) -> bool {
|
||||
has_named_attribute(item_attrs, "Unforgeable") ||
|
||||
has_named_attribute(container_attrs, "Unforgeable") ||
|
||||
has_ident_attribute(container_attrs, "Global")
|
||||
has_named_attribute(item_attrs, "Unforgeable")
|
||||
|| has_named_attribute(container_attrs, "Unforgeable")
|
||||
|| has_ident_attribute(container_attrs, "Global")
|
||||
}
|
||||
|
||||
/// Whether a webidl object is marked as throwing.
|
||||
|
Reference in New Issue
Block a user