function: Add support for wildcards in arguments.
We don't support unnamed arguments, and we give a terrible error ("Parameter has an unsupported type.") when you use them. They're very simple to implement so we should just do it.
This commit is contained in:
parent
8eeb0bb6ec
commit
5eae0bc07b
src/bindgen
tests
@ -63,7 +63,7 @@ impl CDecl {
|
||||
let args = f
|
||||
.args
|
||||
.iter()
|
||||
.map(|&(ref arg_name, ref arg_ty)| (Some(arg_name.clone()), CDecl::from_type(arg_ty)))
|
||||
.map(|&(ref arg_name, ref arg_ty)| (arg_name.clone(), CDecl::from_type(arg_ty)))
|
||||
.collect();
|
||||
self.declarators
|
||||
.push(CDeclarator::Func(args, layout_vertical));
|
||||
|
@ -28,7 +28,7 @@ pub struct Function {
|
||||
/// If the function is a method, this will contain the path of the type in the impl block
|
||||
pub self_type_path: Option<Path>,
|
||||
pub ret: Type,
|
||||
pub args: Vec<(String, Type)>,
|
||||
pub args: Vec<(Option<String>, Type)>,
|
||||
pub extern_decl: bool,
|
||||
pub cfg: Option<Cfg>,
|
||||
pub annotations: AnnotationSet,
|
||||
@ -80,14 +80,14 @@ impl Function {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn swift_name(&self) -> String {
|
||||
pub fn swift_name(&self) -> Option<String> {
|
||||
// If the symbol name starts with the type name, separate the two components with '.'
|
||||
// so that Swift recognises the association between the method and the type
|
||||
let (ref type_prefix, ref type_name) = match self.self_type_path {
|
||||
Some(ref type_name) => {
|
||||
let type_name = type_name.to_string();
|
||||
if !self.path.name().starts_with(&type_name) {
|
||||
return self.path.to_string();
|
||||
return Some(self.path.to_string());
|
||||
}
|
||||
(format!("{}.", type_name), type_name)
|
||||
}
|
||||
@ -101,13 +101,13 @@ impl Function {
|
||||
.trim_start_matches('_');
|
||||
|
||||
let item_args = {
|
||||
let mut items = vec![];
|
||||
let mut items = Vec::with_capacity(self.args.len());
|
||||
for (arg, _) in self.args.iter() {
|
||||
items.push(format!("{}:", arg.as_str()));
|
||||
items.push(format!("{}:", arg.as_ref()?.as_str()));
|
||||
}
|
||||
items.join("")
|
||||
};
|
||||
format!("{}{}({})", type_prefix, item_name, item_args)
|
||||
Some(format!("{}{}({})", type_prefix, item_name, item_args))
|
||||
}
|
||||
|
||||
pub fn path(&self) -> &Path {
|
||||
@ -164,16 +164,24 @@ impl Function {
|
||||
];
|
||||
|
||||
if let Some(r) = find_first_some(&rules) {
|
||||
self.args = self
|
||||
.args
|
||||
.iter()
|
||||
.map(|x| (r.apply(&x.0, IdentifierType::FunctionArg), x.1.clone()))
|
||||
let args = std::mem::replace(&mut self.args, vec![]);
|
||||
self.args = args
|
||||
.into_iter()
|
||||
.map(|(name, ty)| {
|
||||
let name = match name {
|
||||
Some(n) => n,
|
||||
None => return (name, ty),
|
||||
};
|
||||
(Some(r.apply(&name, IdentifierType::FunctionArg)), ty)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
// Escape C/C++ reserved keywords used in argument names
|
||||
for args in &mut self.args {
|
||||
reserved::escape(&mut args.0);
|
||||
for arg in &mut self.args {
|
||||
if let Some(ref mut name) = arg.0 {
|
||||
reserved::escape(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,7 +218,9 @@ impl Source for Function {
|
||||
}
|
||||
|
||||
if let Some(ref swift_name_macro) = config.function.swift_name_macro {
|
||||
write!(out, " {}({})", swift_name_macro, func.swift_name());
|
||||
if let Some(swift_name) = func.swift_name() {
|
||||
write!(out, " {}({})", swift_name_macro, swift_name);
|
||||
}
|
||||
}
|
||||
|
||||
if func.never_return {
|
||||
@ -257,7 +267,9 @@ impl Source for Function {
|
||||
}
|
||||
|
||||
if let Some(ref swift_name_macro) = config.function.swift_name_macro {
|
||||
write!(out, " {}({})", swift_name_macro, func.swift_name());
|
||||
if let Some(swift_name) = func.swift_name() {
|
||||
write!(out, " {}({})", swift_name_macro, swift_name);
|
||||
}
|
||||
}
|
||||
|
||||
if func.never_return {
|
||||
@ -284,7 +296,7 @@ impl Source for Function {
|
||||
}
|
||||
|
||||
pub trait SynFnArgHelpers {
|
||||
fn as_ident_and_type(&self) -> Result<Option<(String, Type)>, String>;
|
||||
fn as_ident_and_type(&self) -> Result<Option<(Option<String>, Type)>, String>;
|
||||
}
|
||||
|
||||
fn gen_self_type(receiver: &syn::Receiver) -> Type {
|
||||
@ -299,29 +311,32 @@ fn gen_self_type(receiver: &syn::Receiver) -> Type {
|
||||
}
|
||||
|
||||
impl SynFnArgHelpers for syn::FnArg {
|
||||
fn as_ident_and_type(&self) -> Result<Option<(String, Type)>, String> {
|
||||
fn as_ident_and_type(&self) -> Result<Option<(Option<String>, Type)>, String> {
|
||||
match *self {
|
||||
syn::FnArg::Typed(syn::PatType {
|
||||
ref pat, ref ty, ..
|
||||
}) => match **pat {
|
||||
syn::Pat::Ident(syn::PatIdent { ref ident, .. }) => {
|
||||
let ty = match Type::load(ty)? {
|
||||
Some(x) => {
|
||||
if let Type::Array(_, _) = x {
|
||||
return Err(
|
||||
"Array as function arguments are not supported".to_owned()
|
||||
);
|
||||
}
|
||||
x
|
||||
}
|
||||
None => return Ok(None),
|
||||
};
|
||||
Ok(Some((ident.to_string(), ty)))
|
||||
}) => {
|
||||
let name = match **pat {
|
||||
syn::Pat::Wild(..) => None,
|
||||
syn::Pat::Ident(syn::PatIdent { ref ident, .. }) => Some(ident.to_string()),
|
||||
_ => {
|
||||
return Err(format!(
|
||||
"Parameter has an unsupported argument name: {:?}",
|
||||
pat
|
||||
))
|
||||
}
|
||||
};
|
||||
let ty = match Type::load(ty)? {
|
||||
Some(x) => x,
|
||||
None => return Ok(None),
|
||||
};
|
||||
if let Type::Array(..) = ty {
|
||||
return Err("Array as function arguments are not supported".to_owned());
|
||||
}
|
||||
_ => Err("Parameter has an unsupported type.".to_owned()),
|
||||
},
|
||||
Ok(Some((name, ty)))
|
||||
}
|
||||
syn::FnArg::Receiver(ref receiver) => {
|
||||
Ok(Some(("self".to_string(), gen_self_type(receiver))))
|
||||
Ok(Some((Some("self".to_string()), gen_self_type(receiver))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,3 +6,5 @@
|
||||
void pointer_test(const uint64_t *a);
|
||||
|
||||
void print_from_rust(void);
|
||||
|
||||
void unnamed(const uint64_t*);
|
||||
|
@ -11,6 +11,8 @@ void pointer_test(const uint64_t *a);
|
||||
|
||||
void print_from_rust(void);
|
||||
|
||||
void unnamed(const uint64_t*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
@ -53,3 +53,5 @@ void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct) CF_SWIF
|
||||
void free_function_should_not_exist_box(Box_SelfTypeTestStruct boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:));
|
||||
|
||||
void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world());
|
||||
|
||||
void unnamed_argument(SelfTypeTestStruct*);
|
||||
|
@ -58,6 +58,8 @@ void free_function_should_not_exist_box(Box_SelfTypeTestStruct boxed) CF_SWIFT_N
|
||||
|
||||
void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world());
|
||||
|
||||
void unnamed_argument(SelfTypeTestStruct*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
@ -6,3 +6,5 @@
|
||||
void pointer_test(const uint64_t *a);
|
||||
|
||||
void print_from_rust(void);
|
||||
|
||||
void unnamed(const uint64_t*);
|
||||
|
@ -11,6 +11,8 @@ void pointer_test(const uint64_t *a);
|
||||
|
||||
void print_from_rust(void);
|
||||
|
||||
void unnamed(const uint64_t*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
@ -9,4 +9,6 @@ void pointer_test(const uint64_t *a);
|
||||
|
||||
void print_from_rust();
|
||||
|
||||
void unnamed(const uint64_t*);
|
||||
|
||||
} // extern "C"
|
||||
|
@ -53,3 +53,5 @@ void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct) CF_SWIF
|
||||
void free_function_should_not_exist_box(Box_SelfTypeTestStruct boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:));
|
||||
|
||||
void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world());
|
||||
|
||||
void unnamed_argument(SelfTypeTestStruct*);
|
||||
|
@ -58,6 +58,8 @@ void free_function_should_not_exist_box(Box_SelfTypeTestStruct boxed) CF_SWIFT_N
|
||||
|
||||
void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world());
|
||||
|
||||
void unnamed_argument(SelfTypeTestStruct*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
@ -57,4 +57,6 @@ void free_function_should_not_exist_box(Box<SelfTypeTestStruct> boxed) CF_SWIFT_
|
||||
|
||||
void rust_print_hello_world() CF_SWIFT_NAME(rust_print_hello_world());
|
||||
|
||||
void unnamed_argument(SelfTypeTestStruct*);
|
||||
|
||||
} // extern "C"
|
||||
|
@ -6,3 +6,5 @@
|
||||
void pointer_test(const uint64_t *a);
|
||||
|
||||
void print_from_rust(void);
|
||||
|
||||
void unnamed(const uint64_t*);
|
||||
|
@ -11,6 +11,8 @@ void pointer_test(const uint64_t *a);
|
||||
|
||||
void print_from_rust(void);
|
||||
|
||||
void unnamed(const uint64_t*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
@ -53,3 +53,5 @@ void free_function_should_exist_ref_mut(struct SelfTypeTestStruct *test_struct)
|
||||
void free_function_should_not_exist_box(struct Box_SelfTypeTestStruct boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:));
|
||||
|
||||
void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world());
|
||||
|
||||
void unnamed_argument(struct SelfTypeTestStruct*);
|
||||
|
@ -58,6 +58,8 @@ void free_function_should_not_exist_box(struct Box_SelfTypeTestStruct boxed) CF_
|
||||
|
||||
void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world());
|
||||
|
||||
void unnamed_argument(struct SelfTypeTestStruct*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
@ -8,13 +8,16 @@ pub unsafe extern fn array_test(a: [u64; 3]) {
|
||||
array_print(&a);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn unnamed(_: *const u64) {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn pointer_test(a: *const u64) {
|
||||
let a = std::slice::from_raw_parts(a, 3);
|
||||
array_print(a);
|
||||
}
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern fn print_from_rust() {
|
||||
let a = [0, 1, 2];
|
||||
|
@ -85,6 +85,11 @@ pub extern fn free_function_should_exist_ref_mut(test_struct: &mut SelfTypeTestS
|
||||
println!("free_function_should_exist_ref_mut");
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn unnamed_argument(_: &mut SelfTypeTestStruct) {
|
||||
println!("unnamed_argument");
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[allow(unused_variables)]
|
||||
pub extern fn free_function_should_not_exist_box(boxed: Box<SelfTypeTestStruct>) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user