Skip to content

Commit

Permalink
add codegen tests for futures, streams, and error-contexts
Browse files Browse the repository at this point in the history
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
  • Loading branch information
dicej committed Nov 20, 2024
1 parent 2f37f79 commit 672a70a
Show file tree
Hide file tree
Showing 27 changed files with 461 additions and 14 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ clap = { version = "4.3.19", features = ["derive"] }
indexmap = "2.0.0"
prettyplease = "0.2.20"
syn = { version = "2.0", features = ["printing"] }
futures = "0.3.31"

wasmparser = { git = "https://github.com/dicej/wasm-tools", branch = "async" }
wasm-encoder = { git = "https://github.com/dicej/wasm-tools", branch = "async" }
Expand Down
15 changes: 15 additions & 0 deletions crates/c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1342,6 +1342,21 @@ void __wasm_export_{ns}_{snake}_dtor({ns}_{snake}_t* arg) {{
self.finish_typedef_struct(id);
}

fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
_ = (id, name, ty, docs);
todo!()
}

fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
_ = (id, name, ty, docs);
todo!()
}

fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) {
_ = (id, name, docs);
todo!()
}

fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
let _ = (id, name, ty, docs);
}
Expand Down
8 changes: 8 additions & 0 deletions crates/c/tests/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ use std::process::Command;
use wit_parser::{Resolve, UnresolvedPackageGroup};

macro_rules! codegen_test {
// TODO: implement support for stream, future, and error-context, and then
// remove these lines:
(streams $name:tt $test:tt) => {};
(futures $name:tt $test:tt) => {};
(resources_with_streams $name:tt $test:tt) => {};
(resources_with_futures $name:tt $test:tt) => {};
(error_context $name:tt $test:tt) => {};

($id:ident $name:tt $test:tt) => {
#[test]
fn $id() {
Expand Down
4 changes: 1 addition & 3 deletions crates/core/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,9 +845,7 @@ fn needs_post_return(resolve: &Resolve, ty: &Type) -> bool {
.filter_map(|t| t.as_ref())
.any(|t| needs_post_return(resolve, t)),
TypeDefKind::Flags(_) | TypeDefKind::Enum(_) => false,
TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::ErrorContext => {
unimplemented!()
}
TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::ErrorContext => false,
TypeDefKind::Unknown => unreachable!(),
},

Expand Down
11 changes: 6 additions & 5 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ pub trait InterfaceGenerator<'a> {
fn type_alias(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
fn type_list(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs);
fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs);
fn types(&mut self, iface: InterfaceId) {
let iface = &self.resolve().interfaces[iface];
for (name, id) in iface.types.iter() {
Expand All @@ -190,12 +193,10 @@ pub trait InterfaceGenerator<'a> {
TypeDefKind::Result(r) => self.type_result(id, name, r, &ty.docs),
TypeDefKind::List(t) => self.type_list(id, name, t, &ty.docs),
TypeDefKind::Type(t) => self.type_alias(id, name, t, &ty.docs),
TypeDefKind::Future(_) => panic!("future types do not require definition"),
TypeDefKind::Stream(_) => panic!("stream types do not require definition"),
TypeDefKind::Future(t) => self.type_future(id, name, t, &ty.docs),
TypeDefKind::Stream(t) => self.type_stream(id, name, t, &ty.docs),
TypeDefKind::Handle(_) => panic!("handle types do not require definition"),
TypeDefKind::ErrorContext => {
panic!("the error-context type does not require definition")
}
TypeDefKind::ErrorContext => self.type_error_context(id, name, &ty.docs),
TypeDefKind::Unknown => unreachable!(),
}
}
Expand Down
4 changes: 3 additions & 1 deletion crates/core/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,9 @@ impl Types {
info = self.optional_type_info(resolve, r.ok.as_ref());
info |= self.optional_type_info(resolve, r.err.as_ref());
}
TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::ErrorContext => {}
TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::ErrorContext => {
info.has_resource = true;
}
TypeDefKind::Unknown => unreachable!(),
}
let prev = self.type_info.insert(ty, info);
Expand Down
15 changes: 15 additions & 0 deletions crates/csharp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1903,6 +1903,21 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
self.type_name(&Type::Id(id));
}

fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
_ = (id, name, ty, docs);
todo!()
}

fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
_ = (id, name, ty, docs);
todo!()
}

fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) {
_ = (id, name, docs);
todo!()
}

fn type_builtin(&mut self, _id: TypeId, _name: &str, _ty: &Type, _docs: &Docs) {
unimplemented!();
}
Expand Down
8 changes: 8 additions & 0 deletions crates/csharp/tests/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ use std::{
use wit_component::StringEncoding;

macro_rules! codegen_test {
// TODO: implement support for stream, future, and error-context, and then
// remove these lines:
(streams $name:tt $test:tt) => {};
(futures $name:tt $test:tt) => {};
(resources_with_streams $name:tt $test:tt) => {};
(resources_with_futures $name:tt $test:tt) => {};
(error_context $name:tt $test:tt) => {};

($id:ident $name:tt $test:tt) => {
#[test]
fn $id() {
Expand Down
15 changes: 15 additions & 0 deletions crates/go/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,21 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
// no impl since these types are generated as anonymous types
}

fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
_ = (id, name, ty, docs);
todo!()
}

fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
_ = (id, name, ty, docs);
todo!()
}

fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) {
_ = (id, name, docs);
todo!()
}

fn type_builtin(&mut self, _id: TypeId, _name: &str, _ty: &Type, _docs: &Docs) {
todo!("type_builtin")
}
Expand Down
9 changes: 9 additions & 0 deletions crates/go/tests/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ use heck::*;
macro_rules! codegen_test {
(issue668 $name:tt $test:tt) => {};
(multiversion $name:tt $test:tt) => {};

// TODO: implement support for stream, future, and error-context, and then
// remove these lines:
(streams $name:tt $test:tt) => {};
(futures $name:tt $test:tt) => {};
(resources_with_streams $name:tt $test:tt) => {};
(resources_with_futures $name:tt $test:tt) => {};
(error_context $name:tt $test:tt) => {};

($id:ident $name:tt $test:tt) => {
#[test]
fn $id() {
Expand Down
15 changes: 15 additions & 0 deletions crates/markdown/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,21 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
self.type_alias(id, name, &Type::Id(id), docs);
}

fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
_ = (id, name, ty, docs);
todo!()
}

fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
_ = (id, name, ty, docs);
todo!()
}

fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) {
_ = (id, name, docs);
todo!()
}

fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
self.type_alias(id, name, ty, docs)
}
Expand Down
15 changes: 15 additions & 0 deletions crates/moonbit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,21 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
// Not needed
}

fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
_ = (id, name, ty, docs);
todo!()
}

fn type_stream(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs) {
_ = (id, name, ty, docs);
todo!()
}

fn type_error_context(&mut self, id: TypeId, name: &str, docs: &Docs) {
_ = (id, name, docs);
todo!()
}

fn type_builtin(&mut self, _id: TypeId, _name: &str, _ty: &Type, _docs: &Docs) {
unimplemented!();
}
Expand Down
8 changes: 8 additions & 0 deletions crates/moonbit/tests/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ use std::path::Path;
use std::process::Command;

macro_rules! codegen_test {
// TODO: implement support for stream, future, and error-context, and then
// remove these lines:
(streams $name:tt $test:tt) => {};
(futures $name:tt $test:tt) => {};
(resources_with_streams $name:tt $test:tt) => {};
(resources_with_futures $name:tt $test:tt) => {};
(error_context $name:tt $test:tt) => {};

($id:ident $name:tt $test:tt) => {
#[test]
fn $id() {
Expand Down
1 change: 1 addition & 0 deletions crates/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ syn = { workspace = true }
prettyplease = { workspace = true }

[dev-dependencies]
futures = { workspace = true }
wit-bindgen = { path = '../guest-rust' }
wit-bindgen-rt = { path = '../guest-rust/rt' }
test-helpers = { path = '../test-helpers' }
Expand Down
56 changes: 54 additions & 2 deletions crates/rust/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2694,6 +2694,48 @@ impl<'a> {camel}Borrow<'a>{{
}
}

fn type_future(&mut self, _id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs) {
let stream_and_future_support = self.path_to_stream_and_future_support();
let mode = TypeMode {
style: TypeOwnershipStyle::Owned,
lists_borrowed: false,
lifetime: None,
};
self.rustdoc(docs);
self.push_str(&format!("pub type {}", name.to_upper_camel_case()));
self.print_generics(mode.lifetime);
self.push_str(" = ");
self.push_str(&format!("{stream_and_future_support}::FutureReader<"));
self.print_optional_ty(ty.as_ref(), mode);
self.push_str(">");
self.push_str(";\n");
}

fn type_stream(&mut self, _id: TypeId, name: &str, ty: &Type, docs: &Docs) {
let stream_and_future_support = self.path_to_stream_and_future_support();
let mode = TypeMode {
style: TypeOwnershipStyle::Owned,
lists_borrowed: false,
lifetime: None,
};
self.rustdoc(docs);
self.push_str(&format!("pub type {}", name.to_upper_camel_case()));
self.print_generics(mode.lifetime);
self.push_str(" = ");
self.push_str(&format!("{stream_and_future_support}::StreamReader<"));
self.print_ty(ty, mode);
self.push_str(">");
self.push_str(";\n");
}

fn type_error_context(&mut self, _id: TypeId, name: &str, docs: &Docs) {
let async_support = self.path_to_async_support();
self.rustdoc(docs);
self.push_str(&format!("pub type {} = ", name.to_upper_camel_case()));
self.push_str(&format!("{async_support}::ErrorContext"));
self.push_str(";\n");
}

fn type_builtin(&mut self, _id: TypeId, name: &str, ty: &Type, docs: &Docs) {
self.rustdoc(docs);
self.src
Expand Down Expand Up @@ -2784,17 +2826,27 @@ impl<'a, 'b> wit_bindgen_core::AnonymousTypeGenerator<'a> for AnonTypeGenerator<

fn anonymous_type_future(&mut self, _id: TypeId, ty: &Option<Type>, _docs: &Docs) {
let stream_and_future_support = self.interface.path_to_stream_and_future_support();
let mode = TypeMode {
style: TypeOwnershipStyle::Owned,
lists_borrowed: false,
lifetime: None,
};
self.interface
.push_str(&format!("{stream_and_future_support}::FutureReader<"));
self.interface.print_optional_ty(ty.as_ref(), self.mode);
self.interface.print_optional_ty(ty.as_ref(), mode);
self.interface.push_str(">");
}

fn anonymous_type_stream(&mut self, _id: TypeId, ty: &Type, _docs: &Docs) {
let stream_and_future_support = self.interface.path_to_stream_and_future_support();
let mode = TypeMode {
style: TypeOwnershipStyle::Owned,
lists_borrowed: false,
lifetime: None,
};
self.interface
.push_str(&format!("{stream_and_future_support}::StreamReader<"));
self.interface.print_ty(ty, self.mode);
self.interface.print_ty(ty, mode);
self.interface.push_str(">");
}

Expand Down
2 changes: 1 addition & 1 deletion crates/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ impl RustWasm {
self.src.push_str("}\n");
if emitted.contains(&RuntimeItem::StreamAndFutureSupport) {
self.src
.push_str("pub use _rt::stream_and_future_support;\n");
.push_str("#[allow(unused_imports)]\npub use _rt::stream_and_future_support;\n");
}
}

Expand Down
33 changes: 33 additions & 0 deletions crates/rust/src/stream_and_future_support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use {
std::{
collections::hash_map::Entry,
convert::Infallible,
fmt,
future::{Future, IntoFuture},
iter,
marker::PhantomData,
Expand All @@ -33,6 +34,14 @@ pub struct FutureWriter<T: FuturePayload> {
_phantom: PhantomData<T>,
}

impl<T: FuturePayload> fmt::Debug for FutureWriter<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FutureWriter")
.field("handle", &self.handle)
.finish()
}
}

impl<T: FuturePayload> FutureWriter<T> {
/// Write the specified value to this `future`.
pub async fn write(self, v: T) {
Expand Down Expand Up @@ -101,6 +110,14 @@ pub struct FutureReader<T: FuturePayload> {
_phantom: PhantomData<T>,
}

impl<T: FuturePayload> fmt::Debug for FutureReader<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FutureReader")
.field("handle", &self.handle)
.finish()
}
}

impl<T: FuturePayload> FutureReader<T> {
#[doc(hidden)]
pub fn from_handle(handle: u32) -> Self {
Expand Down Expand Up @@ -219,6 +236,14 @@ pub struct StreamWriter<T: StreamPayload> {
_phantom: PhantomData<T>,
}

impl<T: StreamPayload> fmt::Debug for StreamWriter<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("StreamWriter")
.field("handle", &self.handle)
.finish()
}
}

impl<T: StreamPayload> Sink<Vec<T>> for StreamWriter<T> {
type Error = Infallible;

Expand Down Expand Up @@ -334,6 +359,14 @@ pub struct StreamReader<T: StreamPayload> {
_phantom: PhantomData<T>,
}

impl<T: StreamPayload> fmt::Debug for StreamReader<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("StreamReader")
.field("handle", &self.handle)
.finish()
}
}

impl<T: StreamPayload> StreamReader<T> {
#[doc(hidden)]
pub fn from_handle(handle: u32) -> Self {
Expand Down
Loading

0 comments on commit 672a70a

Please sign in to comment.