Shuffle around the wiggle crates (#1414)
* Shuffle around the wiggle crates This commit reorganizes the wiggle crates slightly by performing the following transforms: * The `crates/wiggle` crate, previously named `wiggle`, was moved to `crates/wiggle/crates/macro` and is renamed to `wiggle-macro`. * The `crates/wiggle/crates/runtime` crate, previously named `wiggle-runtime`, was moved to `crates/wiggle` and is renamed to `wiggle`. * The new `wiggle` crate depends on `wiggle-macro` and reexports the macro. The goal here is that consumers only deal with the `wiggle` crate itself. No more crates depend on `wiggle-runtime` and all dependencies are entirely on just the `wiggle` crate. * Remove the `crates/wiggle/crates` directory Move everything into `crates/wiggle` directly, like `wasi-common` * Add wiggle-macro to test-all script * Fixup a test
This commit is contained in:
72
crates/wiggle/generate/src/module_trait.rs
Normal file
72
crates/wiggle/generate/src/module_trait.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
use crate::lifetimes::{anon_lifetime, LifetimeExt};
|
||||
use crate::names::Names;
|
||||
use witx::Module;
|
||||
|
||||
pub fn passed_by_reference(ty: &witx::Type) -> bool {
|
||||
let passed_by = match ty.passed_by() {
|
||||
witx::TypePassedBy::Value { .. } => false,
|
||||
witx::TypePassedBy::Pointer { .. } | witx::TypePassedBy::PointerLengthPair { .. } => true,
|
||||
};
|
||||
match ty {
|
||||
witx::Type::Builtin(b) => match &*b {
|
||||
witx::BuiltinType::String => true,
|
||||
_ => passed_by,
|
||||
},
|
||||
witx::Type::Pointer(_) | witx::Type::ConstPointer(_) | witx::Type::Array(_) => true,
|
||||
_ => passed_by,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn define_module_trait(names: &Names, m: &Module) -> TokenStream {
|
||||
let traitname = names.trait_name(&m.name);
|
||||
let traitmethods = m.funcs().map(|f| {
|
||||
// Check if we're returning an entity anotated with a lifetime,
|
||||
// in which case, we'll need to annotate the function itself, and
|
||||
// hence will need an explicit lifetime (rather than anonymous)
|
||||
let (lifetime, is_anonymous) = if f
|
||||
.params
|
||||
.iter()
|
||||
.chain(&f.results)
|
||||
.any(|ret| ret.tref.needs_lifetime())
|
||||
{
|
||||
(quote!('a), false)
|
||||
} else {
|
||||
(anon_lifetime(), true)
|
||||
};
|
||||
let funcname = names.func(&f.name);
|
||||
let args = f.params.iter().map(|arg| {
|
||||
let arg_name = names.func_param(&arg.name);
|
||||
let arg_typename = names.type_ref(&arg.tref, lifetime.clone());
|
||||
let arg_type = if passed_by_reference(&*arg.tref.type_()) {
|
||||
quote!(&#arg_typename)
|
||||
} else {
|
||||
quote!(#arg_typename)
|
||||
};
|
||||
quote!(#arg_name: #arg_type)
|
||||
});
|
||||
let rets = f
|
||||
.results
|
||||
.iter()
|
||||
.skip(1)
|
||||
.map(|ret| names.type_ref(&ret.tref, lifetime.clone()));
|
||||
let err = f
|
||||
.results
|
||||
.get(0)
|
||||
.map(|err_result| names.type_ref(&err_result.tref, lifetime.clone()))
|
||||
.unwrap_or(quote!(()));
|
||||
|
||||
if is_anonymous {
|
||||
quote!(fn #funcname(&self, #(#args),*) -> Result<(#(#rets),*), #err>;)
|
||||
} else {
|
||||
quote!(fn #funcname<#lifetime>(&self, #(#args),*) -> Result<(#(#rets),*), #err>;)
|
||||
}
|
||||
});
|
||||
quote! {
|
||||
pub trait #traitname {
|
||||
#(#traitmethods)*
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user