cargo +nightly fmt --all

Rustfmt all the things!
This commit is contained in:
Alex Crichton
2018-09-26 08:26:00 -07:00
parent a3e160744e
commit 7ecf4aae87
163 changed files with 2975 additions and 1998 deletions

View File

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

View File

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

View File

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

View File

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

View File

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