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