mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2025-01-02 08:33:05 +03:00
Migrate constructors to new naming scheme
This commit is contained in:
parent
5a4a34d4a1
commit
923abc7d85
@ -7,6 +7,7 @@
|
||||
//! Only `interface`s, `dictionary`s, `enum`s and `mixin`s can
|
||||
//! be partial.
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use weedle::{DictionaryDefinition, PartialDictionaryDefinition};
|
||||
@ -80,7 +81,7 @@ pub(crate) struct DictionaryData<'src> {
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
|
||||
pub(crate) enum OperationId<'src> {
|
||||
Constructor,
|
||||
Constructor(IgnoreTraits<&'src str>),
|
||||
Operation(Option<&'src str>),
|
||||
IndexingGetter,
|
||||
IndexingSetter,
|
||||
@ -363,7 +364,7 @@ fn process_interface_attribute<'src>(
|
||||
record,
|
||||
FirstPassOperationType::Interface,
|
||||
self_name,
|
||||
&[OperationId::Constructor],
|
||||
&[OperationId::Constructor(IgnoreTraits(self_name))],
|
||||
&list.args.body.list,
|
||||
&return_ty,
|
||||
&None,
|
||||
@ -381,7 +382,7 @@ fn process_interface_attribute<'src>(
|
||||
record,
|
||||
FirstPassOperationType::Interface,
|
||||
self_name,
|
||||
&[OperationId::Constructor],
|
||||
&[OperationId::Constructor(IgnoreTraits(self_name))],
|
||||
&[],
|
||||
&return_ty,
|
||||
&None,
|
||||
@ -401,7 +402,7 @@ fn process_interface_attribute<'src>(
|
||||
record,
|
||||
FirstPassOperationType::Interface,
|
||||
self_name,
|
||||
&[OperationId::Constructor],
|
||||
&[OperationId::Constructor(IgnoreTraits(list.rhs_identifier.0))],
|
||||
&list.args.body.list,
|
||||
&return_ty,
|
||||
&None,
|
||||
@ -784,3 +785,24 @@ impl<'a> FirstPassRecord<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct IgnoreTraits<T>(pub T);
|
||||
|
||||
impl<T> PartialEq for IgnoreTraits<T> {
|
||||
fn eq(&self, _other: &IgnoreTraits<T>) -> bool { true }
|
||||
}
|
||||
|
||||
impl<T> Eq for IgnoreTraits<T> {}
|
||||
|
||||
impl<T> PartialOrd for IgnoreTraits<T> {
|
||||
fn partial_cmp(&self, _other: &IgnoreTraits<T>) -> Option<Ordering> {
|
||||
Some(Ordering::Equal)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Ord for IgnoreTraits<T> {
|
||||
fn cmp(&self, _other: &IgnoreTraits<T>) -> Ordering {
|
||||
Ordering::Equal
|
||||
}
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
) {
|
||||
let name = match id {
|
||||
OperationId::Operation(Some(name)) => name,
|
||||
OperationId::Constructor |
|
||||
OperationId::Constructor(_) |
|
||||
OperationId::Operation(None) |
|
||||
OperationId::IndexingGetter |
|
||||
OperationId::IndexingSetter |
|
||||
@ -404,13 +404,13 @@ impl<'src> FirstPassRecord<'src> {
|
||||
}),
|
||||
});
|
||||
|
||||
for (ctor_name, args) in data.constructors.iter() {
|
||||
self.append_constructor(program, name, ctor_name, args);
|
||||
}
|
||||
// for (ctor_name, args) in data.constructors.iter() {
|
||||
// self.append_constructor(program, name, ctor_name, args);
|
||||
// }
|
||||
for (id, op_data) in data.operations2.iter() {
|
||||
if let OperationId::Constructor = id {
|
||||
continue // TODO
|
||||
}
|
||||
// if let OperationId::Constructor = id {
|
||||
// continue // TODO
|
||||
// }
|
||||
self.member_operation2(program, name, data, id, op_data);
|
||||
}
|
||||
for member in data.consts.iter() {
|
||||
@ -453,61 +453,61 @@ impl<'src> FirstPassRecord<'src> {
|
||||
}
|
||||
}
|
||||
|
||||
fn append_constructor(
|
||||
&self,
|
||||
program: &mut backend::ast::Program,
|
||||
iface_name: &'src str,
|
||||
ctor_name: &'src str,
|
||||
args: &[Argument<'src>],
|
||||
) {
|
||||
let (overloaded, same_argument_names) = self.get_operation_overloading(
|
||||
args,
|
||||
&::first_pass::OperationId::Constructor,
|
||||
iface_name,
|
||||
false,
|
||||
);
|
||||
|
||||
let self_ty = ident_ty(rust_ident(camel_case_ident(iface_name).as_str()));
|
||||
|
||||
let kind = backend::ast::ImportFunctionKind::Method {
|
||||
class: ctor_name.to_string(),
|
||||
ty: self_ty.clone(),
|
||||
kind: backend::ast::MethodKind::Constructor,
|
||||
};
|
||||
|
||||
let structural = false;
|
||||
|
||||
// Constructors aren't annotated with `[Throws]` extended attributes
|
||||
// (how could they be, since they themselves are extended
|
||||
// attributes?) so we must conservatively assume that they can
|
||||
// always throw.
|
||||
//
|
||||
// From https://heycam.github.io/webidl/#Constructor (emphasis
|
||||
// mine):
|
||||
//
|
||||
// > The prose definition of a constructor must either return an IDL
|
||||
// > value of a type corresponding to the interface the
|
||||
// > `[Constructor]` extended attribute appears on, **or throw an
|
||||
// > exception**.
|
||||
let throws = true;
|
||||
|
||||
for import_function in self.create_function(
|
||||
"new",
|
||||
overloaded,
|
||||
same_argument_names,
|
||||
&match self.convert_arguments(args) {
|
||||
Some(arguments) => arguments,
|
||||
None => return,
|
||||
},
|
||||
IdlType::Interface(iface_name),
|
||||
kind,
|
||||
structural,
|
||||
throws,
|
||||
None,
|
||||
) {
|
||||
program.imports.push(wrap_import_function(import_function));
|
||||
}
|
||||
}
|
||||
// fn append_constructor(
|
||||
// &self,
|
||||
// program: &mut backend::ast::Program,
|
||||
// iface_name: &'src str,
|
||||
// ctor_name: &'src str,
|
||||
// args: &[Argument<'src>],
|
||||
// ) {
|
||||
// let (overloaded, same_argument_names) = self.get_operation_overloading(
|
||||
// args,
|
||||
// &::first_pass::OperationId::Constructor,
|
||||
// iface_name,
|
||||
// false,
|
||||
// );
|
||||
//
|
||||
// let self_ty = ident_ty(rust_ident(camel_case_ident(iface_name).as_str()));
|
||||
//
|
||||
// let kind = backend::ast::ImportFunctionKind::Method {
|
||||
// class: ctor_name.to_string(),
|
||||
// ty: self_ty.clone(),
|
||||
// kind: backend::ast::MethodKind::Constructor,
|
||||
// };
|
||||
//
|
||||
// let structural = false;
|
||||
//
|
||||
// // Constructors aren't annotated with `[Throws]` extended attributes
|
||||
// // (how could they be, since they themselves are extended
|
||||
// // attributes?) so we must conservatively assume that they can
|
||||
// // always throw.
|
||||
// //
|
||||
// // From https://heycam.github.io/webidl/#Constructor (emphasis
|
||||
// // mine):
|
||||
// //
|
||||
// // > The prose definition of a constructor must either return an IDL
|
||||
// // > value of a type corresponding to the interface the
|
||||
// // > `[Constructor]` extended attribute appears on, **or throw an
|
||||
// // > exception**.
|
||||
// let throws = true;
|
||||
//
|
||||
// for import_function in self.create_function(
|
||||
// "new",
|
||||
// overloaded,
|
||||
// same_argument_names,
|
||||
// &match self.convert_arguments(args) {
|
||||
// Some(arguments) => arguments,
|
||||
// None => return,
|
||||
// },
|
||||
// IdlType::Interface(iface_name),
|
||||
// kind,
|
||||
// structural,
|
||||
// throws,
|
||||
// None,
|
||||
// ) {
|
||||
// program.imports.push(wrap_import_function(import_function));
|
||||
// }
|
||||
// }
|
||||
|
||||
fn member_attribute(
|
||||
&self,
|
||||
@ -571,28 +571,29 @@ impl<'src> FirstPassRecord<'src> {
|
||||
id: &OperationId<'src>,
|
||||
op_data: &OperationData2<'src>,
|
||||
) {
|
||||
let operation_kind = match id {
|
||||
OperationId::Constructor => panic!("constructors are unsupported"),
|
||||
OperationId::Operation(_) => backend::ast::OperationKind::Regular,
|
||||
OperationId::IndexingGetter => backend::ast::OperationKind::IndexingGetter,
|
||||
OperationId::IndexingSetter => backend::ast::OperationKind::IndexingSetter,
|
||||
OperationId::IndexingDeleter => backend::ast::OperationKind::IndexingDeleter,
|
||||
let import_function_kind = |opkind| {
|
||||
self.import_function_kind(self_name, data.global, op_data.is_static, opkind)
|
||||
};
|
||||
let operation = backend::ast::Operation {
|
||||
is_static: op_data.is_static,
|
||||
kind: operation_kind,
|
||||
};
|
||||
let ty = ident_ty(rust_ident(camel_case_ident(&self_name).as_str()));
|
||||
let kind = if data.global {
|
||||
backend::ast::ImportFunctionKind::ScopedMethod {
|
||||
ty,
|
||||
operation,
|
||||
let kind = match id {
|
||||
OperationId::Constructor(ctor_name) => {
|
||||
let self_ty = ident_ty(rust_ident(&camel_case_ident(self_name)));
|
||||
backend::ast::ImportFunctionKind::Method {
|
||||
class: ctor_name.0.to_string(),
|
||||
ty: self_ty.clone(),
|
||||
kind: backend::ast::MethodKind::Constructor,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
backend::ast::ImportFunctionKind::Method {
|
||||
class: self_name.to_string(),
|
||||
ty,
|
||||
kind: backend::ast::MethodKind::Operation(operation),
|
||||
OperationId::Operation(_) => {
|
||||
import_function_kind(backend::ast::OperationKind::Regular)
|
||||
}
|
||||
OperationId::IndexingGetter => {
|
||||
import_function_kind(backend::ast::OperationKind::IndexingGetter)
|
||||
}
|
||||
OperationId::IndexingSetter => {
|
||||
import_function_kind(backend::ast::OperationKind::IndexingSetter)
|
||||
}
|
||||
OperationId::IndexingDeleter => {
|
||||
import_function_kind(backend::ast::OperationKind::IndexingDeleter)
|
||||
}
|
||||
};
|
||||
for method in self.create_imports(kind, id, op_data) {
|
||||
|
@ -522,7 +522,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
)
|
||||
}
|
||||
|
||||
fn import_function_kind(
|
||||
pub fn import_function_kind(
|
||||
&self,
|
||||
self_name: &str,
|
||||
global: bool,
|
||||
@ -630,16 +630,28 @@ impl<'src> FirstPassRecord<'src> {
|
||||
}
|
||||
}
|
||||
|
||||
let (name, force_structural) = match id {
|
||||
OperationId::Constructor => ("new", false),
|
||||
OperationId::Operation(Some(s)) => (*s, false),
|
||||
let (name, force_structural, force_throws) = match id {
|
||||
// Constructors aren't annotated with `[Throws]` extended attributes
|
||||
// (how could they be, since they themselves are extended
|
||||
// attributes?) so we must conservatively assume that they can
|
||||
// always throw.
|
||||
//
|
||||
// From https://heycam.github.io/webidl/#Constructor (emphasis
|
||||
// mine):
|
||||
//
|
||||
// > The prose definition of a constructor must either return an IDL
|
||||
// > value of a type corresponding to the interface the
|
||||
// > `[Constructor]` extended attribute appears on, **or throw an
|
||||
// > exception**.
|
||||
OperationId::Constructor(_) => ("new", false, true),
|
||||
OperationId::Operation(Some(s)) => (*s, false, false),
|
||||
OperationId::Operation(None) => {
|
||||
warn!("unsupported unnamed operation");
|
||||
return Vec::new()
|
||||
}
|
||||
OperationId::IndexingGetter => ("get", true),
|
||||
OperationId::IndexingSetter => ("set", true),
|
||||
OperationId::IndexingDeleter => ("delete", true),
|
||||
OperationId::IndexingGetter => ("get", true, false),
|
||||
OperationId::IndexingSetter => ("set", true, false),
|
||||
OperationId::IndexingDeleter => ("delete", true, false),
|
||||
};
|
||||
|
||||
let mut ret = Vec::new();
|
||||
@ -707,7 +719,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
&ret_ty,
|
||||
kind.clone(),
|
||||
force_structural || is_structural(&signature.orig.attrs),
|
||||
throws(&signature.orig.attrs),
|
||||
force_throws || throws(&signature.orig.attrs),
|
||||
None,
|
||||
));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user