wiggle: new error configuration for generating a "trappable error" (#5276)

* Add a new "trappable" mode for wiggle to make an error type

start refactoring how errors are generated and configured

put a pin in this - you can now configure a generated error

but i need to go fix Names

Names is no longer a struct, rt is hardcoded to wiggle

rest of fixes to pass tests

its called a trappable error now

don't generate UserErrorConversion trait if empty

mention in macro docs

* undo omitting the user error conversion trait when empty
This commit is contained in:
Pat Hickey
2022-11-16 08:54:41 -08:00
committed by GitHub
parent 1bd78f1a35
commit 22433ed726
15 changed files with 561 additions and 464 deletions

View File

@@ -3,7 +3,7 @@ pub mod config;
mod funcs;
mod lifetimes;
mod module_trait;
mod names;
pub mod names;
mod types;
pub mod wasmtime;
@@ -12,19 +12,16 @@ use lifetimes::anon_lifetime;
use proc_macro2::{Literal, TokenStream};
use quote::quote;
pub use codegen_settings::{CodegenSettings, UserErrorType};
pub use codegen_settings::{CodegenSettings, ErrorType, UserErrorType};
pub use config::{Config, WasmtimeConfig};
pub use funcs::define_func;
pub use module_trait::define_module_trait;
pub use names::Names;
pub use types::define_datatype;
pub fn generate(doc: &witx::Document, names: &Names, settings: &CodegenSettings) -> TokenStream {
// TODO at some point config should grow more ability to configure name
// overrides.
let rt = names.runtime_mod();
let types = doc.typenames().map(|t| define_datatype(&names, &t));
pub fn generate(doc: &witx::Document, settings: &CodegenSettings) -> TokenStream {
let types = doc
.typenames()
.map(|t| define_datatype(&t, settings.errors.for_name(&t)));
let constants = doc.constants().map(|c| {
let name = quote::format_ident!(
@@ -32,18 +29,24 @@ pub fn generate(doc: &witx::Document, names: &Names, settings: &CodegenSettings)
c.ty.as_str().to_shouty_snake_case(),
c.name.as_str().to_shouty_snake_case()
);
let ty = names.type_(&c.ty);
let ty = names::type_(&c.ty);
let value = Literal::u64_unsuffixed(c.value);
quote! {
pub const #name: #ty = #value;
}
});
let user_error_methods = settings.errors.iter().map(|errtype| {
let abi_typename = names.type_ref(&errtype.abi_type(), anon_lifetime());
let user_typename = errtype.typename();
let methodname = names.user_error_conversion_method(&errtype);
quote!(fn #methodname(&mut self, e: super::#user_typename) -> #rt::anyhow::Result<#abi_typename>;)
let user_error_methods = settings.errors.iter().filter_map(|errtype| match errtype {
ErrorType::User(errtype) => {
let abi_typename = names::type_ref(&errtype.abi_type(), anon_lifetime());
let user_typename = errtype.typename();
let methodname = names::user_error_conversion_method(&errtype);
Some(quote! {
fn #methodname(&mut self, e: super::#user_typename)
-> wiggle::anyhow::Result<#abi_typename>;
})
}
ErrorType::Generated(_) => None,
});
let user_error_conversion = quote! {
pub trait UserErrorConversion {
@@ -51,13 +54,11 @@ pub fn generate(doc: &witx::Document, names: &Names, settings: &CodegenSettings)
}
};
let modules = doc.modules().map(|module| {
let modname = names.module(&module.name);
let fs = module
.funcs()
.map(|f| define_func(&names, &module, &f, &settings));
let modtrait = define_module_trait(&names, &module, &settings);
let modname = names::module(&module.name);
let fs = module.funcs().map(|f| define_func(&module, &f, &settings));
let modtrait = define_module_trait(&module, &settings);
let wasmtime = if settings.wasmtime {
crate::wasmtime::link_module(&module, &names, None, &settings)
crate::wasmtime::link_module(&module, None, &settings)
} else {
quote! {}
};
@@ -86,14 +87,13 @@ pub fn generate(doc: &witx::Document, names: &Names, settings: &CodegenSettings)
)
}
pub fn generate_metadata(doc: &witx::Document, names: &Names) -> TokenStream {
let rt = names.runtime_mod();
pub fn generate_metadata(doc: &witx::Document) -> TokenStream {
let doc_text = &format!("{}", doc);
quote! {
pub mod metadata {
pub const DOC_TEXT: &str = #doc_text;
pub fn document() -> #rt::witx::Document {
#rt::witx::parse(DOC_TEXT).unwrap()
pub fn document() -> wiggle::witx::Document {
wiggle::witx::parse(DOC_TEXT).unwrap()
}
}
}