mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-03-28 07:51:07 +00:00
Migrate methods to new naming scheme
Allows deletion of `create_basic_method`!
This commit is contained in:
parent
15d4338abe
commit
5a4a34d4a1
@ -82,12 +82,12 @@ fn optional_and_union_arguments() {
|
|||||||
let f = OptionalAndUnionArguments::new().unwrap();
|
let f = OptionalAndUnionArguments::new().unwrap();
|
||||||
assert_eq!(f.m("abc"), "string, abc, boolean, true, number, 123, number, 456");
|
assert_eq!(f.m("abc"), "string, abc, boolean, true, number, 123, number, 456");
|
||||||
assert_eq!(f.m_with_b("abc", false), "string, abc, boolean, false, number, 123, number, 456");
|
assert_eq!(f.m_with_b("abc", false), "string, abc, boolean, false, number, 123, number, 456");
|
||||||
assert_eq!(f.m_with_bool_and_i16("abc", false, 5), "string, abc, boolean, false, number, 5, number, 456");
|
assert_eq!(f.m_with_b_and_i16("abc", false, 5), "string, abc, boolean, false, number, 5, number, 456");
|
||||||
assert_eq!(f.m_with_bool_and_str("abc", false, "5"), "string, abc, boolean, false, string, 5, number, 456");
|
assert_eq!(f.m_with_b_and_str("abc", false, "5"), "string, abc, boolean, false, string, 5, number, 456");
|
||||||
assert_eq!(f.m_with_bool_and_i16_and_opt_i64("abc", false, 5, Some(10)), "string, abc, boolean, false, number, 5, bigint, 10");
|
assert_eq!(f.m_with_b_and_i16_and_opt_i64("abc", false, 5, Some(10)), "string, abc, boolean, false, number, 5, bigint, 10");
|
||||||
assert_eq!(f.m_with_bool_and_i16_and_opt_bool("abc", false, 5, Some(true)), "string, abc, boolean, false, number, 5, boolean, true");
|
assert_eq!(f.m_with_b_and_i16_and_opt_bool("abc", false, 5, Some(true)), "string, abc, boolean, false, number, 5, boolean, true");
|
||||||
assert_eq!(f.m_with_bool_and_str_and_opt_i64("abc", false, "5", Some(10)), "string, abc, boolean, false, string, 5, bigint, 10");
|
assert_eq!(f.m_with_b_and_str_and_opt_i64("abc", false, "5", Some(10)), "string, abc, boolean, false, string, 5, bigint, 10");
|
||||||
assert_eq!(f.m_with_bool_and_str_and_opt_bool("abc", false, "5", Some(true)), "string, abc, boolean, false, string, 5, boolean, true");
|
assert_eq!(f.m_with_b_and_str_and_opt_bool("abc", false, "5", Some(true)), "string, abc, boolean, false, string, 5, boolean, true");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
@ -118,7 +118,9 @@ fn mixin() {
|
|||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
fn overload_naming() {
|
fn overload_naming() {
|
||||||
let o = Overloads::new().unwrap();
|
let o = Overloads::new().unwrap();
|
||||||
// o.foo();
|
o.foo();
|
||||||
// o.foo_with_arg("x");
|
o.foo_with_arg("x");
|
||||||
// o.foo_with_arg_and_a("x", 3);
|
o.foo_with_arg_and_i32("x", 3);
|
||||||
|
o.foo_with_arg_and_f32("x", 2.0);
|
||||||
|
o.foo_with_arg_and_i16("x", 5);
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,7 @@ pub(crate) struct OperationData<'src> {
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub(crate) struct OperationData2<'src> {
|
pub(crate) struct OperationData2<'src> {
|
||||||
pub(crate) signatures: Vec<Signature<'src>>,
|
pub(crate) signatures: Vec<Signature<'src>>,
|
||||||
|
pub(crate) is_static: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -231,6 +232,7 @@ fn first_pass_operation<'src>(
|
|||||||
arguments: &'src [Argument<'src>],
|
arguments: &'src [Argument<'src>],
|
||||||
ret: &weedle::types::ReturnType<'src>,
|
ret: &weedle::types::ReturnType<'src>,
|
||||||
attrs: &'src Option<ExtendedAttributeList<'src>>,
|
attrs: &'src Option<ExtendedAttributeList<'src>>,
|
||||||
|
is_static: bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if util::is_chrome_only(attrs) {
|
if util::is_chrome_only(attrs) {
|
||||||
return false
|
return false
|
||||||
@ -292,14 +294,13 @@ fn first_pass_operation<'src>(
|
|||||||
.entry(names.clone())
|
.entry(names.clone())
|
||||||
.and_modify(|same_argument_names| *same_argument_names = true)
|
.and_modify(|same_argument_names| *same_argument_names = true)
|
||||||
.or_insert(false);
|
.or_insert(false);
|
||||||
operations2.entry(*id)
|
let op2 = operations2.entry(*id).or_default();
|
||||||
.or_default()
|
op2.is_static = is_static;
|
||||||
.signatures
|
op2.signatures.push(Signature {
|
||||||
.push(Signature {
|
args: args.clone(),
|
||||||
args: args.clone(),
|
ret: ret.clone(),
|
||||||
ret: ret.clone(),
|
attrs,
|
||||||
attrs,
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -366,6 +367,7 @@ fn process_interface_attribute<'src>(
|
|||||||
&list.args.body.list,
|
&list.args.body.list,
|
||||||
&return_ty,
|
&return_ty,
|
||||||
&None,
|
&None,
|
||||||
|
false,
|
||||||
) {
|
) {
|
||||||
record.interfaces
|
record.interfaces
|
||||||
.get_mut(self_name)
|
.get_mut(self_name)
|
||||||
@ -383,6 +385,7 @@ fn process_interface_attribute<'src>(
|
|||||||
&[],
|
&[],
|
||||||
&return_ty,
|
&return_ty,
|
||||||
&None,
|
&None,
|
||||||
|
false,
|
||||||
) {
|
) {
|
||||||
record.interfaces
|
record.interfaces
|
||||||
.get_mut(self_name)
|
.get_mut(self_name)
|
||||||
@ -402,6 +405,7 @@ fn process_interface_attribute<'src>(
|
|||||||
&list.args.body.list,
|
&list.args.body.list,
|
||||||
&return_ty,
|
&return_ty,
|
||||||
&None,
|
&None,
|
||||||
|
false,
|
||||||
) {
|
) {
|
||||||
record.interfaces
|
record.interfaces
|
||||||
.get_mut(self_name)
|
.get_mut(self_name)
|
||||||
@ -488,10 +492,14 @@ impl<'src> FirstPass<'src, &'src str> for weedle::interface::OperationInterfaceM
|
|||||||
warn!("Unsupported webidl operation: {:?}", self);
|
warn!("Unsupported webidl operation: {:?}", self);
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
if let Some(StringifierOrStatic::Stringifier(_)) = self.modifier {
|
let is_static = match self.modifier {
|
||||||
warn!("Unsupported webidl stringifier: {:?}", self);
|
Some(StringifierOrStatic::Stringifier(_)) => {
|
||||||
return Ok(())
|
warn!("Unsupported webidl stringifier: {:?}", self);
|
||||||
}
|
return Ok(())
|
||||||
|
}
|
||||||
|
Some(StringifierOrStatic::Static(_)) => true,
|
||||||
|
None => false,
|
||||||
|
};
|
||||||
|
|
||||||
let mut ids = vec![OperationId::Operation(self.identifier.map(|s| s.0))];
|
let mut ids = vec![OperationId::Operation(self.identifier.map(|s| s.0))];
|
||||||
for special in self.specials.iter() {
|
for special in self.specials.iter() {
|
||||||
@ -510,6 +518,7 @@ impl<'src> FirstPass<'src, &'src str> for weedle::interface::OperationInterfaceM
|
|||||||
&self.args.body.list,
|
&self.args.body.list,
|
||||||
&self.return_type,
|
&self.return_type,
|
||||||
&self.attributes,
|
&self.attributes,
|
||||||
|
is_static,
|
||||||
) {
|
) {
|
||||||
record.interfaces
|
record.interfaces
|
||||||
.get_mut(self_name)
|
.get_mut(self_name)
|
||||||
@ -621,6 +630,7 @@ impl<'src> FirstPass<'src, &'src str> for weedle::mixin::OperationMixinMember<'s
|
|||||||
&self.args.body.list,
|
&self.args.body.list,
|
||||||
&self.return_type,
|
&self.return_type,
|
||||||
&self.attributes,
|
&self.attributes,
|
||||||
|
false,
|
||||||
) {
|
) {
|
||||||
record.mixins
|
record.mixins
|
||||||
.get_mut(self_name)
|
.get_mut(self_name)
|
||||||
@ -719,6 +729,7 @@ impl<'src> FirstPass<'src, &'src str> for weedle::namespace::OperationNamespaceM
|
|||||||
&self.args.body.list,
|
&self.args.body.list,
|
||||||
&self.return_type,
|
&self.return_type,
|
||||||
&self.attributes,
|
&self.attributes,
|
||||||
|
true,
|
||||||
) {
|
) {
|
||||||
record.namespaces.get_mut(self_name).unwrap().members.push(self);
|
record.namespaces.get_mut(self_name).unwrap().members.push(self);
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,8 @@ use weedle::argument::Argument;
|
|||||||
use weedle::attribute::{ExtendedAttributeList};
|
use weedle::attribute::{ExtendedAttributeList};
|
||||||
use weedle::dictionary::DictionaryMember;
|
use weedle::dictionary::DictionaryMember;
|
||||||
|
|
||||||
use first_pass::{FirstPass, FirstPassRecord, OperationId};
|
use first_pass::{FirstPass, FirstPassRecord, OperationId, InterfaceData};
|
||||||
|
use first_pass::OperationData2;
|
||||||
use util::{public, webidl_const_v_to_backend_const_v, TypePosition, camel_case_ident, mdn_doc};
|
use util::{public, webidl_const_v_to_backend_const_v, TypePosition, camel_case_ident, mdn_doc};
|
||||||
use idl_type::{IdlType, ToIdlType};
|
use idl_type::{IdlType, ToIdlType};
|
||||||
|
|
||||||
@ -309,7 +310,7 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
module: &mut backend::ast::Module,
|
module: &mut backend::ast::Module,
|
||||||
self_name: &'src str,
|
self_name: &'src str,
|
||||||
id: &OperationId<'src>,
|
id: &OperationId<'src>,
|
||||||
data: &first_pass::OperationData2<'src>,
|
data: &OperationData2<'src>,
|
||||||
) {
|
) {
|
||||||
let name = match id {
|
let name = match id {
|
||||||
OperationId::Operation(Some(name)) => name,
|
OperationId::Operation(Some(name)) => name,
|
||||||
@ -379,7 +380,7 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
&self,
|
&self,
|
||||||
program: &mut backend::ast::Program,
|
program: &mut backend::ast::Program,
|
||||||
name: &'src str,
|
name: &'src str,
|
||||||
data: &first_pass::InterfaceData<'src>,
|
data: &InterfaceData<'src>,
|
||||||
) {
|
) {
|
||||||
let doc_comment = Some(format!(
|
let doc_comment = Some(format!(
|
||||||
"The `{}` object\n\n{}",
|
"The `{}` object\n\n{}",
|
||||||
@ -406,17 +407,11 @@ 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 member in data.methods.iter() {
|
for (id, op_data) in data.operations2.iter() {
|
||||||
self.member_operation(
|
if let OperationId::Constructor = id {
|
||||||
program,
|
continue // TODO
|
||||||
name,
|
}
|
||||||
&member.attributes,
|
self.member_operation2(program, name, data, id, op_data);
|
||||||
member.modifier,
|
|
||||||
&member.specials,
|
|
||||||
&member.return_type,
|
|
||||||
&member.args.body.list,
|
|
||||||
&member.identifier,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
for member in data.consts.iter() {
|
for member in data.consts.iter() {
|
||||||
self.append_const(program, name, member);
|
self.append_const(program, name, member);
|
||||||
@ -433,23 +428,14 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for data in self.all_mixins(name) {
|
for mixin_data in self.all_mixins(name) {
|
||||||
for member in &data.methods {
|
for (id, op_data) in mixin_data.operations2.iter() {
|
||||||
self.member_operation(
|
self.member_operation2(program, name, data, id, op_data);
|
||||||
program,
|
|
||||||
name,
|
|
||||||
&member.attributes,
|
|
||||||
None,
|
|
||||||
&[],
|
|
||||||
&member.return_type,
|
|
||||||
&member.args.body.list,
|
|
||||||
&member.identifier,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
for member in &data.consts {
|
for member in &mixin_data.consts {
|
||||||
self.append_const(program, name, member);
|
self.append_const(program, name, member);
|
||||||
}
|
}
|
||||||
for member in &data.attributes {
|
for member in &mixin_data.attributes {
|
||||||
self.member_attribute(
|
self.member_attribute(
|
||||||
program,
|
program,
|
||||||
name,
|
name,
|
||||||
@ -577,69 +563,40 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn member_operation(
|
fn member_operation2(
|
||||||
&self,
|
&self,
|
||||||
program: &mut backend::ast::Program,
|
program: &mut backend::ast::Program,
|
||||||
self_name: &'src str,
|
self_name: &str,
|
||||||
attrs: &'src Option<ExtendedAttributeList>,
|
data: &InterfaceData<'src>,
|
||||||
modifier: Option<weedle::interface::StringifierOrStatic>,
|
id: &OperationId<'src>,
|
||||||
specials: &[weedle::interface::Special],
|
op_data: &OperationData2<'src>,
|
||||||
return_type: &'src weedle::types::ReturnType<'src>,
|
|
||||||
args: &'src [Argument],
|
|
||||||
identifier: &Option<weedle::common::Identifier<'src>>,
|
|
||||||
) {
|
) {
|
||||||
use weedle::interface::StringifierOrStatic::*;
|
let operation_kind = match id {
|
||||||
use weedle::interface::Special;
|
OperationId::Constructor => panic!("constructors are unsupported"),
|
||||||
|
OperationId::Operation(_) => backend::ast::OperationKind::Regular,
|
||||||
let is_static = match modifier {
|
OperationId::IndexingGetter => backend::ast::OperationKind::IndexingGetter,
|
||||||
Some(Stringifier(_)) => unimplemented!(), // filtered out earlier
|
OperationId::IndexingSetter => backend::ast::OperationKind::IndexingSetter,
|
||||||
Some(Static(_)) => true,
|
OperationId::IndexingDeleter => backend::ast::OperationKind::IndexingDeleter,
|
||||||
None => false,
|
|
||||||
};
|
};
|
||||||
|
let operation = backend::ast::Operation {
|
||||||
let mut operation_ids = vec![
|
is_static: op_data.is_static,
|
||||||
OperationId::Operation(identifier.map(|s| s.0)),
|
kind: operation_kind,
|
||||||
];
|
};
|
||||||
if specials.len() == 1 {
|
let ty = ident_ty(rust_ident(camel_case_ident(&self_name).as_str()));
|
||||||
let id = match specials[0] {
|
let kind = if data.global {
|
||||||
Special::Getter(weedle::term::Getter) => OperationId::IndexingGetter,
|
backend::ast::ImportFunctionKind::ScopedMethod {
|
||||||
Special::Setter(weedle::term::Setter) => OperationId::IndexingSetter,
|
ty,
|
||||||
Special::Deleter(weedle::term::Deleter) => OperationId::IndexingDeleter,
|
operation,
|
||||||
Special::LegacyCaller(weedle::term::LegacyCaller) => {
|
|
||||||
warn!("Unsupported legacy caller: {:?}", (self_name, identifier));
|
|
||||||
return
|
|
||||||
},
|
|
||||||
};
|
|
||||||
operation_ids.push(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
let global = self
|
|
||||||
.interfaces
|
|
||||||
.get(self_name)
|
|
||||||
.map(|interface_data| interface_data.global)
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
for id in operation_ids {
|
|
||||||
let methods = self
|
|
||||||
.create_basic_method(
|
|
||||||
args,
|
|
||||||
id,
|
|
||||||
return_type,
|
|
||||||
self_name,
|
|
||||||
is_static,
|
|
||||||
match id {
|
|
||||||
OperationId::IndexingGetter |
|
|
||||||
OperationId::IndexingSetter |
|
|
||||||
OperationId::IndexingDeleter => true,
|
|
||||||
_ => false,
|
|
||||||
},
|
|
||||||
util::throws(attrs),
|
|
||||||
global,
|
|
||||||
);
|
|
||||||
|
|
||||||
for method in methods {
|
|
||||||
program.imports.push(wrap_import_function(method));
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
backend::ast::ImportFunctionKind::Method {
|
||||||
|
class: self_name.to_string(),
|
||||||
|
ty,
|
||||||
|
kind: backend::ast::MethodKind::Operation(operation),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for method in self.create_imports(kind, id, op_data) {
|
||||||
|
program.imports.push(wrap_import_function(method));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -407,97 +407,6 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
Some(converted_arguments)
|
Some(converted_arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a wasm-bindgen method, if possible.
|
|
||||||
pub fn create_basic_method(
|
|
||||||
&self,
|
|
||||||
arguments: &[Argument<'src>],
|
|
||||||
operation_id: first_pass::OperationId,
|
|
||||||
return_type: &weedle::types::ReturnType<'src>,
|
|
||||||
self_name: &str,
|
|
||||||
is_static: bool,
|
|
||||||
structural: bool,
|
|
||||||
catch: bool,
|
|
||||||
global: bool,
|
|
||||||
) -> Vec<backend::ast::ImportFunction> {
|
|
||||||
let (overloaded, same_argument_names) = self.get_operation_overloading(
|
|
||||||
arguments,
|
|
||||||
&operation_id,
|
|
||||||
self_name,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
let name = match &operation_id {
|
|
||||||
first_pass::OperationId::Constructor => panic!("constructors are unsupported"),
|
|
||||||
first_pass::OperationId::Operation(name) => match name {
|
|
||||||
None => {
|
|
||||||
warn!("Unsupported unnamed operation: {:?}", operation_id);
|
|
||||||
return Vec::new();
|
|
||||||
}
|
|
||||||
Some(name) => name,
|
|
||||||
},
|
|
||||||
first_pass::OperationId::IndexingGetter => "get",
|
|
||||||
first_pass::OperationId::IndexingSetter => "set",
|
|
||||||
first_pass::OperationId::IndexingDeleter => "delete",
|
|
||||||
};
|
|
||||||
let operation_kind = match &operation_id {
|
|
||||||
first_pass::OperationId::Constructor => panic!("constructors are unsupported"),
|
|
||||||
first_pass::OperationId::Operation(_) => backend::ast::OperationKind::Regular,
|
|
||||||
first_pass::OperationId::IndexingGetter => backend::ast::OperationKind::IndexingGetter,
|
|
||||||
first_pass::OperationId::IndexingSetter => backend::ast::OperationKind::IndexingSetter,
|
|
||||||
first_pass::OperationId::IndexingDeleter => backend::ast::OperationKind::IndexingDeleter,
|
|
||||||
};
|
|
||||||
let operation = backend::ast::Operation { is_static, kind: operation_kind };
|
|
||||||
let ty = ident_ty(rust_ident(camel_case_ident(&self_name).as_str()));
|
|
||||||
let kind = if global {
|
|
||||||
backend::ast::ImportFunctionKind::ScopedMethod {
|
|
||||||
ty,
|
|
||||||
operation,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
backend::ast::ImportFunctionKind::Method {
|
|
||||||
class: self_name.to_string(),
|
|
||||||
ty,
|
|
||||||
kind: backend::ast::MethodKind::Operation(operation),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let ret = match return_type.to_idl_type(self) {
|
|
||||||
None => return Vec::new(),
|
|
||||||
Some(idl_type) => idl_type,
|
|
||||||
};
|
|
||||||
|
|
||||||
let doc_comment = match &operation_id {
|
|
||||||
first_pass::OperationId::Constructor => panic!("constructors are unsupported"),
|
|
||||||
first_pass::OperationId::Operation(_) => Some(
|
|
||||||
format!(
|
|
||||||
"The `{}()` method\n\n{}",
|
|
||||||
name,
|
|
||||||
mdn_doc(self_name, Some(&name))
|
|
||||||
)
|
|
||||||
),
|
|
||||||
first_pass::OperationId::IndexingGetter => Some("The indexing getter\n\n".to_string()),
|
|
||||||
first_pass::OperationId::IndexingSetter => Some("The indexing setter\n\n".to_string()),
|
|
||||||
first_pass::OperationId::IndexingDeleter => Some("The indexing deleter\n\n".to_string()),
|
|
||||||
};
|
|
||||||
|
|
||||||
let arguments = match self.convert_arguments(arguments) {
|
|
||||||
None => return Vec::new(),
|
|
||||||
Some(arguments) => arguments
|
|
||||||
};
|
|
||||||
|
|
||||||
self.create_function(
|
|
||||||
&name,
|
|
||||||
overloaded,
|
|
||||||
same_argument_names,
|
|
||||||
&arguments,
|
|
||||||
ret,
|
|
||||||
kind,
|
|
||||||
structural,
|
|
||||||
catch,
|
|
||||||
doc_comment,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether operation is overloaded and
|
/// Whether operation is overloaded and
|
||||||
/// whether there overloads with same argument names for given argument types
|
/// whether there overloads with same argument names for given argument types
|
||||||
pub fn get_operation_overloading(
|
pub fn get_operation_overloading(
|
||||||
@ -659,7 +568,8 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
let mut actual_signatures = Vec::new();
|
let mut actual_signatures = Vec::new();
|
||||||
'outer:
|
'outer:
|
||||||
for signature in data.signatures.iter() {
|
for signature in data.signatures.iter() {
|
||||||
let start = actual_signatures.len();
|
let real_start = actual_signatures.len();
|
||||||
|
let mut start = real_start;
|
||||||
|
|
||||||
// Start off with an empty signature, this'll handle zero-argument
|
// Start off with an empty signature, this'll handle zero-argument
|
||||||
// cases and otherwise the loop below will continue to add on to this.
|
// cases and otherwise the loop below will continue to add on to this.
|
||||||
@ -669,51 +579,67 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (i, arg) in signature.args.iter().enumerate() {
|
for (i, arg) in signature.args.iter().enumerate() {
|
||||||
let cur = actual_signatures.len();
|
|
||||||
// If any argument in this signature can't be converted we have
|
// If any argument in this signature can't be converted we have
|
||||||
// to throw out the entire signature, so revert back to the
|
// to throw out the entire signature, so revert back to the
|
||||||
// beginning and then keep going.
|
// beginning and then keep going.
|
||||||
let idl_type = match arg.ty.to_idl_type(self) {
|
let idl_type = match arg.ty.to_idl_type(self) {
|
||||||
Some(t) => t,
|
Some(t) => t,
|
||||||
None => {
|
None => {
|
||||||
actual_signatures.truncate(start);
|
actual_signatures.truncate(real_start);
|
||||||
continue 'outer
|
continue 'outer
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if arg.optional {
|
||||||
|
assert!(signature.args[i..].iter().all(|a| a.optional));
|
||||||
|
let end = actual_signatures.len();
|
||||||
|
for j in start..end {
|
||||||
|
let sig = actual_signatures[j].clone();
|
||||||
|
actual_signatures.push(sig);
|
||||||
|
}
|
||||||
|
start = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(start < actual_signatures.len());
|
||||||
|
for sig in actual_signatures[start..].iter() {
|
||||||
|
assert_eq!(sig.args.len(), i);
|
||||||
|
}
|
||||||
|
|
||||||
// The first arugment gets pushed directly in-place, but all
|
// The first arugment gets pushed directly in-place, but all
|
||||||
// future expanded arguments will cause new signatures to be
|
// future expanded arguments will cause new signatures to be
|
||||||
// created. If we have an optional argument then we consider the
|
// created. If we have an optional argument then we consider the
|
||||||
// already existing signature as the "none" case and the flatten
|
// already existing signature as the "none" case and the flatten
|
||||||
// below will produce the "some" case, so we've already
|
// below will produce the "some" case, so we've already
|
||||||
// processed the first argument effectively.
|
// processed the first argument effectively.
|
||||||
let mut first = !arg.optional;
|
let mut first = true;
|
||||||
|
let cur = actual_signatures.len();
|
||||||
for idl_type in idl_type.flatten() {
|
for idl_type in idl_type.flatten() {
|
||||||
for j in start..cur {
|
for j in start..cur {
|
||||||
if first {
|
if first {
|
||||||
actual_signatures[j].args.push(idl_type.clone());
|
actual_signatures[j].args.push(idl_type.clone());
|
||||||
first = false;
|
|
||||||
} else {
|
} else {
|
||||||
let mut sig = actual_signatures[j].clone();
|
let mut sig = actual_signatures[j].clone();
|
||||||
|
assert_eq!(sig.args.len(), i + 1);
|
||||||
sig.args.truncate(i);
|
sig.args.truncate(i);
|
||||||
sig.args.push(idl_type.clone());
|
sig.args.push(idl_type.clone());
|
||||||
actual_signatures.push(sig);
|
actual_signatures.push(sig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = match id {
|
let (name, force_structural) = match id {
|
||||||
OperationId::Constructor => "new",
|
OperationId::Constructor => ("new", false),
|
||||||
OperationId::Operation(Some(s)) => s,
|
OperationId::Operation(Some(s)) => (*s, false),
|
||||||
OperationId::Operation(None) => {
|
OperationId::Operation(None) => {
|
||||||
warn!("unsupported unnamed operation");
|
warn!("unsupported unnamed operation");
|
||||||
return Vec::new()
|
return Vec::new()
|
||||||
}
|
}
|
||||||
OperationId::IndexingGetter => "get",
|
OperationId::IndexingGetter => ("get", true),
|
||||||
OperationId::IndexingSetter => "set",
|
OperationId::IndexingSetter => ("set", true),
|
||||||
OperationId::IndexingDeleter => "delete",
|
OperationId::IndexingDeleter => ("delete", true),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ret = Vec::new();
|
let mut ret = Vec::new();
|
||||||
@ -731,6 +657,7 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
// name for this argument or a different type for this argument.
|
// name for this argument or a different type for this argument.
|
||||||
let mut any_same_name = false;
|
let mut any_same_name = false;
|
||||||
let mut any_different_type = false;
|
let mut any_different_type = false;
|
||||||
|
let mut any_different = false;
|
||||||
let arg_name = signature.orig.args[i].name;
|
let arg_name = signature.orig.args[i].name;
|
||||||
for other in actual_signatures.iter() {
|
for other in actual_signatures.iter() {
|
||||||
if other.orig.args.get(i).map(|s| s.name) == Some(arg_name) {
|
if other.orig.args.get(i).map(|s| s.name) == Some(arg_name) {
|
||||||
@ -738,15 +665,20 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
any_same_name = true;
|
any_same_name = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if other.args.get(i) != Some(arg) {
|
if let Some(other) = other.args.get(i) {
|
||||||
any_different_type = true;
|
if other != arg {
|
||||||
|
any_different_type = true;
|
||||||
|
any_different = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
any_different = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If all signatures have the exact same type for this argument,
|
// If all signatures have the exact same type for this argument,
|
||||||
// then there's nothing to disambiguate so we don't modify the
|
// then there's nothing to disambiguate so we don't modify the
|
||||||
// name.
|
// name.
|
||||||
if !any_different_type {
|
if !any_different {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if first {
|
if first {
|
||||||
@ -760,7 +692,7 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
// then that's a bit more human readable so we include it in the
|
// then that's a bit more human readable so we include it in the
|
||||||
// method name. Otherwise the type name should disambiguate
|
// method name. Otherwise the type name should disambiguate
|
||||||
// correctly.
|
// correctly.
|
||||||
if !any_same_name {
|
if !any_same_name || !any_different_type {
|
||||||
rust_name.push_str(&arg_name.to_snake_case());
|
rust_name.push_str(&arg_name.to_snake_case());
|
||||||
} else {
|
} else {
|
||||||
arg.push_type_name(&mut rust_name);
|
arg.push_type_name(&mut rust_name);
|
||||||
@ -774,7 +706,7 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
.map(|(ty, orig_arg)| (orig_arg.name, ty)),
|
.map(|(ty, orig_arg)| (orig_arg.name, ty)),
|
||||||
&ret_ty,
|
&ret_ty,
|
||||||
kind.clone(),
|
kind.clone(),
|
||||||
is_structural(&signature.orig.attrs),
|
force_structural || is_structural(&signature.orig.attrs),
|
||||||
throws(&signature.orig.attrs),
|
throws(&signature.orig.attrs),
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user