diff --git a/crates/csharp/src/AsyncSupport.cs b/crates/csharp/src/AsyncSupport.cs index a80ec6e4a..837d63f68 100644 --- a/crates/csharp/src/AsyncSupport.cs +++ b/crates/csharp/src/AsyncSupport.cs @@ -2,8 +2,174 @@ * Helpers for the async support. */ - public enum CallbackCode +public enum CallbackCode { Exit = 0, Yield = 1, } + +public partial class WaitableSet(int handle) : IDisposable +{ + public int Handle { get; } = handle; + + void Dispose(bool _disposing) + { + AsyncSupport.WaitableSetDrop(this); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + ~WaitableSet() + { + Dispose(false); + } +} + +public static class AsyncSupport +{ + private static class Interop + { + [global::System.Runtime.InteropServices.DllImportAttribute("$root", EntryPoint = "[waitable-set-new]"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] + internal static extern int WaitableSetNew(); + + [global::System.Runtime.InteropServices.DllImportAttribute("$root", EntryPoint = "[waitable-join]"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] + internal static extern void WaitableJoin(int waitable, int set); + + [global::System.Runtime.InteropServices.DllImportAttribute("$root", EntryPoint = "[waitable-set-wait]"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] + internal static unsafe extern int WaitableSetWait(int waitable, int* waitableHandlePtr); + + [global::System.Runtime.InteropServices.DllImportAttribute("$root", EntryPoint = "[waitable-set-drop]"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] + internal static unsafe extern void WaitableSetDrop(int waitable); + } + + public static WaitableSet WaitableSetNew() + {{ + var waitable = Interop.WaitableSetNew(); + return new WaitableSet(waitable); + }} + + public static void Join(FutureWriter writer, WaitableSet set) + {{ + Interop.WaitableJoin(writer.Handle, set.Handle); + }} + + public unsafe static EventWaitable WaitableSetWait(WaitableSet set) + {{ + int* buffer = stackalloc int[2]; + var eventCode = (EventCode)Interop.WaitableSetWait(set.Handle, buffer); + return new EventWaitable(eventCode, buffer[0], buffer[1]); + }} + + public static void WaitableSetDrop(WaitableSet set) + {{ + Interop.WaitableSetDrop(set.Handle); + }} +} + +/** + * Helpers for future reader support. + */ +public abstract class FutureReader(int handle) : IDisposable // : TODO Waitable +{ + public int Handle { get; private set; } = handle; + + public int TakeHandle() + { + if(Handle == 0) + { + throw new InvalidOperationException("Handle already taken"); + } + var handle = Handle; + Handle = 0; + return handle; + } + + // TODO: Generate per type for this instrinsic. + public Task Read() + { + // TODO: Generate for the interop name and the namespace. + + var status = new WaitableStatus(ReadInternal()); + if (status.IsBlocked) + { + //TODO: store somewhere so we can complete it later. + var tcs = new TaskCompletionSource(); + + return tcs.Task; + } + if (status.IsCompleted) + { + return Task.CompletedTask; + } + + throw new NotImplementedException(); + } + + void Dispose(bool _disposing) + { + // Free unmanaged resources if any. + Drop(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + ~FutureReader() + { + Dispose(false); + } + + protected abstract int ReadInternal(); + protected abstract void Drop(); +} + +/** + * Helpers for future writer support. + */ +public abstract class FutureWriter(int handle) // : TODO Waitable +{ + public int Handle { get; } = handle; + + // TODO: Generate per type for this instrinsic. + public Task Write() + { + // TODO: Generate for the interop name. + var status = new WaitableStatus(Write(Handle, IntPtr.Zero)); + if (status.IsBlocked) + { + //TODO: store somewhere so we can complete it later. + var tcs = new TaskCompletionSource(); + return tcs.Task; + } + + throw new NotImplementedException(); + } + + protected abstract void Drop(); + + void Dispose(bool _disposing) + { + // Free unmanaged resources if any. + Drop(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + ~FutureWriter() + { + Dispose(false); + } + + protected abstract int Write(int handle, IntPtr buffer); +} diff --git a/crates/csharp/src/FutureCommonSupport.cs b/crates/csharp/src/FutureCommonSupport.cs new file mode 100644 index 000000000..a5c4e6f19 --- /dev/null +++ b/crates/csharp/src/FutureCommonSupport.cs @@ -0,0 +1,39 @@ +/** + * Helpers for future support. + */ + +public readonly struct WaitableStatus (int status) +{ + public int State => status & 0xf; + public int Count => (int)(status >> 4); + public bool IsBlocked => status == -1; + public bool IsCompleted => State == 0; + public bool IsDropped => State == 1; +} + +public enum EventCode +{ + None, + Subtask, + StreamRead, + StreamWrite, + FutureRead, + FutureWrite, + Cancel, +} + +public readonly struct EventWaitable +{ + public EventWaitable(EventCode eventCode, int waitable, int code) + { + Event = eventCode; + Waitable = waitable; + Status = new WaitableStatus(code); + } + public readonly EventCode Event; + public readonly int Waitable; + public readonly int Code; + + public readonly WaitableStatus Status; +} + diff --git a/crates/csharp/src/csproj.rs b/crates/csharp/src/csproj.rs index ebd6c4276..52661d877 100644 --- a/crates/csharp/src/csproj.rs +++ b/crates/csharp/src/csproj.rs @@ -109,11 +109,10 @@ impl CSProjectLLVMBuilder { csproj.push_str( &format!( r#" - - - - - "#), + + + + "#), ); fs::write( @@ -153,8 +152,9 @@ impl CSProjectLLVMBuilder { } csproj.push_str( - r#" - "#, + r#" + +"#, ); fs::write(self.dir.join(format!("{camel}.csproj")), csproj)?; diff --git a/crates/csharp/src/function.rs b/crates/csharp/src/function.rs index c22389c2a..e06b79eea 100644 --- a/crates/csharp/src/function.rs +++ b/crates/csharp/src/function.rs @@ -33,6 +33,7 @@ pub(crate) struct FunctionBindgen<'a, 'b> { fixed_statments: Vec, parameter_type: ParameterType, result_type: Option, + pub(crate) resource_type_name: Option, } impl<'a, 'b> FunctionBindgen<'a, 'b> { @@ -70,6 +71,7 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> { fixed_statments: Vec::new(), parameter_type: parameter_type, result_type: result_type, + resource_type_name: None, } } @@ -166,7 +168,7 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> { .drain(self.blocks.len() - cases.len()..) .collect::>(); let ty = self.interface_gen.type_name_with_qualifier(ty, true); - //let ty = self.gen.type_name(ty); + //let ty = self.r#gentype_name(ty); let generics_position = ty.find('<'); let lifted = self.locals.tmp("lifted"); @@ -1065,9 +1067,32 @@ impl Bindgen for FunctionBindgen<'_, '_> { None => operands.join(", "), }; + let (_namespace, interface_name) = + &CSharp::get_class_name_from_qualified_name(self.interface_gen.name); + let mut interop_name = format!("{}ImportsInterop", interface_name.strip_prefix("I").unwrap() + .strip_suffix(if self.interface_gen.direction == Direction::Import { "Imports" } else { "Exports" }).unwrap().to_upper_camel_case()); + + if self.interface_gen.is_world && self.interface_gen.direction == Direction::Import { + interop_name = format!("Imports.{interop_name}"); + } + + let resource_type_name = match self.kind { + FunctionKind::Method(resource_type_id) | + FunctionKind::Static(resource_type_id) | + FunctionKind::Constructor(resource_type_id) => { + format!( + ".{}", + self.interface_gen.csharp_gen.all_resources[resource_type_id] + .name + .to_upper_camel_case() + ) + } + _ => String::new(), + }; + uwriteln!( self.src, - "{assignment} {func_name}WasmInterop.wasmImport{func_name}({operands});" + "{assignment} {interop_name}{resource_type_name}.{func_name}WasmInterop.wasmImport{func_name}({operands});" ); if let Some(buffer) = async_return_buffer { @@ -1367,6 +1392,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { } else { uwriteln!(self.src, "var {resource} = ({export_name}) {export_name}.repTable.Get({op});"); } + self.resource_type_name = Some(export_name); } } results.push(resource); @@ -1376,8 +1402,10 @@ impl Bindgen for FunctionBindgen<'_, '_> { results.extend(operands.iter().take(*amt).map(|v| v.clone())); } - Instruction::FutureLower { .. } => { + Instruction::FutureLower { payload: _, ty } => { let op = &operands[0]; + self.interface_gen.add_future(self.func_name, ty); + results.push(format!("{op}.Handle")); } @@ -1385,8 +1413,18 @@ impl Bindgen for FunctionBindgen<'_, '_> { uwriteln!(self.src, "// TODO_task_cancel.forget();"); } - Instruction::FutureLift { .. } - | Instruction::StreamLower { .. } + Instruction::FutureLift { payload: _, ty } => { + // TODO get the prefix for the type + let sig_type_name = "Void"; + let reader_var = self.locals.tmp("reader"); + uwriteln!(self.src, "var {reader_var} = new {}.FutureReader{}({});", self.interface_gen.name, sig_type_name, operands[0]); + results.push(reader_var); + + self.interface_gen.add_future(self.func_name, ty); + self.interface_gen.csharp_gen.needs_async_support = true; + } + + Instruction::StreamLower { .. } | Instruction::StreamLift { .. } | Instruction::ErrorContextLower { .. } | Instruction::ErrorContextLift { .. } @@ -1421,7 +1459,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { uwrite!( self.src, " - var {ret_area} = stackalloc {element_type}[{array_size}+1]; + var {ret_area} = stackalloc {element_type}[{array_size} + 1]; var {ptr} = ((int){ret_area}) + ({align} - 1) & -{align}; ", align = align.align_wasm32() @@ -1490,7 +1528,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { } /// Dereference any number `TypeDefKind::Type` aliases to retrieve the target type. -fn dealias(resolve: &Resolve, mut id: TypeId) -> TypeId { +pub fn dealias(resolve: &Resolve, mut id: TypeId) -> TypeId { loop { match &resolve.types[id].kind { TypeDefKind::Type(Type::Id(that_id)) => id = *that_id, diff --git a/crates/csharp/src/interface.rs b/crates/csharp/src/interface.rs index 4f30b8f68..c6f04bbff 100644 --- a/crates/csharp/src/interface.rs +++ b/crates/csharp/src/interface.rs @@ -4,6 +4,7 @@ use crate::function::ResourceInfo; use crate::world_generator::CSharp; use heck::{ToShoutySnakeCase, ToUpperCamelCase}; use std::collections::HashMap; +use std::collections::HashSet; use std::fmt::Write; use std::ops::Deref; use wit_bindgen_core::abi::LiftLower; @@ -20,6 +21,7 @@ pub(crate) struct InterfaceFragment { pub(crate) csharp_src: String, pub(crate) csharp_interop_src: String, pub(crate) stub: String, + pub(crate) direction: Option, // Types do not have a direction. } pub(crate) struct InterfaceTypeAndFragments { @@ -36,6 +38,11 @@ impl InterfaceTypeAndFragments { } } +pub(crate) struct FutureInfo { + pub name: String, + pub ty: TypeId, +} + /// InterfaceGenerator generates the C# code for wit interfaces. /// It produces types by interface in wit and then generates the interop code /// by calling out to FunctionGenerator @@ -47,6 +54,8 @@ pub(crate) struct InterfaceGenerator<'a> { pub(crate) resolve: &'a Resolve, pub(crate) name: &'a str, pub(crate) direction: Direction, + pub(crate) futures: Vec, + pub(crate) is_world: bool, } impl InterfaceGenerator<'_> { @@ -132,11 +141,12 @@ impl InterfaceGenerator<'_> { } pub(crate) fn qualifier(&self, when: bool, ty: &TypeId) -> String { + let type_def = &self.resolve.types[*ty]; + // anonymous types dont get an owner from wit-parser, so assume they are part of an interface here. let owner = if let Some(owner_type) = self.csharp_gen.anonymous_type_owners.get(ty) { *owner_type } else { - let type_def = &self.resolve.types[*ty]; type_def.owner }; @@ -151,13 +161,37 @@ impl InterfaceGenerator<'_> { } if when { - let name = self.name; + let mut name = self.name; + let tmp_name: String; + if self.is_world { + if CSharp::type_is_bidirectional(self.resolve(), ty) { + name = name.rsplitn(2, ".").nth(1).unwrap(); + } + // World level types, except resources are always imports. + else if name.ends_with("Exports") && type_def.kind != TypeDefKind::Resource { + tmp_name = Self::replace_last(&name, "Exports", "Imports"); + name = &tmp_name; + } + } format!("{global_prefix}{name}.") } else { String::new() } } + fn replace_last(haystack: &str, needle: &str, replacement: &str) -> String { + if let Some(pos) = haystack.rfind(needle) { + let mut result = + String::with_capacity(haystack.len() - needle.len() + replacement.len()); + result.push_str(&haystack[..pos]); + result.push_str(replacement); + result.push_str(&haystack[pos + needle.len()..]); + result + } else { + haystack.to_string() + } + } + pub(crate) fn add_interface_fragment(self, is_export: bool) { self.csharp_gen .interface_fragments @@ -168,14 +202,146 @@ impl InterfaceGenerator<'_> { csharp_src: self.src, csharp_interop_src: self.csharp_interop_src, stub: self.stub, + direction: Some(self.direction), + }); + } + + pub(crate) fn add_futures(&mut self, import_module_name: &str) { + if self.futures.is_empty() { + return; + } + + let (_namespace, interface_name) = &CSharp::get_class_name_from_qualified_name(self.name); + let interop_name = format!("{}Interop", interface_name.strip_prefix("I").unwrap()); + let mut generated_future_types: HashSet = HashSet::new(); + + for future in &self.futures { + let future_name = &future.name; + if !generated_future_types.contains(&future.ty) { + uwrite!( + self.csharp_interop_src, + r#" + [global::System.Runtime.InteropServices.DllImportAttribute("{import_module_name}", EntryPoint = "[future-new-0][async]{future_name}"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] + internal static extern ulong FutureNew(); + "# + ); + + // TODO: Move this and other type dependent functions out to another function. + uwrite!( + self.csharp_interop_src, + r#" + [global::System.Runtime.InteropServices.DllImportAttribute("{import_module_name}", EntryPoint = "[future-cancel-read-0][async]{future_name}"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] + internal static extern uint FutureCancelRead(int readable); + "# + ); + + uwrite!( + self.csharp_interop_src, + r#" + [global::System.Runtime.InteropServices.DllImportAttribute("{import_module_name}", EntryPoint = "[future-cancel-write-0][async]{future_name}"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] + internal static extern uint FutureCancelWrite(int writeable); + "# + ); + + uwrite!( + self.csharp_interop_src, + r#" + [global::System.Runtime.InteropServices.DllImportAttribute("{import_module_name}", EntryPoint = "[future-drop-writeable-0][async]{future_name}"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] + internal static extern void FutureDropWriteable(int writeable); + "# + ); + + self.csharp_gen + .interface_fragments + .entry(self.name.to_string()) + .or_insert_with(|| InterfaceTypeAndFragments::new(false)) + .interface_fragments + .push(InterfaceFragment { + csharp_src: format!(r#" + public static (FutureReader, FutureWriter) FutureNew() + {{ + var packed = {interop_name}.FutureNew(); + var readerHandle = (int)(packed & 0xFFFFFFFF); + var writerHandle = (int)(packed >> 32); + + return (new FutureReaderVoid(readerHandle), new FutureWriterVoid(writerHandle)); + }} + "#).to_string(), + csharp_interop_src: "".to_string(), + stub: "".to_string(), + direction: Some(self.direction), + }); + generated_future_types.insert(future.ty); + } + } + + self.csharp_gen.needs_async_support = true; + + // TODO: When we do the next type, switch to a generic implementation with a vtable style call + // for the interop functions. This will align c# with other lanaguage implementations. + let future_type_name = "Void"; + + self.csharp_gen + .interface_fragments + .entry(self.name.to_string()) + .or_insert_with(|| InterfaceTypeAndFragments::new(false)) + .interface_fragments + .push(InterfaceFragment { + csharp_src: format!(r#" + public class FutureReader{future_type_name} : FutureReader + {{ + public FutureReader{future_type_name}(int handle) : base(handle) {{ }} + + protected override int ReadInternal() + {{ + return {interop_name}.FutureRead{future_type_name}(Handle, IntPtr.Zero); + }} + + protected override void Drop() + {{ + {interop_name}.FutureDropReader{future_type_name}(Handle); + }} + }} + + public class FutureWriter{future_type_name} : FutureWriter + {{ + public FutureWriter{future_type_name}(int handle) : base(handle) {{ }} + + protected override int Write(int handle, IntPtr buffer) + {{ + return {interop_name}.FutureWrite{future_type_name}(handle, buffer); + }} + + protected override void Drop() + {{ + {interop_name}.FutureDropWriter{future_type_name}(Handle); + }} + }} + "#).to_string(), + csharp_interop_src: format!(r#" + [global::System.Runtime.InteropServices.DllImportAttribute("{import_module_name}", EntryPoint = "[async-lower][future-read-0][async]read-future"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] + internal static unsafe extern int FutureRead{future_type_name}(int readable, IntPtr ptr); + + [global::System.Runtime.InteropServices.DllImportAttribute("{import_module_name}", EntryPoint = "[async-lower][future-write-0][async]read-future"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] + internal static unsafe extern int FutureWrite{future_type_name}(int writeable, IntPtr buffer); + + [global::System.Runtime.InteropServices.DllImportAttribute("{import_module_name}", EntryPoint = "[future-drop-readable-0][async]read-future"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] + internal static extern void FutureDropReader{future_type_name}(int readable); + + [global::System.Runtime.InteropServices.DllImportAttribute("{import_module_name}", EntryPoint = "[future-drop-writable-0][async]read-future"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] + internal static extern void FutureDropWriter{future_type_name}(int readable); + "#).to_string(), + stub: "".to_string(), + direction: Some(self.direction), }); } - pub(crate) fn add_world_fragment(self) { + pub(crate) fn add_world_fragment(self, direction: Option) { self.csharp_gen.world_fragments.push(InterfaceFragment { csharp_src: self.src, csharp_interop_src: self.csharp_interop_src, stub: self.stub, + direction, }); } @@ -279,14 +445,8 @@ impl InterfaceGenerator<'_> { func.name.to_string() }; - let target = if let FunctionKind::Freestanding = &func.kind { - &mut self.csharp_interop_src - } else { - &mut self.src - }; - uwrite!( - target, + self.csharp_interop_src, r#" internal static class {interop_camel_name}WasmInterop {{ @@ -298,7 +458,7 @@ impl InterfaceGenerator<'_> { for (src, params) in funcs { uwrite!( - target, + self.src, r#" {access} {modifiers} unsafe {result_type} {camel_name}({params}) {{ @@ -480,6 +640,7 @@ impl InterfaceGenerator<'_> { ); let src = bindgen.src; + let resource_type_name = bindgen.resource_type_name; let vars = bindgen .resource_drops @@ -518,7 +679,7 @@ impl InterfaceGenerator<'_> { 0 }) .map(|(name, ty)| { - let ty = self.type_name(ty); + let ty = self.type_name_with_qualifier(ty, true); let name = name.to_csharp_ident(); format!("{ty} {name}") }) @@ -588,19 +749,33 @@ impl InterfaceGenerator<'_> { if async_ { let import_module_name = &self.resolve.name_world_key(interface_name.unwrap()); + let (_namespace, interface_name) = + &CSharp::get_class_name_from_qualified_name(self.name); + let impl_name = if resource_type_name.is_some() { + resource_type_name.unwrap() + } else { + format!("{}Impl", interface_name.strip_prefix("I").unwrap()) + }; uwriteln!( self.csharp_interop_src, r#" [global::System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute(EntryPoint = "[callback][async-lift]{import_module_name}#{wasm_func_name}")] - public static uint {camel_name}Callback(uint eventRaw, uint waitable, uint code) + public static int {camel_name}Callback(uint eventRaw, uint waitable, uint code) {{ // TODO: decode the parameters - return (uint)CallbackCode.Exit; + return {impl_name}.{camel_name}Callback(); }} "# ); + uwriteln!( + self.src, + r#" + public static abstract int {camel_name}Callback(); + "# + ); + // TODO: The task return function can take up to 16 core parameters. let task_return_param = match &sig.results[..] { [] => "", @@ -628,12 +803,19 @@ impl InterfaceGenerator<'_> { } if self.csharp_gen.opts.generate_stub { - let sig = self.sig_string(func, true); + let sig: String = self.sig_string(func, true); + let func_name = func.item_name().to_upper_camel_case(); uwrite!( self.stub, r#" - {sig} {{ + {sig} + {{ + throw new global::System.NotImplementedException(); + }} + + public static int {func_name}Callback(/* TODO: event arg */) + {{ throw new global::System.NotImplementedException(); }} "# @@ -787,9 +969,10 @@ impl InterfaceGenerator<'_> { .map(|ty| self.type_name_with_qualifier(ty, qualifier)) .unwrap_or_else(|| "".to_owned()); if name.is_empty() { - return "Task".to_owned(); + return "FutureReader".to_owned(); } else { - return format!("Task<{name}>"); + // TODO: When we add more future types, this will become a generic. + return format!("FutureReader{name}"); } } _ => { @@ -972,6 +1155,7 @@ impl InterfaceGenerator<'_> { {access} interface I{upper_camel} {{ "# ); + self.csharp_gen.needs_rep_table = true; if self.csharp_gen.opts.generate_stub { let super_ = self.type_name_with_qualifier(&Type::Id(id), true); @@ -995,6 +1179,14 @@ impl InterfaceGenerator<'_> { } } }; + + uwrite!( + self.csharp_interop_src, + r#" + internal static class {upper_camel} + {{ + "# + ); } pub(crate) fn end_resource(&mut self) { @@ -1013,6 +1205,13 @@ impl InterfaceGenerator<'_> { }} " ); + + uwrite!( + self.csharp_interop_src, + " + }} + " + ); } fn sig_string(&mut self, func: &Function, qualifier: bool) -> String { @@ -1052,6 +1251,10 @@ impl InterfaceGenerator<'_> { format!("{access} {modifiers} {result_type} {camel_name}({params})") } + + pub(crate) fn add_future(&mut self, func_name: &str, ty: &TypeId) { + self.futures.push(FutureInfo { name: func_name.to_string(), ty: ty.clone() }); + } } impl<'a> CoreInterfaceGenerator<'a> for InterfaceGenerator<'a> { @@ -1265,7 +1468,7 @@ impl<'a> CoreInterfaceGenerator<'a> for InterfaceGenerator<'a> { self.type_name(&Type::Id(id)); } - fn type_enum(&mut self, _id: TypeId, name: &str, enum_: &Enum, docs: &Docs) { + fn type_enum(&mut self, ty: TypeId, name: &str, enum_: &Enum, docs: &Docs) { self.print_docs(docs); let name = name.to_upper_camel_case(); @@ -1279,14 +1482,28 @@ impl<'a> CoreInterfaceGenerator<'a> for InterfaceGenerator<'a> { let access = self.csharp_gen.access_modifier(); - uwrite!( - self.src, - " - {access} enum {name} {{ - {cases} - }} - " - ); + // Write the top level bidirectional types to csharp_gen. Could also create a class to gather the interface level bidrectional types. + match &self.resolve.types[ty].owner { + TypeOwner::World(_id) => { + self.csharp_gen.bidirectional_types_src.insert(format!( + " + {access} enum {name} {{ + {cases} + }} + " + )); + } + _ => { + uwrite!( + self.src, + " + {access} enum {name} {{ + {cases} + }} + " + ); + } + }; } fn type_alias(&mut self, id: TypeId, _name: &str, _ty: &Type, _docs: &Docs) { @@ -1380,10 +1597,9 @@ fn modifiers(func: &Function, name: &str, direction: Direction) -> String { _ => "", }; - let abstract_modifier = if direction == Direction::Export { - " abstract" - } else { - "" + let abstract_modifier = match (direction, &func.kind) { + (Direction::Export, _) => " abstract", + _ => "", }; let async_modifier = match &func.kind { diff --git a/crates/csharp/src/world_generator.rs b/crates/csharp/src/world_generator.rs index 205e47cba..6ace9c2ea 100644 --- a/crates/csharp/src/world_generator.rs +++ b/crates/csharp/src/world_generator.rs @@ -12,7 +12,8 @@ use wit_bindgen_core::{Direction, Files, InterfaceGenerator as _, WorldGenerator use wit_component::WitPrinter; use wit_parser::abi::WasmType; use wit_parser::{ - Function, InterfaceId, Resolve, SizeAlign, Type, TypeId, TypeOwner, WorldId, WorldKey, + Function, InterfaceId, Resolve, SizeAlign, Type, TypeDefKind, TypeId, TypeOwner, WorldId, + WorldItem, WorldKey, }; /// CSharp is the world generator for wit files. It coordinates all the generated code. @@ -41,6 +42,9 @@ pub struct CSharp { pub(crate) all_resources: HashMap, pub(crate) world_resources: HashMap, pub(crate) import_funcs_called: bool, + + // Top level types that are bidirectional like enums, to save code size and not duplicate whene unnecessary. + pub(crate) bidirectional_types_src: HashSet, } impl CSharp { @@ -62,6 +66,7 @@ impl CSharp { resolve: &'a Resolve, name: &'a str, direction: Direction, + is_world: bool, ) -> InterfaceGenerator<'a> { InterfaceGenerator { src: String::new(), @@ -71,6 +76,8 @@ impl CSharp { resolve, name, direction, + futures: Vec::new(), + is_world, } } @@ -87,6 +94,50 @@ impl CSharp { (String::new(), String::new()) } } + + // We can share some types to save some code size and allow a more intuitive user experience. + pub(crate) fn type_is_bidirectional(resolve: &Resolve, ty: &TypeId) -> bool { + let type_def = &resolve.types[*ty]; + let kind = &type_def.kind; + + return match kind { + TypeDefKind::Flags(_) => true, + TypeDefKind::Enum(_) => true, + _ => false, + }; + } + + fn write_world_fragments( + &mut self, + direction: Direction, + direction_name: &str, + src: &mut String, + access: &str, + name: &String, + ) { + if self + .world_fragments + .iter() + .any(|f| f.direction == Some(direction)) + { + uwrite!( + src, + " + {access} interface I{name}World{direction_name}{{ + " + ); + src.push_str( + &self + .world_fragments + .iter() + .filter(|f| f.direction == Some(direction)) + .map(|f| f.csharp_src.deref()) + .collect::>() + .join("\n"), + ); + src.push_str("}\n"); + } + } } impl WorldGenerator for CSharp { @@ -105,14 +156,14 @@ impl WorldGenerator for CSharp { ) -> anyhow::Result<()> { let name = interface_name(self, resolve, key, Direction::Import); self.interface_names.insert(id, name.clone()); - let mut r#gen = self.interface(resolve, &name, Direction::Import); + let mut r#gen = self.interface(resolve, &name, Direction::Import, false); let mut old_resources = mem::take(&mut r#gen.csharp_gen.all_resources); r#gen.types(id); let new_resources = mem::take(&mut r#gen.csharp_gen.all_resources); old_resources.extend(new_resources.clone()); r#gen.csharp_gen.all_resources = old_resources; - + let import_module_name = &resolve.name_world_key(key); for (resource, funcs) in by_resource( resolve.interfaces[id] .functions @@ -124,7 +175,6 @@ impl WorldGenerator for CSharp { r#gen.start_resource(resource, Some(key)); } - let import_module_name = &resolve.name_world_key(key); for func in funcs { r#gen.import(import_module_name, func); } @@ -137,6 +187,8 @@ impl WorldGenerator for CSharp { // for anonymous types r#gen.define_interface_types(id); + r#gen.add_futures(import_module_name); + r#gen.add_interface_fragment(false); Ok(()) @@ -152,9 +204,10 @@ impl WorldGenerator for CSharp { self.import_funcs_called = true; let name = &format!("{}-world", resolve.worlds[world].name).to_upper_camel_case(); - let name = &format!("{name}.I{name}"); - let mut r#gen = self.interface(resolve, name, Direction::Import); + let name = &format!("{name}.I{name}Imports"); + let mut r#gen = self.interface(resolve, name, Direction::Import, true); + //TODO: This generates resource types for imports even when not used, i.e. no imported functions. for (resource, funcs) in by_resource( funcs.iter().copied(), r#gen.csharp_gen.world_resources.keys().copied(), @@ -172,7 +225,7 @@ impl WorldGenerator for CSharp { } } - r#gen.add_world_fragment(); + r#gen.add_world_fragment(Some(Direction::Import)); } fn export_interface( @@ -184,14 +237,13 @@ impl WorldGenerator for CSharp { ) -> anyhow::Result<()> { let name = interface_name(self, resolve, key, Direction::Export); self.interface_names.insert(id, name.clone()); - let mut r#gen = self.interface(resolve, &name, Direction::Export); + let mut r#gen = self.interface(resolve, &name, Direction::Export, false); let mut old_resources = mem::take(&mut r#gen.csharp_gen.all_resources); r#gen.types(id); let new_resources = mem::take(&mut r#gen.csharp_gen.all_resources); old_resources.extend(new_resources.clone()); r#gen.csharp_gen.all_resources = old_resources; - for (resource, funcs) in by_resource( resolve.interfaces[id] .functions @@ -215,6 +267,9 @@ impl WorldGenerator for CSharp { // for anonymous types r#gen.define_interface_types(id); + let import_module_name = &resolve.name_world_key(key); + r#gen.add_futures(&format!("[export]{import_module_name}")); + r#gen.add_interface_fragment(true); Ok(()) } @@ -222,15 +277,39 @@ impl WorldGenerator for CSharp { fn export_funcs( &mut self, resolve: &Resolve, - world: WorldId, + world_id: WorldId, funcs: &[(&str, &Function)], _files: &mut Files, ) -> anyhow::Result<()> { - let name = &format!("{}-world", resolve.worlds[world].name).to_upper_camel_case(); - let name = &format!("{name}.I{name}"); - let mut r#gen = self.interface(resolve, name, Direction::Export); + let name = &format!("{}-world", resolve.worlds[world_id].name).to_upper_camel_case(); + let name = &format!("{name}.I{name}Exports"); + let mut r#gen = self.interface(resolve, name, Direction::Export, true); + + // Write the export types used by the functions. + let world = &resolve.worlds[world_id]; + let mut types = Vec::new(); + for (name, export) in world.exports.iter() { + match name { + WorldKey::Name(name) => match export { + WorldItem::Type(id) => { + if !CSharp::type_is_bidirectional(resolve, &id) { + types.push((name.as_str(), *id)) + } + } + _ => {} + }, + WorldKey::Interface(_) => {} + } + } - for (resource, funcs) in by_resource(funcs.iter().copied(), iter::empty()) { + if !types.is_empty() { + export_types(&mut r#gen, &types); + } + + for (resource, funcs) in by_resource( + funcs.iter().copied(), + r#gen.csharp_gen.world_resources.keys().copied(), + ) { if let Some(resource) = resource { r#gen.start_resource(resource, None); } @@ -244,7 +323,7 @@ impl WorldGenerator for CSharp { } } - r#gen.add_world_fragment(); + r#gen.add_world_fragment(Some(Direction::Export)); Ok(()) } @@ -256,8 +335,8 @@ impl WorldGenerator for CSharp { _files: &mut Files, ) { let name = &format!("{}-world", resolve.worlds[world].name).to_upper_camel_case(); - let name = &format!("{name}.I{name}"); - let mut r#gen = self.interface(resolve, name, Direction::Import); + let name = &format!("{name}.I{name}Imports"); + let mut r#gen = self.interface(resolve, name, Direction::Import, false); let mut old_resources = mem::take(&mut r#gen.csharp_gen.all_resources); for (ty_name, ty) in types { @@ -268,7 +347,7 @@ impl WorldGenerator for CSharp { r#gen.csharp_gen.all_resources = old_resources; r#gen.csharp_gen.world_resources = new_resources; - r#gen.add_world_fragment(); + r#gen.add_world_fragment(Some(Direction::Import)); } fn finish(&mut self, resolve: &Resolve, id: WorldId, files: &mut Files) -> anyhow::Result<()> { @@ -294,6 +373,13 @@ impl WorldGenerator for CSharp { let mut src = String::new(); src.push_str(&header); + let mut producers = wasm_metadata::Producers::empty(); + producers.add( + "processed-by", + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_VERSION"), + ); + let access = self.access_modifier(); uwrite!( @@ -301,7 +387,6 @@ impl WorldGenerator for CSharp { " namespace {world_namespace} {{ - {access} interface I{name}World {{ " ); @@ -309,19 +394,22 @@ impl WorldGenerator for CSharp { &self .world_fragments .iter() + .filter(|f| f.direction.is_none()) .map(|f| f.csharp_src.deref()) .collect::>() .join("\n"), ); - let mut producers = wasm_metadata::Producers::empty(); - producers.add( - "processed-by", - env!("CARGO_PKG_NAME"), - env!("CARGO_PKG_VERSION"), + src.push_str( + self.bidirectional_types_src + .iter() + .cloned() + .collect::>() + .join("\n") + .as_str(), ); - - src.push_str("}\n"); + self.write_world_fragments(Direction::Import, "Imports", &mut src, access, &name); + self.write_world_fragments(Direction::Export, "Exports", &mut src, access, &name); if self.needs_result { uwrite!( @@ -494,23 +582,65 @@ impl WorldGenerator for CSharp { if !&self.world_fragments.is_empty() { src.push_str("\n"); - src.push_str("namespace exports {\n"); + if self + .world_fragments + .iter() + .any(|f| f.direction == Some(Direction::Import)) + { + src.push_str("\n"); - src.push_str(&format!("{access} static class {name}World\n")); - src.push_str("{"); + src.push_str("namespace Imports {\n"); - for fragment in &self.world_fragments { - src.push_str("\n"); + src.push_str(&format!( + "{access} partial class {name}WorldImportsInterop : I{name}WorldImports\n" + )); + src.push_str("{"); + + for fragment in self + .world_fragments + .iter() + .filter(|f| f.direction == Some(Direction::Import)) + { + if !fragment.csharp_interop_src.is_empty() { + src.push_str("\n"); - src.push_str(&fragment.csharp_interop_src); + src.push_str(&fragment.csharp_interop_src); + } + } + src.push_str("}\n"); + src.push_str("}\n"); + } + + if self + .world_fragments + .iter() + .any(|f| f.direction == Some(Direction::Export)) + { + src.push_str("namespace Exports {\n"); + + src.push_str(&format!("{access} static class {name}WorldInterop\n")); + src.push_str("{"); + + for fragment in self + .world_fragments + .iter() + .filter(|f| f.direction == Some(Direction::Export)) + { + src.push_str("\n"); + + src.push_str(&fragment.csharp_interop_src); + } + src.push_str("}\n"); + src.push_str("}\n"); } - src.push_str("}\n"); - src.push_str("}\n"); } if self.needs_async_support { src.push_str("\n"); src.push_str(include_str!("AsyncSupport.cs")); + + src.push_str("\n"); + src.push_str(&include_str!("FutureCommonSupport.cs")); } src.push_str("\n"); @@ -575,7 +705,7 @@ impl WorldGenerator for CSharp { if self.opts.generate_stub { generate_stub( - format!("I{name}World"), + format!("I{name}WorldExports"), files, Stubs::World(&self.world_fragments), ); @@ -732,6 +862,12 @@ enum Stubs<'a> { Interface(&'a Vec), } +fn export_types(r#gen: &mut InterfaceGenerator, types: &[(&str, TypeId)]) { + for (ty_name, ty) in types { + r#gen.define_type(ty_name, *ty); + } +} + // We cant use "StructLayout.Pack" as dotnet will use the minimum of the type and the "Pack" field, // so for byte it would always use 1 regardless of the "Pack". pub fn dotnet_aligned_array(array_size: usize, required_alignment: usize) -> (usize, String) { @@ -800,14 +936,21 @@ fn interface_name( } }; - let name = match name { - WorldKey::Name(name) => name.to_upper_camel_case(), - WorldKey::Interface(id) => resolve.interfaces[*id] - .name - .as_ref() - .unwrap() - .to_upper_camel_case(), - }; + let name = format!( + "{}{}", + match name { + WorldKey::Name(name) => name.to_upper_camel_case(), + WorldKey::Interface(id) => resolve.interfaces[*id] + .name + .as_ref() + .unwrap() + .to_upper_camel_case(), + }, + match direction { + Direction::Import => "Imports", + Direction::Export => "Exports", + } + ); let namespace = match &pkg { Some(name) => { @@ -836,8 +979,8 @@ fn interface_name( "{}wit.{}.{}I{name}", world_namespace, match direction { - Direction::Import => "imports", - Direction::Export => "exports", + Direction::Import => "Imports", + Direction::Export => "Exports", }, namespace ) diff --git a/crates/test/src/lib.rs b/crates/test/src/lib.rs index 327c3124e..69790972a 100644 --- a/crates/test/src/lib.rs +++ b/crates/test/src/lib.rs @@ -819,7 +819,12 @@ impl Runner<'_> { } wasmparser::Validator::new_with_features(wasmparser::WasmFeatures::all()) .validate_all(&wasm) - .with_context(|| format!("compiler produced invalid wasm file {output:?}"))?; + .with_context(|| { + format!( + "compiler produced invalid wasm file {output:?} for component {}", + component.name + ) + })?; Ok(output) } diff --git a/tests/runtime-async/async/simple-future/runner.cs b/tests/runtime-async/async/simple-future/runner.cs new file mode 100644 index 000000000..730d8dca1 --- /dev/null +++ b/tests/runtime-async/async/simple-future/runner.cs @@ -0,0 +1,57 @@ +using System; +using System.Runtime.InteropServices; +using System.Diagnostics; +using RunnerWorld.wit.Imports.my.test; +using RunnerWorld; + +public class Program +{ + public static async Task Main(string[] args) + { + { + var (reader, writer) = IIImports.FutureNew(); + + var writeTask = writer.Write(); + Debug.Assert(!writeTask.IsCompleted); + + var task = IIImports.ReadFuture(reader); + Debug.Assert(task.IsCompleted); + + var set = AsyncSupport.WaitableSetNew(); + AsyncSupport.Join(writer, set); + + var ev = new EventWaitable(); + var status = AsyncSupport.WaitableSetWait(set); + Debug.Assert(status.Event == EventCode.FutureWrite); + Debug.Assert(status.Waitable == writer.Handle); + Debug.Assert(status.Status.IsCompleted); + Debug.Assert(status.Status.Count == 0); + + writer.Dispose(); + set.Dispose(); + } + + { + var (reader, writer) = IIImports.FutureNew(); + + var writeTask = writer.Write(); + Debug.Assert(!writeTask.IsCompleted); + + var task = IIImports.DropFuture(reader); + Debug.Assert(task.IsCompleted); + + var set = AsyncSupport.WaitableSetNew(); + AsyncSupport.Join(writer, set); + + var ev = new EventWaitable(); + var status = AsyncSupport.WaitableSetWait(set); + Debug.Assert(status.Event == EventCode.FutureWrite); + Debug.Assert(status.Waitable == writer.Handle); + Debug.Assert(status.Status.IsDropped); + Debug.Assert(status.Status.Count == 0); + + writer.Dispose(); + set.Dispose(); + } + } +} \ No newline at end of file diff --git a/tests/runtime-async/async/simple-future/test.cs b/tests/runtime-async/async/simple-future/test.cs new file mode 100644 index 000000000..b165cf603 --- /dev/null +++ b/tests/runtime-async/async/simple-future/test.cs @@ -0,0 +1,38 @@ +using System.Diagnostics; + +namespace TestWorld.wit.Exports.my.test +{ + public class IExportsImpl : IIExports + { + public static Task ReadFuture(FutureReader reader) + { + var task = reader.Read(); + + Debug.Assert(task.IsCompleted); + // TODO: Should we check the Count? + + reader.Dispose(); + + return Task.CompletedTask; + } + + public static int ReadFutureCallback() + { + Debug.Assert(false); + return 0; + } + + public static Task DropFuture(FutureReader reader) + { + reader.Dispose(); + return Task.CompletedTask; + } + + public static int DropFutureCallback() + { + Debug.Assert(false); + return 0; + } + + } +} diff --git a/tests/runtime-async/async/simple-import-params-results/runner.cs b/tests/runtime-async/async/simple-import-params-results/runner.cs index 1098b9209..370037532 100644 --- a/tests/runtime-async/async/simple-import-params-results/runner.cs +++ b/tests/runtime-async/async/simple-import-params-results/runner.cs @@ -1,28 +1,28 @@ using System; using System.Runtime.InteropServices; using System.Diagnostics; -using RunnerWorld.wit.imports.a.b; +using RunnerWorld.wit.Imports.a.b; using System.Text; public class Program { public static async Task Main(string[] args) { - var t = II.OneArgument(1); + var t = IIImports.OneArgument(1); Debug.Assert(t.IsCompletedSuccessfully); - var tOneResult = II.OneResult(); + var tOneResult = IIImports.OneResult(); Debug.Assert(tOneResult.IsCompletedSuccessfully); Debug.Assert(tOneResult.Result == 2); - var tOneArgumentAndResult = II.OneArgumentAndResult(3); + var tOneArgumentAndResult = IIImports.OneArgumentAndResult(3); Debug.Assert(tOneArgumentAndResult.IsCompletedSuccessfully); Debug.Assert(tOneArgumentAndResult.Result == 4); - var tTwoArguments = II.TwoArguments(5, 6); + var tTwoArguments = IIImports.TwoArguments(5, 6); Debug.Assert(tTwoArguments.IsCompletedSuccessfully); - var tTwoArgumentsAndResult = II.TwoArgumentsAndResult(7, 8); + var tTwoArgumentsAndResult = IIImports.TwoArgumentsAndResult(7, 8); Debug.Assert(tTwoArgumentsAndResult.IsCompletedSuccessfully); Debug.Assert(tTwoArgumentsAndResult.Result == 9); } diff --git a/tests/runtime-async/async/simple-import-params-results/test.cs b/tests/runtime-async/async/simple-import-params-results/test.cs index 57c0ac905..8c9db521b 100644 --- a/tests/runtime-async/async/simple-import-params-results/test.cs +++ b/tests/runtime-async/async/simple-import-params-results/test.cs @@ -1,9 +1,9 @@ using System.Diagnostics; -using TestWorld.wit.exports.a.b; +using TestWorld.wit.Exports.a.b; -namespace TestWorld.wit.exports.a.b +namespace TestWorld.wit.Exports.a.b { - public class IImpl : II + public class IExportsImpl : IIExports { public static async Task OneArgument(uint x) { @@ -33,5 +33,30 @@ public static async Task TwoArgumentsAndResult(uint x, uint y) Debug.Assert(y == 8); return 9; } + + public static int OneArgumentCallback() + { + throw new NotImplementedException(); + } + + public static int OneResultCallback() + { + throw new NotImplementedException(); + } + + public static int OneArgumentAndResultCallback() + { + throw new NotImplementedException(); + } + + public static int TwoArgumentsCallback() + { + throw new NotImplementedException(); + } + + public static int TwoArgumentsAndResultCallback() + { + throw new NotImplementedException(); + } } } diff --git a/tests/runtime/demo/runner.cs b/tests/runtime/demo/runner.cs index 75f1087f1..08be34fe1 100644 --- a/tests/runtime/demo/runner.cs +++ b/tests/runtime/demo/runner.cs @@ -1,7 +1,4 @@ -using System; -using System.Runtime.InteropServices; -using System.Diagnostics; -using RunnerWorld.wit.imports.a.b; +using RunnerWorld.wit.Imports.a.b; namespace RunnerWorld; @@ -9,6 +6,6 @@ public class RunnerWorldImpl : IRunnerWorld { public static void Run() { - TheTestInterop.X(); + ITheTestImports.X(); } } diff --git a/tests/runtime/demo/test.cs b/tests/runtime/demo/test.cs index e5c0974f8..44087a889 100644 --- a/tests/runtime/demo/test.cs +++ b/tests/runtime/demo/test.cs @@ -1,10 +1,6 @@ -using System; -using System.Diagnostics; -using TestWorld; +namespace TestWorld.wit.Exports.a.b; -namespace TestWorld; - -public class TheTestImpl : ITestWorld +public class TheTestExportsImpl : ITheTestExports { public static void X() { diff --git a/tests/runtime/lists/runner.cs b/tests/runtime/lists/runner.cs index ef623e6ec..900e282ec 100644 --- a/tests/runtime/lists/runner.cs +++ b/tests/runtime/lists/runner.cs @@ -1,7 +1,5 @@ -using System; -using System.Runtime.InteropServices; using System.Diagnostics; -using RunnerWorld.wit.imports.test.lists; +using RunnerWorld.wit.Imports.test.lists; using System.Text; namespace RunnerWorld; @@ -10,30 +8,30 @@ public class RunnerWorldImpl : IRunnerWorld { public static void Run() { - ToTestInterop.EmptyListParam(new byte[0]); - ToTestInterop.EmptyStringParam(""); + IToTestImports.EmptyListParam(new byte[0]); + IToTestImports.EmptyStringParam(""); { - byte[] result = ToTestInterop.EmptyListResult(); + byte[] result = IToTestImports.EmptyListResult(); Debug.Assert(result.Length == 0); } { - string result = ToTestInterop.EmptyStringResult(); + string result = IToTestImports.EmptyStringResult(); Debug.Assert(result.Length == 0); } - ToTestInterop.ListParam(new byte[] { (byte)1, (byte)2, (byte)3, (byte)4 }); - ToTestInterop.ListParam((new byte[] { (byte)1, (byte)2, (byte)3, (byte)4 }).AsSpan()); - ToTestInterop.ListParam((new byte[] { (byte)1, (byte)2, (byte)3, (byte)4 }).AsMemory()); - ToTestInterop.ListParam2("foo"); - ToTestInterop.ListParam3(new List() { + IToTestImports.ListParam(new byte[] { (byte)1, (byte)2, (byte)3, (byte)4 }); + IToTestImports.ListParam((new byte[] { (byte)1, (byte)2, (byte)3, (byte)4 }).AsSpan()); + IToTestImports.ListParam((new byte[] { (byte)1, (byte)2, (byte)3, (byte)4 }).AsMemory()); + IToTestImports.ListParam2("foo"); + IToTestImports.ListParam3(new List() { "foo", "bar", "baz" }); - ToTestInterop.ListParam4(new List>() { + IToTestImports.ListParam4(new List>() { new List() { "foo", "bar" @@ -48,10 +46,10 @@ public static void Run() { randomStrings.Add(Guid.NewGuid().ToString()); } - ToTestInterop.ListParamLarge(randomStrings); + IToTestImports.ListParamLarge(randomStrings); { - byte[] result = ToTestInterop.ListResult(); + byte[] result = IToTestImports.ListResult(); Debug.Assert(result.Length == 5); Debug.Assert(result[0] == (byte)1); Debug.Assert(result[1] == (byte)2); @@ -61,13 +59,13 @@ public static void Run() } { - string result = ToTestInterop.ListResult2(); + string result = IToTestImports.ListResult2(); Console.WriteLine(result); Debug.Assert(result == "hello!"); } { - List result = ToTestInterop.ListResult3(); + List result = IToTestImports.ListResult3(); Debug.Assert(result.Count() == 2); Console.WriteLine(result[0]); Console.WriteLine(result[1]); @@ -78,15 +76,15 @@ public static void Run() string[] strings = { "x", "", "hello", "hello ⚑ world" }; foreach (string s in strings) { - string result = ToTestInterop.StringRoundtrip(s); + string result = IToTestImports.StringRoundtrip(s); Debug.Assert(result == s); byte[] bytes = Encoding.UTF8.GetBytes(s); - Debug.Assert(bytes.SequenceEqual(ToTestInterop.ListRoundtrip(bytes))); + Debug.Assert(bytes.SequenceEqual(IToTestImports.ListRoundtrip(bytes))); } { - var (u, s) = ToTestInterop.ListMinmax8( + var (u, s) = IToTestImports.ListMinmax8( new byte[] { byte.MinValue, byte.MaxValue }, new sbyte[] { sbyte.MinValue, sbyte.MaxValue } ); @@ -96,7 +94,7 @@ public static void Run() } { - var (u, s) = ToTestInterop.ListMinmax16( + var (u, s) = IToTestImports.ListMinmax16( new ushort[] { ushort.MinValue, ushort.MaxValue }, new short[] { short.MinValue, short.MaxValue } ); @@ -114,7 +112,7 @@ public static void Run() } { - var (u, s) = ToTestInterop.ListMinmax32( + var (u, s) = IToTestImports.ListMinmax32( new uint[] { uint.MinValue, uint.MaxValue }, new int[] { int.MinValue, int.MaxValue } ); @@ -124,7 +122,7 @@ public static void Run() } { - var (u, s) = ToTestInterop.ListMinmax64( + var (u, s) = IToTestImports.ListMinmax64( new ulong[] { ulong.MinValue, ulong.MaxValue }, new long[] { long.MinValue, long.MaxValue } ); @@ -135,7 +133,7 @@ public static void Run() } { - var (u, s) = ToTestInterop.ListMinmaxFloat( + var (u, s) = IToTestImports.ListMinmaxFloat( new float[] { float.MinValue, float.MaxValue, diff --git a/tests/runtime/lists/test.cs b/tests/runtime/lists/test.cs index 1d2e1cbf6..77ff16410 100644 --- a/tests/runtime/lists/test.cs +++ b/tests/runtime/lists/test.cs @@ -3,9 +3,9 @@ using System.Diagnostics; using System.Text; -namespace TestWorld.wit.exports.test.lists +namespace TestWorld.wit.Exports.test.lists { - public class ToTestImpl : ITestWorld + public class ToTestExportsImpl : IToTestExports { public static uint AllocatedBytes() diff --git a/tests/runtime/many-arguments/runner.cs b/tests/runtime/many-arguments/runner.cs index 6188800f9..2959e1242 100644 --- a/tests/runtime/many-arguments/runner.cs +++ b/tests/runtime/many-arguments/runner.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; using System.Diagnostics; -using RunnerWorld.wit.imports.test.manyArguments; +using RunnerWorld.wit.Imports.test.manyArguments; namespace RunnerWorld; @@ -9,7 +9,7 @@ public class RunnerWorldImpl : IRunnerWorld { public static void Run() { - ToTestInterop.ManyArguments( + IToTestImports.ManyArguments( 1, 2, 3, diff --git a/tests/runtime/many-arguments/test.cs b/tests/runtime/many-arguments/test.cs index 3bef9fd1a..04a4a2e70 100644 --- a/tests/runtime/many-arguments/test.cs +++ b/tests/runtime/many-arguments/test.cs @@ -1,9 +1,9 @@ using System.Diagnostics; -using TestWorld.wit.exports.test.manyArguments; +using TestWorld.wit.Exports.test.manyArguments; namespace TestWorld; -public class ToTestImpl : ITestWorld +public class ToTestExportsImpl : IToTestExports { public static void ManyArguments( ulong a1, diff --git a/tests/runtime/numbers/runner.cs b/tests/runtime/numbers/runner.cs index b22300d0f..c6c5d10bb 100644 --- a/tests/runtime/numbers/runner.cs +++ b/tests/runtime/numbers/runner.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; using System.Diagnostics; -using RunnerWorld.wit.imports.test.numbers; +using RunnerWorld.wit.Imports.test.numbers; namespace RunnerWorld; @@ -9,56 +9,52 @@ public class RunnerWorldImpl : IRunnerWorld { public static void Run() { - Debug.Assert(NumbersInterop.RoundtripU8(1) == 1); - Debug.Assert(NumbersInterop.RoundtripU8(0) == 0); - Debug.Assert(NumbersInterop.RoundtripU8(Byte.MaxValue) == Byte.MaxValue); - - Debug.Assert(NumbersInterop.RoundtripS8(1) == 1); - Debug.Assert(NumbersInterop.RoundtripS8(SByte.MinValue) == SByte.MinValue); - Debug.Assert(NumbersInterop.RoundtripS8(SByte.MaxValue) == SByte.MaxValue); - - Debug.Assert(NumbersInterop.RoundtripU16(1) == 1); - Debug.Assert(NumbersInterop.RoundtripU16(0) == 0); - Debug.Assert(NumbersInterop.RoundtripU16(UInt16.MaxValue) == UInt16.MaxValue); - - Debug.Assert(NumbersInterop.RoundtripS16(1) == 1); - Debug.Assert(NumbersInterop.RoundtripS16(Int16.MinValue) == Int16.MinValue); - Debug.Assert(NumbersInterop.RoundtripS16(Int16.MaxValue) == Int16.MaxValue); - - Debug.Assert(NumbersInterop.RoundtripU32(1) == 1); - Debug.Assert(NumbersInterop.RoundtripU32(0) == 0); - Debug.Assert(NumbersInterop.RoundtripU32(UInt32.MaxValue) == UInt32.MaxValue); - - Debug.Assert(NumbersInterop.RoundtripS32(1) == 1); - Debug.Assert(NumbersInterop.RoundtripS32(Int32.MinValue) == Int32.MinValue); - Debug.Assert(NumbersInterop.RoundtripS32(Int32.MaxValue) == Int32.MaxValue); - - Debug.Assert(NumbersInterop.RoundtripU64(1) == 1); - Debug.Assert(NumbersInterop.RoundtripU64(0) == 0); - Debug.Assert(NumbersInterop.RoundtripU64(UInt64.MaxValue) == UInt64.MaxValue); - - Debug.Assert(NumbersInterop.RoundtripS64(1) == 1); - Debug.Assert(NumbersInterop.RoundtripS64(Int64.MinValue) == Int64.MinValue); - Debug.Assert(NumbersInterop.RoundtripS64(Int64.MaxValue) == Int64.MaxValue); - - Debug.Assert(NumbersInterop.RoundtripF32(1.0f) == 1.0f); - Debug.Assert(NumbersInterop.RoundtripF32(Single.PositiveInfinity) == Single.PositiveInfinity); - Debug.Assert(NumbersInterop.RoundtripF32(Single.NegativeInfinity) == Single.NegativeInfinity); - Debug.Assert(float.IsNaN(NumbersInterop.RoundtripF32(Single.NaN))); - - Debug.Assert(NumbersInterop.RoundtripF64(1.0) == 1.0); - Debug.Assert(NumbersInterop.RoundtripF64(Double.PositiveInfinity) == Double.PositiveInfinity); - Debug.Assert(NumbersInterop.RoundtripF64(Double.NegativeInfinity) == Double.NegativeInfinity); - Debug.Assert(double.IsNaN(NumbersInterop.RoundtripF64(Double.NaN))); - - Debug.Assert(NumbersInterop.RoundtripChar('a') == 'a'); - Debug.Assert(NumbersInterop.RoundtripChar(' ') == ' '); - Debug.Assert(Char.ConvertFromUtf32((int)NumbersInterop.RoundtripChar((uint)Char.ConvertToUtf32("🚩", 0))) == + Debug.Assert(INumbersImports.RoundtripU8(1) == 1); + Debug.Assert(INumbersImports.RoundtripU8(0) == 0); + Debug.Assert(INumbersImports.RoundtripU8(Byte.MaxValue) == Byte.MaxValue); + + Debug.Assert(INumbersImports.RoundtripS8(1) == 1); + Debug.Assert(INumbersImports.RoundtripS8(SByte.MinValue) == SByte.MinValue); + Debug.Assert(INumbersImports.RoundtripS8(SByte.MaxValue) == SByte.MaxValue); + + Debug.Assert(INumbersImports.RoundtripU16(1) == 1); + Debug.Assert(INumbersImports.RoundtripU16(0) == 0); + Debug.Assert(INumbersImports.RoundtripU16(UInt16.MaxValue) == UInt16.MaxValue); + + Debug.Assert(INumbersImports.RoundtripS16(1) == 1); + Debug.Assert(INumbersImports.RoundtripS16(Int16.MinValue) == Int16.MinValue); + Debug.Assert(INumbersImports.RoundtripS16(Int16.MaxValue) == Int16.MaxValue); + Debug.Assert(INumbersImports.RoundtripU32(1) == 1); + Debug.Assert(INumbersImports.RoundtripU32(0) == 0); + Debug.Assert(INumbersImports.RoundtripU32(UInt32.MaxValue) == UInt32.MaxValue); + + Debug.Assert(INumbersImports.RoundtripS32(1) == 1); + Debug.Assert(INumbersImports.RoundtripS32(Int32.MinValue) == Int32.MinValue); + Debug.Assert(INumbersImports.RoundtripS32(Int32.MaxValue) == Int32.MaxValue); + + Debug.Assert(INumbersImports.RoundtripU64(1) == 1); + Debug.Assert(INumbersImports.RoundtripU64(0) == 0); + Debug.Assert(INumbersImports.RoundtripU64(UInt64.MaxValue) == UInt64.MaxValue); + + Debug.Assert(INumbersImports.RoundtripS64(1) == 1); + Debug.Assert(INumbersImports.RoundtripS64(Int64.MinValue) == Int64.MinValue); + Debug.Assert(INumbersImports.RoundtripS64(Int64.MaxValue) == Int64.MaxValue); + Debug.Assert(INumbersImports.RoundtripF32(1.0f) == 1.0f); + Debug.Assert(INumbersImports.RoundtripF32(Single.PositiveInfinity) == Single.PositiveInfinity); + Debug.Assert(INumbersImports.RoundtripF32(Single.NegativeInfinity) == Single.NegativeInfinity); + Debug.Assert(float.IsNaN(INumbersImports.RoundtripF32(Single.NaN))); + Debug.Assert(INumbersImports.RoundtripF64(1.0) == 1.0); + Debug.Assert(INumbersImports.RoundtripF64(Double.PositiveInfinity) == Double.PositiveInfinity); + Debug.Assert(INumbersImports.RoundtripF64(Double.NegativeInfinity) == Double.NegativeInfinity); + Debug.Assert(double.IsNaN(INumbersImports.RoundtripF64(Double.NaN))); + Debug.Assert(INumbersImports.RoundtripChar('a') == 'a'); + Debug.Assert(INumbersImports.RoundtripChar(' ') == ' '); + Debug.Assert(Char.ConvertFromUtf32((int)INumbersImports.RoundtripChar((uint)Char.ConvertToUtf32("🚩", 0))) == "🚩"); // This is 2 chars long as it contains a surrogate pair - NumbersInterop.SetScalar(2); - Debug.Assert(NumbersInterop.GetScalar() == 2); - NumbersInterop.SetScalar(4); - Debug.Assert(NumbersInterop.GetScalar() == 4); + INumbersImports.SetScalar(2); + Debug.Assert(INumbersImports.GetScalar() == 2); + INumbersImports.SetScalar(4); + Debug.Assert(INumbersImports.GetScalar() == 4); } } diff --git a/tests/runtime/numbers/test.cs b/tests/runtime/numbers/test.cs index 149dd35e0..16ba0e44e 100644 --- a/tests/runtime/numbers/test.cs +++ b/tests/runtime/numbers/test.cs @@ -1,10 +1,8 @@ -using System; -using System.Runtime.InteropServices; -using System.Diagnostics; +using TestWorld.wit.Exports.test.numbers; -namespace TestWorld.wit.exports.test.numbers +namespace TestWorld.wit.Exports.test.numbers { - public class NumbersImpl : ITestWorld + public class NumbersExportsImpl : INumbersExports { static uint SCALAR = 0; diff --git a/tests/runtime/options/runner.cs b/tests/runtime/options/runner.cs index 6be68a102..6fd23c6d2 100644 --- a/tests/runtime/options/runner.cs +++ b/tests/runtime/options/runner.cs @@ -1,5 +1,5 @@ using System.Diagnostics; -using RunnerWorld.wit.imports.test.options; +using RunnerWorld.wit.Imports.test.options; namespace RunnerWorld; @@ -7,13 +7,13 @@ public class RunnerWorldImpl : IRunnerWorld { public static void Run() { - ToTestInterop.OptionNoneParam(null); - ToTestInterop.OptionSomeParam("foo"); - Debug.Assert(ToTestInterop.OptionNoneResult() == null); - Debug.Assert(ToTestInterop.OptionSomeResult() == "foo"); - Debug.Assert(ToTestInterop.OptionRoundtrip("foo") == "foo"); - Debug.Assert(ToTestInterop.DoubleOptionRoundtrip(new Option(42)).Value == 42); - Debug.Assert(ToTestInterop.DoubleOptionRoundtrip(new Option(null)).Value == null); - Debug.Assert(!ToTestInterop.DoubleOptionRoundtrip(Option.None).HasValue); + IToTestImports.OptionNoneParam(null); + IToTestImports.OptionSomeParam("foo"); + Debug.Assert(IToTestImports.OptionNoneResult() == null); + Debug.Assert(IToTestImports.OptionSomeResult() == "foo"); + Debug.Assert(IToTestImports.OptionRoundtrip("foo") == "foo"); + Debug.Assert(IToTestImports.DoubleOptionRoundtrip(new Option(42)).Value == 42); + Debug.Assert(IToTestImports.DoubleOptionRoundtrip(new Option(null)).Value == null); + Debug.Assert(!IToTestImports.DoubleOptionRoundtrip(Option.None).HasValue); } } diff --git a/tests/runtime/options/test.cs b/tests/runtime/options/test.cs index 38380c82c..9668603f6 100644 --- a/tests/runtime/options/test.cs +++ b/tests/runtime/options/test.cs @@ -1,8 +1,8 @@ using System.Diagnostics; -namespace TestWorld.wit.exports.test.options +namespace TestWorld.wit.Exports.test.options { - public class ToTestImpl : IToTest + public class ToTestExportsImpl : IToTestExports { public static void OptionNoneParam(string? a) { diff --git a/tests/runtime/records/runner.cs b/tests/runtime/records/runner.cs index 14431da6f..8515d0ad0 100644 --- a/tests/runtime/records/runner.cs +++ b/tests/runtime/records/runner.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; using System.Diagnostics; -using RunnerWorld.wit.imports.test.records; +using RunnerWorld.wit.Imports.test.records; namespace RunnerWorld; @@ -10,51 +10,51 @@ public class RunnerWorldImpl : IRunnerWorld public static void Run() { { - var results = ToTestInterop.MultipleResults(); + var results = IToTestImports.MultipleResults(); Debug.Assert(results.Item1 == 4); Debug.Assert(results.Item2 == 5); } (byte, uint) input = (1, 2); - (uint, byte) output = ToTestInterop.SwapTuple(input); + (uint, byte) output = IToTestImports.SwapTuple(input); Debug.Assert(output.Item1 == 2); Debug.Assert(output.Item2 == 1); - Debug.Assert(ToTestInterop.RoundtripFlags1(IToTest.F1.A) == IToTest.F1.A); - Debug.Assert(ToTestInterop.RoundtripFlags1(0) == 0); - Debug.Assert(ToTestInterop.RoundtripFlags1(IToTest.F1.B) == IToTest.F1.B); - Debug.Assert(ToTestInterop.RoundtripFlags1(IToTest.F1.A | IToTest.F1.B) == (IToTest.F1.A | IToTest.F1.B)); + Debug.Assert(IToTestImports.RoundtripFlags1(IToTestImports.F1.A) == IToTestImports.F1.A); + Debug.Assert(IToTestImports.RoundtripFlags1(0) == 0); + Debug.Assert(IToTestImports.RoundtripFlags1(IToTestImports.F1.B) == IToTestImports.F1.B); + Debug.Assert(IToTestImports.RoundtripFlags1(IToTestImports.F1.A | IToTestImports.F1.B) == (IToTestImports.F1.A | IToTestImports.F1.B)); - Debug.Assert(ToTestInterop.RoundtripFlags2(IToTest.F2.C) == IToTest.F2.C); - Debug.Assert(ToTestInterop.RoundtripFlags2(0) == 0); - Debug.Assert(ToTestInterop.RoundtripFlags2(IToTest.F2.D) == IToTest.F2.D); - Debug.Assert(ToTestInterop.RoundtripFlags2(IToTest.F2.C | IToTest.F2.E) == (IToTest.F2.C | IToTest.F2.E)); + Debug.Assert(IToTestImports.RoundtripFlags2(IToTestImports.F2.C) == IToTestImports.F2.C); + Debug.Assert(IToTestImports.RoundtripFlags2(0) == 0); + Debug.Assert(IToTestImports.RoundtripFlags2(IToTestImports.F2.D) == IToTestImports.F2.D); + Debug.Assert(IToTestImports.RoundtripFlags2(IToTestImports.F2.C | IToTestImports.F2.E) == (IToTestImports.F2.C | IToTestImports.F2.E)); { - var result = ToTestInterop.RoundtripFlags3(IToTest.Flag8.B0, IToTest.Flag16.B1, - IToTest.Flag32.B2); - Debug.Assert(result.Item1 == IToTest.Flag8.B0); - Debug.Assert(result.Item2 == IToTest.Flag16.B1); - Debug.Assert(result.Item3 == IToTest.Flag32.B2); + var result = IToTestImports.RoundtripFlags3(IToTestImports.Flag8.B0, IToTestImports.Flag16.B1, + IToTestImports.Flag32.B2); + Debug.Assert(result.Item1 == IToTestImports.Flag8.B0); + Debug.Assert(result.Item2 == IToTestImports.Flag16.B1); + Debug.Assert(result.Item3 == IToTestImports.Flag32.B2); } { - IToTest.R1 inputRecord = new(8, 0); - var result = ToTestInterop.RoundtripRecord1(inputRecord); + IToTestImports.R1 inputRecord = new(8, 0); + var result = IToTestImports.RoundtripRecord1(inputRecord); Debug.Assert(result.a == 8); Debug.Assert(result.b == 0); } { - IToTest.R1 inputRecord = new(0, IToTest.F1.A | IToTest.F1.B); + IToTestImports.R1 inputRecord = new(0, IToTestImports.F1.A | IToTestImports.F1.B); - var result = ToTestInterop.RoundtripRecord1(inputRecord); + var result = IToTestImports.RoundtripRecord1(inputRecord); Debug.Assert(result.a == 0); - Debug.Assert(result.b == (IToTest.F1.A | IToTest.F1.B)); + Debug.Assert(result.b == (IToTestImports.F1.A | IToTestImports.F1.B)); } { - var result = ToTestInterop.Tuple1(1); + var result = IToTestImports.Tuple1(1); Debug.Assert(result == 1); } } diff --git a/tests/runtime/records/test.cs b/tests/runtime/records/test.cs index 4e0b8310b..f6ae2f23b 100644 --- a/tests/runtime/records/test.cs +++ b/tests/runtime/records/test.cs @@ -1,6 +1,6 @@ -namespace TestWorld.wit.exports.test.records +namespace TestWorld.wit.Exports.test.records { - public class ToTestImpl : ITestWorld + public class ToTestExportsImpl : IToTestExports { public static (byte, ushort) MultipleResults() { @@ -12,30 +12,30 @@ public static (uint, byte) SwapTuple((byte, uint) a) return (a.Item2, a.Item1); } - public static IToTest.F1 RoundtripFlags1( - IToTest.F1 a) + public static IToTestExports.F1 RoundtripFlags1( + IToTestExports.F1 a) { return a; } - public static IToTest.F2 RoundtripFlags2( - IToTest.F2 a) + public static IToTestExports.F2 RoundtripFlags2( + IToTestExports.F2 a) { return a; } - public static (IToTest.Flag8, - IToTest.Flag16, - IToTest.Flag32) RoundtripFlags3( - IToTest.Flag8 a, - IToTest.Flag16 b, - IToTest.Flag32 c) + public static (IToTestExports.Flag8, + IToTestExports.Flag16, + IToTestExports.Flag32) RoundtripFlags3( + IToTestExports.Flag8 a, + IToTestExports.Flag16 b, + IToTestExports.Flag32 c) { return (a, b, c); } - public static IToTest.R1 RoundtripRecord1( - IToTest.R1 a) + public static IToTestExports.R1 RoundtripRecord1( + IToTestExports.R1 a) { return a; } diff --git a/tests/runtime/resource-borrow/runner.cs b/tests/runtime/resource-borrow/runner.cs index 2cf2f769b..336e39a32 100644 --- a/tests/runtime/resource-borrow/runner.cs +++ b/tests/runtime/resource-borrow/runner.cs @@ -1,4 +1,4 @@ -using RunnerWorld.wit.imports.test.resourceBorrow; +using RunnerWorld.wit.Imports.test.resourceBorrow; using System.Diagnostics; namespace RunnerWorld; @@ -7,7 +7,7 @@ public class RunnerWorldImpl : IRunnerWorld { public static void Run() { - uint ret = ToTestInterop.Foo(new IToTest.Thing(42)); + uint ret = ToTestImports.Foo(new IToTestImports.Thing(42)); Debug.Assert(ret == 42 + 1 + 2); } } diff --git a/tests/runtime/resource-borrow/test.cs b/tests/runtime/resource-borrow/test.cs index f5feab341..0acf0be34 100644 --- a/tests/runtime/resource-borrow/test.cs +++ b/tests/runtime/resource-borrow/test.cs @@ -1,7 +1,7 @@ -namespace TestWorld.wit.exports.test.resourceBorrow +namespace TestWorld.wit.Exports.test.resourceBorrow { - public class ToTestImpl : IToTest { - public class Thing : IToTest.Thing, IToTest.IThing { + public class ToTestExportsImpl : IToTestExports { + public class Thing : IToTestExports.Thing, IToTestExports.IThing { public uint val; public Thing(uint v) { @@ -9,7 +9,7 @@ public Thing(uint v) { } } - public static uint Foo(IToTest.Thing v) { + public static uint Foo(IToTestExports.Thing v) { return ((Thing) v).val + 2; } } diff --git a/tests/runtime/resource-import-and-export/intermediate.cs b/tests/runtime/resource-import-and-export/intermediate.cs index d2094cc2a..67d139721 100644 --- a/tests/runtime/resource-import-and-export/intermediate.cs +++ b/tests/runtime/resource-import-and-export/intermediate.cs @@ -1,10 +1,10 @@ -using Import = IntermediateWorld.wit.imports.test.resourceImportAndExport.ITest; -using Host = IntermediateWorld.wit.imports.test.resourceImportAndExport.TestInterop; +using IntermediateWorld.wit.Imports.test.resourceImportAndExport; +using Import = IntermediateWorld.wit.Imports.test.resourceImportAndExport.ITestImports; -namespace IntermediateWorld.wit.exports.test.resourceImportAndExport +namespace IntermediateWorld.wit.Exports.test.resourceImportAndExport { - public class TestImpl : ITest { - public class Thing : ITest.Thing, ITest.IThing { + public class TestExportsImpl : ITestExports { + public class Thing : ITestExports.Thing, ITestExports.IThing { public Import.Thing val; public Thing(uint v) { @@ -19,7 +19,7 @@ public void Bar(uint v) { this.val.Bar(v + 3); } - public static ITest.Thing Baz(ITest.Thing a, ITest.Thing b) { + public static ITestExports.Thing Baz(ITestExports.Thing a, ITestExports.Thing b) { return new Thing(Import.Thing.Baz(((Thing) a).val, ((Thing) b).val).Foo() + 4); } } @@ -27,9 +27,10 @@ public static ITest.Thing Baz(ITest.Thing a, ITest.Thing b) { } namespace IntermediateWorld { - public class IntermediateWorldImpl : IIntermediateWorld { + public class IntermediateWorldExportsImpl : ITestImports + { public static Import.Thing ToplevelExport(Import.Thing things) { - return exports.IntermediateWorld.ToplevelImport(things); + return IntermediateWorld.IIntermediateWorldImports.ToplevelImport(things); } } } diff --git a/tests/runtime/resource_aggregates/runner.cs b/tests/runtime/resource_aggregates/runner.cs index ba3d65a42..31b6f9ff8 100644 --- a/tests/runtime/resource_aggregates/runner.cs +++ b/tests/runtime/resource_aggregates/runner.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; using System.Diagnostics; -using RunnerWorld.wit.imports.test.resourceAggregates; +using RunnerWorld.wit.Imports.test.resourceAggregates; using RunnerWorld; namespace RunnerWorld; @@ -10,27 +10,27 @@ public class RunnerWorldImpl : IRunnerWorld { public static void Run() { - var il1 = new List(); - il1.Add(new IToTest.Thing(9)); - il1.Add(new IToTest.Thing(10)); - var il2 = new List(); - il2.Add(new IToTest.Thing(11)); - il2.Add(new IToTest.Thing(12)); + var il1 = new List(); + il1.Add(new IToTestImports.Thing(9)); + il1.Add(new IToTestImports.Thing(10)); + var il2 = new List(); + il2.Add(new IToTestImports.Thing(11)); + il2.Add(new IToTestImports.Thing(12)); - uint res = ToTestInterop.Foo( - new IToTest.R1(new IToTest.Thing(0)), - new IToTest.R2(new IToTest.Thing(1)), - new IToTest.R3(new IToTest.Thing(2), new IToTest.Thing(3)), - (new IToTest.Thing(4), new IToTest.R1(new IToTest.Thing(5))), - new IToTest.Thing(6), - IToTest.V1.Thing(new IToTest.Thing(7)), - IToTest.V2.Thing(new IToTest.Thing(8)), + uint res = IToTestImports.Foo( + new IToTestImports.R1(new IToTestImports.Thing(0)), + new IToTestImports.R2(new IToTestImports.Thing(1)), + new IToTestImports.R3(new IToTestImports.Thing(2), new IToTestImports.Thing(3)), + (new IToTestImports.Thing(4), new IToTestImports.R1(new IToTestImports.Thing(5))), + new IToTestImports.Thing(6), + IToTestImports.V1.Thing(new IToTestImports.Thing(7)), + IToTestImports.V2.Thing(new IToTestImports.Thing(8)), il1, il2, - new IToTest.Thing(13), - new IToTest.Thing(14), - Result.Ok(new IToTest.Thing(15)), - Result.Ok(new IToTest.Thing(16)) + new IToTestImports.Thing(13), + new IToTestImports.Thing(14), + Result.Ok(new IToTestImports .Thing(15)), + Result.Ok(new IToTestImports.Thing(16)) ); Debug.Assert(res == 156); } diff --git a/tests/runtime/resource_aggregates/test.cs b/tests/runtime/resource_aggregates/test.cs index 4b0d01afa..6f769f8d6 100644 --- a/tests/runtime/resource_aggregates/test.cs +++ b/tests/runtime/resource_aggregates/test.cs @@ -1,7 +1,7 @@ -namespace TestWorld.wit.exports.test.resourceAggregates +namespace TestWorld.wit.Exports.test.resourceAggregates { - public class ToTestImpl : IToTest { - public class Thing : IToTest.Thing, IToTest.IThing { + public class ToTestExportsImpl : IToTestExports { + public class Thing : IToTestExports.Thing, IToTestExports.IThing { public uint val; public Thing(uint v) { @@ -10,19 +10,19 @@ public Thing(uint v) { } public static uint Foo( - IToTest.R1 r1, - IToTest.R2 r2, - IToTest.R3 r3, - (IToTest.Thing, IToTest.R1) t1, - IToTest.Thing t2, - IToTest.V1 v1, - IToTest.V2 v2, - List l1, - List l2, - IToTest.Thing? o1, - IToTest.Thing? o2, - Result result1, - Result result2 + IToTestExports.R1 r1, + IToTestExports.R2 r2, + IToTestExports.R3 r3, + (IToTestExports.Thing, IToTestExports.R1) t1, + IToTestExports.Thing t2, + IToTestExports.V1 v1, + IToTestExports.V2 v2, + List l1, + List l2, + IToTestExports.Thing? o1, + IToTestExports.Thing? o2, + Result result1, + Result result2 ) { uint sumIl1 = 0; diff --git a/tests/runtime/resource_alias/test.cs b/tests/runtime/resource_alias/test.cs index 41421e9c1..79601f847 100644 --- a/tests/runtime/resource_alias/test.cs +++ b/tests/runtime/resource_alias/test.cs @@ -1,7 +1,7 @@ -namespace TestWorld.wit.exports.test.resourceAlias +namespace TestWorld.wit.Exports.test.resourceAlias { - public class E1Impl : IE1 { - public class X : IE1.X, IE1.IX { + public class E1ExportsImpl : IE1Exports { + public class X : IE1Exports.X, IE1Exports.IX { public uint val; public X(uint v) { @@ -9,14 +9,14 @@ public X(uint v) { } } - public static List A(IE1.Foo f) { - return new List() { f.x }; + public static List A(IE1Exports.Foo f) { + return new List() { f.x }; } } - public class E2Impl : IE2 { - public static List A(IE2.Foo f, IE1.Foo g, IE1.X h) { - return new List() { f.x, g.x }; + public class E2ExportsImpl : IE2Exports { + public static List A(IE2Exports.Foo f, IE1Exports.Foo g, IE1Exports.X h) { + return new List() { f.x, g.x }; } } } diff --git a/tests/runtime/resource_alias_redux/_test_disabled.cs b/tests/runtime/resource_alias_redux/_test_disabled.cs deleted file mode 100644 index 8a60a05b5..000000000 --- a/tests/runtime/resource_alias_redux/_test_disabled.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace TestWorld.wit.exports.test.resourceAliasRedux -{ - public class ResourceAlias1Impl : IResourceAlias1 { - public class Thing : IResourceAlias1.Thing, IResourceAlias1.IThing { - public string val; - - public Thing(string v) { - this.val = v + " GuestThing"; - } - - public string Get() { - return this.val + " GuestThing.get"; - } - } - - public static List A(IResourceAlias1.Foo f) { - var newList = new List(); - newList.Add(f.thing); - return newList; - } - } - - public class ResourceAlias2Impl : IResourceAlias2 { - public static List B(IResourceAlias2.Foo f, IResourceAlias1.Foo g) { - var newList = new List(); - newList.Add(f.thing); - newList.Add(g.thing); - return newList; - } - } -} - -namespace TestWorld { - using TestWorld.wit.exports.test.resourceAliasRedux; - - public class TestWorldImpl : ITestWorld { - public static List Test(List things) { - return things; - } - } -} diff --git a/tests/runtime/resource_alias_redux/runner.cs b/tests/runtime/resource_alias_redux/runner.cs index ffebacee0..704a62138 100644 --- a/tests/runtime/resource_alias_redux/runner.cs +++ b/tests/runtime/resource_alias_redux/runner.cs @@ -1,8 +1,8 @@ using System; using System.Runtime.InteropServices; using System.Diagnostics; -using RunnerWorld.wit.imports.test.resourceAliasRedux; -using RunnerWorld.wit.imports; +using RunnerWorld.wit.Imports.test.resourceAliasRedux; +using RunnerWorld.wit.Imports; using System.Text; namespace RunnerWorld; @@ -11,19 +11,19 @@ public class RunnerWorldImpl : IRunnerWorld { public static void Run() { - IResourceAlias1.Thing thing1 = new IResourceAlias1.Thing("Ni Hao"); - List myList = new List(); + IResourceAlias1Importa.Thing thing1 = new IResourceAlias1Imports.Thing("Ni Hao"); + List myList = new List(); myList.Add(thing1); - List ret = TheTestInterop.Test(myList); + List ret = ITheTestImports.Test(myList); Debug.Assert(ret[0].Get() == "Ni Hao GuestThing GuestThing.get"); - ret = ResourceAlias1Interop.A( - new IResourceAlias1.Foo(new IResourceAlias1.Thing("Ciao"))); + ret = IResourceAlias1Imports.A( + new IResourceAlias1Imports.Foo(new IResourceAlias1Imports.Thing("Ciao"))); Debug.Assert(ret[0].Get() == "Ciao GuestThing GuestThing.get"); - ret = ResourceAlias2Interop.B( - new IResourceAlias2.Foo(new IResourceAlias1.Thing("Ciao")), - new IResourceAlias1.Foo(new IResourceAlias1.Thing("Aloha")) + ret = IResourceAlias2Imports.B( + new IResourceAlias2Imports.Foo(new IResourceAlias1Imports.Thing("Ciao")), + new IResourceAlias1Imports.Foo(new IResourceAlias1Imports.Thing("Aloha")) ); Debug.Assert(ret[0].Get() == "Ciao GuestThing GuestThing.get"); Debug.Assert(ret[1].Get() == "Aloha GuestThing GuestThing.get"); diff --git a/tests/runtime/resource_alias_redux/test.cs b/tests/runtime/resource_alias_redux/test.cs new file mode 100644 index 000000000..fff69a4d4 --- /dev/null +++ b/tests/runtime/resource_alias_redux/test.cs @@ -0,0 +1,45 @@ +using TestWorld.wit.Exports.test.resourceAliasRedux; + +namespace TestWorld.wit.Exports +{ + public class ResourceAlias1ExportsImpl : IResourceAlias1Exports { + public class Thing : IResourceAlias1Exports.Thing, IResourceAlias1Exports.IThing { + public string val; + + public Thing(string v) { + this.val = v + " GuestThing"; + } + + public string Get() { + return this.val + " GuestThing.get"; + } + } + + public static List A(IResourceAlias1Exports.Foo f) { + var newList = new List(); + newList.Add(f.thing); + return newList; + } + } + + public class ResourceAlias2ExportsImpl : IResourceAlias2Exports { + public static List B(IResourceAlias2Exports.Foo f, IResourceAlias1Exports.Foo g) { + var newList = new List(); + newList.Add(f.thing); + newList.Add(g.thing); + return newList; + } + } +} + +namespace TestWorld { + using TestWorld.wit.Exports.test.resourceAliasRedux; + using TestWorld.wit.Exports; + + public class TheTestExportsImpl : ITheTestExports + { + public static List Test(List things) { + return things; + } + } +} diff --git a/tests/runtime/resource_borrow_in_record/runner.cs b/tests/runtime/resource_borrow_in_record/runner.cs index 187812166..40316dc20 100644 --- a/tests/runtime/resource_borrow_in_record/runner.cs +++ b/tests/runtime/resource_borrow_in_record/runner.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; using System.Diagnostics; -using RunnerWorld.wit.imports.test.resourceBorrowInRecord; +using RunnerWorld.wit.Imports.test.resourceBorrowInRecord; using System.Text; namespace RunnerWorld; @@ -10,13 +10,13 @@ public class RunnerWorldImpl : IRunnerWorld { public static void Run() { - IToTest.Thing thing1 = new IToTest.Thing("Bonjour"); - IToTest.Thing thing2 = new IToTest.Thing("mon cher"); + IToTestImports.Thing thing1 = new IToTestImports.Thing("Bonjour"); + IToTestImports.Thing thing2 = new IToTestImports.Thing("mon cher"); - List myList = new List(); - myList.Add(new IToTest.Foo(thing1)); - myList.Add(new IToTest.Foo(thing2)); - List ret = ToTestInterop.Test(myList); + List myList = new List(); + myList.Add(new IToTestImports.Foo(thing1)); + myList.Add(new IToTestImports.Foo(thing2)); + List ret = IToTestImports.Test(myList); Debug.Assert(ret[0].Get() == "Bonjour new test get"); Debug.Assert(ret[1].Get() == "mon cher new test get"); diff --git a/tests/runtime/resource_borrow_in_record/test.cs b/tests/runtime/resource_borrow_in_record/test.cs index d0f417230..c78183707 100644 --- a/tests/runtime/resource_borrow_in_record/test.cs +++ b/tests/runtime/resource_borrow_in_record/test.cs @@ -1,7 +1,7 @@ -using TestWorld.wit.exports.test.resourceBorrowInRecord; +using TestWorld.wit.Exports.test.resourceBorrowInRecord; -public class ToTestImpl : IToTest { - public class Thing : IToTest.Thing, IToTest.IThing { +public class ToTestExportsImpl : IToTestExports { + public class Thing : IToTestExports.Thing, IToTestExports.IThing { public string val; public Thing(string v) { @@ -17,8 +17,8 @@ public string Get() { } } - public static List Test(List v) { - var myResult = new List(); + public static List Test(List v) { + var myResult = new List(); foreach (var foo in v) { myResult.Add(new Thing((Thing) foo.thing)); diff --git a/tests/runtime/resource_floats/intermediate.cs b/tests/runtime/resource_floats/intermediate.cs index f1b3190f0..d135c7da2 100644 --- a/tests/runtime/resource_floats/intermediate.cs +++ b/tests/runtime/resource_floats/intermediate.cs @@ -1,29 +1,29 @@ -using Import1 = IntermediateWorld.wit.imports.IImports; -using Import2 = IntermediateWorld.wit.imports.test.resourceFloats.ITest; +using Import1 = IntermediateWorld.wit.Imports.IImportsImports; +using Import2 = IntermediateWorld.wit.Imports.test.resourceFloats.ITestImports; -namespace IntermediateWorld.wit.exports +namespace IntermediateWorld.wit.Exports { - public class ExportsImpl : IExports { - public class Float : IExports.Float, IExports.IFloat { + public class ExportsExportsImpl : IExportsExports { + public class Float : IExportsExports.Float, IExportsExports.IFloat { public Import1.Float val; public Float(double v) { - this.val = new Import1.Float(v + 1.0); + this.val = new Import1.Float(v + 1.0); } public double Get() { - return this.val.Get() + 3.0; + return this.val.Get() + 3.0; } - public static IExports.Float Add(IExports.Float a, double b) { - return new Float(Import1.Float.Add(((Float) a).val, b).Get() + 5.0); + public static IExportsExports.Float Add(IExportsExports.Float a, double b) { + return new Float(Import1.Float.Add(((Float) a).val, b).Get() + 5.0); } } } } namespace IntermediateWorld { - public class IntermediateWorldImpl : IIntermediateWorld { + public class IntermediateWorldExportsImpl : Import2 { public static Import2.Float Add(Import2.Float a, Import2.Float b) { return new Import2.Float(a.Get() + b.Get() + 5.0); } diff --git a/tests/runtime/resource_with_lists/resource-with-lists.cs b/tests/runtime/resource_with_lists/resource-with-lists.cs index 7a9804149..ea334eda3 100644 --- a/tests/runtime/resource_with_lists/resource-with-lists.cs +++ b/tests/runtime/resource_with_lists/resource-with-lists.cs @@ -1,11 +1,10 @@ using System.Text; -using Import = ResourceWithListsWorld.wit.imports.test.resourceWithLists.ITest; -using Host = ResourceWithListsWorld.wit.imports.test.resourceWithLists.TestInterop; +using Import = ResourceWithListsWorld.wit.Imports.test.resourceWithLists.ITestImports; -namespace ResourceWithListsWorld.wit.exports.test.resourceWithLists +namespace ResourceWithListsWorld.wit.Exports.test.resourceWithLists { - public class TestImpl : ITest { - public class Thing : ITest.Thing, ITest.IThing { + public class TestExportsImpl : ITestExports { + public class Thing : ITestExports.Thing, ITestExports.IThing { public Import.Thing val; public Thing(byte[] v) { diff --git a/tests/runtime/resources/resources.cs b/tests/runtime/resources/resources.cs index 7528234ae..ee8255a17 100644 --- a/tests/runtime/resources/resources.cs +++ b/tests/runtime/resources/resources.cs @@ -1,45 +1,45 @@ using System.Diagnostics; using ResourcesWorld; -using ResourcesWorld.wit.imports; +using ResourcesWorld.wit.Imports; -namespace ResourcesWorld.wit.exports +namespace ResourcesWorld.wit.Exports { - public class ExportsImpl : IExports + public class ExportsExportsImpl : IExportsExports { - public static IExports.Z Add(IExports.Z a, IExports.Z b) + public static IExportsExports.Z Add(IExportsExports.Z a, IExportsExports.Z b) { return new Z(((Z) a).val + ((Z) b).val); } - public static void Consume(IExports.X x) + public static void Consume(IExportsExports.X x) { x.Dispose(); } public static void TestImports() { - var y1 = new IImports.Y(10); + var y1 = new IImportsImports.Y(10); Debug.Assert(y1.GetA() == 10); y1.SetA(20); Debug.Assert(y1.GetA() == 20); - var y2 = IImports.Y.Add(y1, 20); + var y2 = IImportsImports.Y.Add(y1, 20); Debug.Assert(y2.GetA() == 40); - var y3 = new IImports.Y(1); - var y4 = new IImports.Y(2); + var y3 = new IImportsImports.Y(1); + var y4 = new IImportsImports.Y(2); Debug.Assert(y3.GetA() == 1); Debug.Assert(y4.GetA() == 2); y3.SetA(10); y4.SetA(20); Debug.Assert(y3.GetA() == 10); Debug.Assert(y4.GetA() == 20); - var y5 = IImports.Y.Add(y3, 20); - var y6 = IImports.Y.Add(y4, 30); + var y5 = IImportsImports.Y.Add(y3, 20); + var y6 = IImportsImports.Y.Add(y4, 30); Debug.Assert(y5.GetA() == 30); Debug.Assert(y6.GetA() == 50); } - public class X : IExports.X, IExports.IX { + public class X : IExportsExports.X, IExportsExports.IX { public int val; public X(int val) { @@ -54,14 +54,14 @@ public int GetA() { return val; } - public static IExports.X Add(IExports.X a, int b) { + public static IExportsExports.X Add(IExportsExports.X a, int b) { var myA = (X) a; myA.SetA(myA.GetA() + b); return myA; } } - public class Z : IExports.Z, IExports.IZ { + public class Z : IExportsExports.Z, IExportsExports.IZ { private static uint numDropped = 0; public int val; @@ -85,7 +85,7 @@ override protected void Dispose(bool disposing) { } } - public class KebabCase : IExports.KebabCase, IExports.IKebabCase { + public class KebabCase : IExportsExports.KebabCase, IExportsExports.IKebabCase { public uint val; public KebabCase(uint val) { @@ -96,7 +96,7 @@ public uint GetA() { return val; } - public static uint TakeOwned(IExports.KebabCase a) { + public static uint TakeOwned(IExportsExports.KebabCase a) { return ((KebabCase) a).val; } } diff --git a/tests/runtime/results/intermediate.cs b/tests/runtime/results/intermediate.cs index 7f09fa335..084e2c25a 100644 --- a/tests/runtime/results/intermediate.cs +++ b/tests/runtime/results/intermediate.cs @@ -1,17 +1,17 @@ -namespace IntermediateWorld.wit.exports.test.results +namespace IntermediateWorld.wit.Exports.test.results { - public class TestImpl : ITest + public class TestExportsImpl : ITestExports { public static float StringError(float a) { - return imports.test.results.TestInterop.StringError(a); + return Imports.test.results.ITestImports.StringError(a); } public static float EnumError(float a) { try { - return imports.test.results.TestInterop.EnumError(a); - } catch (WitException e) { + return Imports.test.results.ITestImports.EnumError(a); + } catch (WitException e) { throw new WitException(e.TypedValue, 0); } } @@ -19,22 +19,22 @@ public static float EnumError(float a) public static float RecordError(float a) { try { - return imports.test.results.TestInterop.RecordError(a); - } catch (WitException e) { - throw new WitException(new ITest.E2(e.TypedValue.line, e.TypedValue.column), 0); + return Imports.test.results.ITestImports.RecordError(a); + } catch (WitException e) { + throw new WitException(new ITestExports.E2(e.TypedValue.line, e.TypedValue.column), 0); } } public static float VariantError(float a) { try { - return imports.test.results.TestInterop.VariantError(a); - } catch (WitException e) - when (e.TypedValue.Tag == imports.test.results.ITest.E3.Tags.E1) { - throw new WitException(ITest.E3.E1((ITest.E)Enum.Parse(typeof(ITest.E), e.TypedValue.AsE1.ToString())), 0); - } catch (WitException e) - when (e.TypedValue.Tag == imports.test.results.ITest.E3.Tags.E2) { - throw new WitException(ITest.E3.E2(new ITest.E2(e.TypedValue.AsE2.line, e.TypedValue.AsE2.column)), 0); + return Imports.test.results.ITestImports.VariantError(a); + } catch (WitException e) + when (e.TypedValue.Tag == Imports.test.results.ITestImports.E3.Tags.E1) { + throw new WitException(ITestExports.E3.E1((ITestExports.E)Enum.Parse(typeof(ITestExports.E), e.TypedValue.AsE1.ToString())), 0); + } catch (WitException e) + when (e.TypedValue.Tag == Imports.test.results.ITestImports.E3.Tags.E2) { + throw new WitException(ITestExports.E3.E2(new ITestExports.E2(e.TypedValue.AsE2.line, e.TypedValue.AsE2.column)), 0); } catch { throw new Exception("unreachable"); @@ -43,12 +43,12 @@ public static float VariantError(float a) public static uint EmptyError(uint a) { - return imports.test.results.TestInterop.EmptyError(a); + return Imports.test.results.ITestImports.EmptyError(a); } public static void DoubleError(uint a) { - imports.test.results.TestInterop.DoubleError(a); + Imports.test.results.ITestImports.DoubleError(a); } } } diff --git a/tests/runtime/results/intermediate_with_wit_results.cs b/tests/runtime/results/intermediate_with_wit_results.cs index d8710dd5c..f48ac5724 100644 --- a/tests/runtime/results/intermediate_with_wit_results.cs +++ b/tests/runtime/results/intermediate_with_wit_results.cs @@ -1,61 +1,62 @@ //@ args = '--with-wit-results' +using IntermediateWorld.wit.Imports.test.results; -namespace IntermediateWorld.wit.exports.test.results +namespace IntermediateWorld.wit.Exports.test.results { - public class TestImpl : ITest + public class TestExportsImpl : ITestExports { public static Result StringError(float a) { - return imports.test.results.TestInterop.StringError(a); + return ITestImports.StringError(a); } - public static Result EnumError(float a) + public static Result EnumError(float a) { - var result = imports.test.results.TestInterop.EnumError(a); + var result = ITestImports.EnumError(a); if (result.IsOk) { - return Result.Ok(result.AsOk); + return Result.Ok(result.AsOk); } else { switch (result.AsErr){ - case imports.test.results.ITest.E.A: - return Result.Err(ITest.E.A); - case imports.test.results.ITest.E.B: - return Result.Err(ITest.E.B); - case imports.test.results.ITest.E.C: - return Result.Err(ITest.E.C); + case ITestImports.E.A: + return Result.Err(ITestExports.E.A); + case ITestImports.E.B: + return Result.Err(ITestExports.E.B); + case ITestImports.E.C: + return Result.Err(ITestExports.E.C); default: throw new Exception("unreachable"); } } } - public static Result RecordError(float a) + public static Result RecordError(float a) { - var result = imports.test.results.TestInterop.RecordError(a); + var result = ITestImports.RecordError(a); if (result.IsOk) { - return Result.Ok(result.AsOk); + return Result.Ok(result.AsOk); } else { switch (result.AsErr) { - case imports.test.results.ITest.E2: - return Result.Err(new ITest.E2(result.AsErr.line, result.AsErr.column)); + case ITestImports.E2: + return Result.Err(new ITestExports.E2(result.AsErr.line, result.AsErr.column)); default: throw new Exception("unreachable"); } } } - public static Result VariantError(float a) + public static Result VariantError(float a) { - var result = imports.test.results.TestInterop.VariantError(a); + var result = ITestImports.VariantError(a); if (result.IsOk) { - return Result.Ok(result.AsOk); + return Result.Ok(result.AsOk); } else { switch (result.AsErr) { - case imports.test.results.ITest.E3: + case ITestImports.E3: switch (result.AsErr.Tag){ - case imports.test.results.ITest.E3.Tags.E1: - return Result.Err(ITest.E3.E1((ITest.E)Enum.Parse(typeof(ITest.E), result.AsErr.AsE1.ToString()))); - case imports.test.results.ITest.E3.Tags.E2: - return Result.Err(ITest.E3.E2(new ITest.E2(result.AsErr.AsE2.line, result.AsErr.AsE2.column))); + case ITestImports.E3.Tags.E1: + return Result.Err(ITestExports.E3.E1((ITestExports.E)Enum.Parse(typeof(ITestExports.E), result.AsErr.AsE1.ToString()))); + case ITestImports.E3.Tags.E2: + return Result.Err(ITestExports.E3.E2(new ITestExports.E2(result.AsErr.AsE2.line, result.AsErr.AsE2.column))); default: throw new Exception("unreachable"); } @@ -67,12 +68,12 @@ public static Result StringError(float a) public static Result EmptyError(uint a) { - return imports.test.results.TestInterop.EmptyError(a); + return ITestImports.EmptyError(a); } public static Result, string> DoubleError(uint a) { - return imports.test.results.TestInterop.DoubleError(a); + return ITestImports.DoubleError(a); } } } diff --git a/tests/runtime/rust/resource_into_inner/test.cs b/tests/runtime/rust/resource_into_inner/test.cs index aa784569d..46001f3c1 100644 --- a/tests/runtime/rust/resource_into_inner/test.cs +++ b/tests/runtime/rust/resource_into_inner/test.cs @@ -1,16 +1,17 @@ using System.Diagnostics; +using TestWorld.wit.Exports.test.resourceIntoInner; -namespace TestWorld.wit.exports.test.resourceIntoInner +namespace TestWorld.wit.Exports.test.resourceIntoInner { - public class ToTestImpl : IToTest { - public class Thing : IToTest.Thing, IToTest.IThing { + public class ToTestExportsImpl : IToTestExports { + public class Thing : IToTestExports.Thing, IToTestExports.IThing { public string val; public Thing(string v) { this.val = v; } } - + public static void Test() { // Unlike wasm.rs, this doesn't test anything interesting // due there being no ownership semantics in C# (and also diff --git a/tests/runtime/strings/runner.cs b/tests/runtime/strings/runner.cs index f602e9578..0420d063a 100644 --- a/tests/runtime/strings/runner.cs +++ b/tests/runtime/strings/runner.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; using System.Diagnostics; -using RunnerWorld.wit.imports.test.strings; +using RunnerWorld.wit.Imports.test.strings; using System.Text; namespace RunnerWorld; @@ -10,10 +10,10 @@ public class RunnerWorldImpl : IRunnerWorld { public static void Run() { - ToTestInterop.TakeBasic("latin utf16"); - Debug.Assert(ToTestInterop.ReturnUnicode() == "🚀🚀🚀 𠈄𓀀"); + IToTestImports.TakeBasic("latin utf16"); + Debug.Assert(IToTestImports.ReturnUnicode() == "🚀🚀🚀 𠈄𓀀"); - Debug.Assert(ToTestInterop.ReturnEmpty() == string.Empty); - Debug.Assert(ToTestInterop.Roundtrip("🚀🚀🚀 𠈄𓀀") == "🚀🚀🚀 𠈄𓀀"); + Debug.Assert(IToTestImports.ReturnEmpty() == string.Empty); + Debug.Assert(IToTestImports.Roundtrip("🚀🚀🚀 𠈄𓀀") == "🚀🚀🚀 𠈄𓀀"); } } diff --git a/tests/runtime/strings/test.cs b/tests/runtime/strings/test.cs index b5dfc63a8..458f16dd5 100644 --- a/tests/runtime/strings/test.cs +++ b/tests/runtime/strings/test.cs @@ -1,10 +1,8 @@ -using System; -using System.Runtime.InteropServices; using System.Diagnostics; -namespace TestWorld.wit.exports.test.strings +namespace TestWorld.wit.Exports.test.strings { - public class ToTestImpl : ITestWorld + public class ToTestExportsImpl : IToTestExports { public static void TakeBasic(string s) { diff --git a/tests/runtime/variants/runner.cs b/tests/runtime/variants/runner.cs index 1e92bbd43..1d1900f0c 100644 --- a/tests/runtime/variants/runner.cs +++ b/tests/runtime/variants/runner.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; using System.Diagnostics; -using RunnerWorld.wit.imports.test.variants; +using RunnerWorld.wit.Imports.test.variants; using System.Text; using RunnerWorld; @@ -11,15 +11,15 @@ public class RunnerWorldImpl : IRunnerWorld { public static void Run() { - Debug.Assert(ToTestInterop.RoundtripOption(1.0f).Value == 1); - Debug.Assert(ToTestInterop.RoundtripOption(null).HasValue == false); - Debug.Assert(ToTestInterop.RoundtripOption(2.0f).Value == 2); + Debug.Assert(IToTestImports.RoundtripOption(1.0f).Value == 1); + Debug.Assert(IToTestImports.RoundtripOption(null).HasValue == false); + Debug.Assert(IToTestImports.RoundtripOption(2.0f).Value == 2); - Debug.Assert(ToTestInterop.RoundtripResult(Result.Ok(2)) == 2.0); - Debug.Assert(ToTestInterop.RoundtripResult(Result.Ok(4)) == 4.0); + Debug.Assert(IToTestImports.RoundtripResult(Result.Ok(2)) == 2.0); + Debug.Assert(IToTestImports.RoundtripResult(Result.Ok(4)) == 4.0); try { - ToTestInterop.RoundtripResult(Result.Err(5.3f)); + IToTestImports.RoundtripResult(Result.Err(5.3f)); throw new Exception(); } catch (WitException e) @@ -27,14 +27,13 @@ public static void Run() Debug.Assert((byte)e.Value == 5); } - Debug.Assert(ToTestInterop.RoundtripEnum(IToTest.E1.A) == IToTest.E1.A); - Debug.Assert(ToTestInterop.RoundtripEnum(IToTest.E1.B) == IToTest.E1.B); - - Debug.Assert(ToTestInterop.InvertBool(true) == false); - Debug.Assert(ToTestInterop.InvertBool(false) == true); + Debug.Assert(IToTestImports.RoundtripEnum(IToTestImports.E1.A) == IToTestImports.E1.A); + Debug.Assert(IToTestImports.RoundtripEnum(IToTestImports.E1.B) == IToTestImports.E1.B); + Debug.Assert(IToTestImports.InvertBool(true) == false); + Debug.Assert(IToTestImports.InvertBool(false) == true); var (a1, a2, a3, a4, a5, a6) = - ToTestInterop.VariantCasts((IToTest.C1.A(1), IToTest.C2.A(2), IToTest.C3.A(3), IToTest.C4.A(4), IToTest.C5.A(5), IToTest.C6.A(6.0f))); + IToTestImports.VariantCasts((IToTestImports.C1.A(1), IToTestImports.C2.A(2), IToTestImports.C3.A(3), IToTestImports.C4.A(4), IToTestImports.C5.A(5), IToTestImports.C6.A(6.0f))); Debug.Assert(a1.AsA == 1); Debug.Assert(a2.AsA == 2); Debug.Assert(a3.AsA == 3); @@ -43,7 +42,7 @@ public static void Run() Debug.Assert(a6.AsA == 6.0f); var (b1, b2, b3, b4, b5, b6) = -ToTestInterop.VariantCasts((IToTest.C1.B(1), IToTest.C2.B(2), IToTest.C3.B(3), IToTest.C4.B(4), IToTest.C5.B(5), IToTest.C6.B(6.0))); +IToTestImports.VariantCasts((IToTestImports.C1.B(1), IToTestImports.C2.B(2), IToTestImports.C3.B(3), IToTestImports.C4.B(4), IToTestImports.C5.B(5), IToTestImports.C6.B(6.0))); Debug.Assert(b1.AsB == 1); Debug.Assert(b2.AsB == 2.0f); Debug.Assert(b3.AsB == 3.0f); @@ -52,25 +51,25 @@ public static void Run() Debug.Assert(b6.AsB == 6.0); var (za1, za2, za3, za4) = -ToTestInterop.VariantZeros((IToTest.Z1.A(1), IToTest.Z2.A(2), IToTest.Z3.A(3.0f), IToTest.Z4.A(4.0f))); +IToTestImports.VariantZeros((IToTestImports.Z1.A(1), IToTestImports.Z2.A(2), IToTestImports.Z3.A(3.0f), IToTestImports.Z4.A(4.0f))); Debug.Assert(za1.AsA == 1); Debug.Assert(za2.AsA == 2); Debug.Assert(za3.AsA == 3.0f); Debug.Assert(za4.AsA == 4.0f); var (zb1, zb2, zb3, zb4) = -ToTestInterop.VariantZeros((IToTest.Z1.B(), IToTest.Z2.B(), IToTest.Z3.B(), IToTest.Z4.B())); +IToTestImports.VariantZeros((IToTestImports.Z1.B(), IToTestImports.Z2.B(), IToTestImports.Z3.B(), IToTestImports.Z4.B())); //TODO: Add comparison operator to variants and None //Debug.Assert(zb1.AsB == IToTest.Z1.b()); //Debug.Assert(zb2.AsB == IToTest.Z2.b()); //Debug.Assert(zb3.AsB == IToTest.Z3.b()); //Debug.Assert(zb4.AsB == IToTest.Z4.b()); - ToTestInterop.VariantTypedefs(null, false, Result.Err(new None())); + IToTestImports.VariantTypedefs(null, false, Result.Err(new None())); - var (a, b, c) = ToTestInterop.VariantEnums(true, Result.Ok(new None()), IToTest.MyErrno.SUCCESS); + var (a, b, c) = IToTestImports.VariantEnums(true, Result.Ok(new None()), IToTestImports.MyErrno.SUCCESS); Debug.Assert(a == true); var test = b.AsOk; - Debug.Assert(c == IToTest.MyErrno.SUCCESS); + Debug.Assert(c == IToTestImports.MyErrno.SUCCESS); } } diff --git a/tests/runtime/variants/test.cs b/tests/runtime/variants/test.cs index 3530be950..bad27cd16 100644 --- a/tests/runtime/variants/test.cs +++ b/tests/runtime/variants/test.cs @@ -1,6 +1,6 @@ -namespace TestWorld.wit.exports.test.variants +namespace TestWorld.wit.Exports.test.variants { - public class ToTestImpl : ITestWorld + public class ToTestExportsImpl : ITestWorldImports { public static byte? RoundtripOption(float? a) { @@ -17,7 +17,7 @@ public static double RoundtripResult(Result a) } } - public static IToTest.E1 RoundtripEnum(IToTest.E1 a) + public static IToTestExports.E1 RoundtripEnum(IToTestExports.E1 a) { return a; } @@ -27,21 +27,21 @@ public static bool InvertBool(bool a) return !a; } - public static (IToTest.C1, IToTest.C2, IToTest.C3, IToTest.C4, IToTest.C5, IToTest.C6) - VariantCasts((IToTest.C1, IToTest.C2, IToTest.C3, IToTest.C4, IToTest.C5, IToTest.C6) a) + public static (IToTestExports.C1, IToTestExports.C2, IToTestExports.C3, IToTestExports.C4, IToTestExports.C5, IToTestExports.C6) + VariantCasts((IToTestExports.C1, IToTestExports.C2, IToTestExports.C3, IToTestExports.C4, IToTestExports.C5, IToTestExports.C6) a) { return a; } - public static (bool, Result, IToTest.MyErrno) - VariantEnums(bool a, Result b, IToTest.MyErrno c) + public static (bool, Result, IToTestExports.MyErrno) + VariantEnums(bool a, Result b, IToTestExports.MyErrno c) { return new(a, b, c); } public static void VariantTypedefs(uint? a, bool b, Result c) { } - public static (IToTest.Z1, IToTest.Z2, IToTest.Z3, IToTest.Z4) VariantZeros((IToTest.Z1, IToTest.Z2, IToTest.Z3, IToTest.Z4) a) + public static (IToTestExports.Z1, IToTestExports.Z2, IToTestExports.Z3, IToTestExports.Z4) VariantZeros((IToTestExports.Z1, IToTestExports.Z2, IToTestExports.Z3, IToTestExports.Z4) a) { return a; } diff --git a/tests/runtime/versions/runner.cs b/tests/runtime/versions/runner.cs index ee8e1f188..fc477ed66 100644 --- a/tests/runtime/versions/runner.cs +++ b/tests/runtime/versions/runner.cs @@ -1,8 +1,6 @@ -using System; -using System.Runtime.InteropServices; using System.Diagnostics; -using v1 = RunnerWorld.wit.imports.test.dep.v0_1_0; -using v2 = RunnerWorld.wit.imports.test.dep.v0_2_0; +using v1 = RunnerWorld.wit.Imports.test.dep.v0_1_0; +using v2 = RunnerWorld.wit.Imports.test.dep.v0_2_0; using System.Text; namespace RunnerWorld; @@ -11,10 +9,10 @@ public class RunnerWorldImpl : IRunnerWorld { public static void Run() { - Debug.Assert(v1.TestInterop.X() == 1.0f); - Debug.Assert(v1.TestInterop.Y(1.0f) == 2.0f); + Debug.Assert(v1.ITestImports.X() == 1.0f); + Debug.Assert(v1.ITestImports.Y(1.0f) == 2.0f); - Debug.Assert(v2.TestInterop.X() == 2.0f); - Debug.Assert(v2.TestInterop.Z(1.0f, 1.0f) == 4.0f); + Debug.Assert(v2.ITestImports.X() == 2.0f); + Debug.Assert(v2.ITestImports.Z(1.0f, 1.0f) == 4.0f); } } diff --git a/tests/runtime/versions/test.cs b/tests/runtime/versions/test.cs index a5eb592b1..62c90f765 100644 --- a/tests/runtime/versions/test.cs +++ b/tests/runtime/versions/test.cs @@ -1,7 +1,7 @@ using System.Diagnostics; -namespace TestWorld.wit.exports.test.dep.v0_1_0 { - public class TestImpl : TestWorld.wit.exports.test.dep.v0_1_0.ITest +namespace TestWorld.wit.Exports.test.dep.v0_1_0 { + public class TestExportsImpl : TestWorld.wit.Exports.test.dep.v0_1_0.ITestExports { public static float X() { return 1.0f; @@ -13,9 +13,9 @@ public static float Y(float a){ } } -namespace TestWorld.wit.exports.test.dep.v0_2_0 +namespace TestWorld.wit.Exports.test.dep.v0_2_0 { - public class TestImpl : TestWorld.wit.exports.test.dep.v0_2_0.ITest + public class TestExportsImpl : TestWorld.wit.Exports.test.dep.v0_2_0.ITestExports { public static float X() { return 2.0f;