diff --git a/crates/csharp/src/RepTable.cs b/crates/csharp/src/RepTable.cs index 6e3dd2985..64948e126 100644 --- a/crates/csharp/src/RepTable.cs +++ b/crates/csharp/src/RepTable.cs @@ -32,7 +32,7 @@ internal int Add(T v) { internal T Get(nint rep) { if (list[(int)rep] is Vacant) { - throw new ArgumentException("invalid rep"); + throw new global::System.ArgumentException("invalid rep"); } return (T) list[(int)rep]; } diff --git a/crates/csharp/src/function.rs b/crates/csharp/src/function.rs index 4b68c0a43..375a10330 100644 --- a/crates/csharp/src/function.rs +++ b/crates/csharp/src/function.rs @@ -145,7 +145,7 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> { switch ({op}.Tag) {{ {cases} - default: throw new ArgumentException($"invalid discriminant: {{{op}}}"); + default: throw new global::System.ArgumentException("invalid discriminant: " + {op}); }} "# ); @@ -222,7 +222,7 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> { switch ({op}) {{ {cases} - default: throw new ArgumentException($"invalid discriminant: {{{op}}}"); + default: throw new global::System.ArgumentException("invalid discriminant:" + {op}); }} "# ); @@ -363,7 +363,7 @@ impl<'a, 'b> FunctionBindgen<'a, 'b> { {{ {cases} - default: throw new ArgumentException($"invalid nesting level: {{e.NestingLevel}}"); + default: throw new global::System.ArgumentException($"invalid nesting level: {{e.NestingLevel}}"); }} }} "# @@ -400,22 +400,22 @@ impl Bindgen for FunctionBindgen<'_, '_> { })), Instruction::I32Load { offset } | Instruction::PointerLoad { offset } - | Instruction::LengthLoad { offset } => results.push(format!("BitConverter.ToInt32(new Span((void*)({} + {offset}), 4))",operands[0],offset = offset.size_wasm32())), - Instruction::I32Load8U { offset } => results.push(format!("new Span((void*)({} + {offset}), 1)[0]",operands[0],offset = offset.size_wasm32())), - Instruction::I32Load8S { offset } => results.push(format!("(sbyte)new Span((void*)({} + {offset}), 1)[0]",operands[0],offset = offset.size_wasm32())), - Instruction::I32Load16U { offset } => results.push(format!("BitConverter.ToUInt16(new Span((void*)({} + {offset}), 2))",operands[0],offset = offset.size_wasm32())), - Instruction::I32Load16S { offset } => results.push(format!("BitConverter.ToInt16(new Span((void*)({} + {offset}), 2))",operands[0],offset = offset.size_wasm32())), - Instruction::I64Load { offset } => results.push(format!("BitConverter.ToInt64(new Span((void*)({} + {offset}), 8))",operands[0],offset = offset.size_wasm32())), - Instruction::F32Load { offset } => results.push(format!("BitConverter.ToSingle(new Span((void*)({} + {offset}), 4))",operands[0],offset = offset.size_wasm32())), - Instruction::F64Load { offset } => results.push(format!("BitConverter.ToDouble(new Span((void*)({} + {offset}), 8))",operands[0],offset = offset.size_wasm32())), + | Instruction::LengthLoad { offset } => results.push(format!("global::System.BitConverter.ToInt32(new global::System.Span((void*)({} + {offset}), 4))",operands[0],offset = offset.size_wasm32())), + Instruction::I32Load8U { offset } => results.push(format!("new global::System.Span((void*)({} + {offset}), 1)[0]",operands[0],offset = offset.size_wasm32())), + Instruction::I32Load8S { offset } => results.push(format!("(sbyte)new global::System.Span((void*)({} + {offset}), 1)[0]",operands[0],offset = offset.size_wasm32())), + Instruction::I32Load16U { offset } => results.push(format!("global::System.BitConverter.ToUInt16(new global::System.Span((void*)({} + {offset}), 2))",operands[0],offset = offset.size_wasm32())), + Instruction::I32Load16S { offset } => results.push(format!("global::System.BitConverter.ToInt16(new global::System.Span((void*)({} + {offset}), 2))",operands[0],offset = offset.size_wasm32())), + Instruction::I64Load { offset } => results.push(format!("global::System.BitConverter.ToInt64(new global::System.Span((void*)({} + {offset}), 8))",operands[0],offset = offset.size_wasm32())), + Instruction::F32Load { offset } => results.push(format!("global::System.BitConverter.ToSingle(new global::System.Span((void*)({} + {offset}), 4))",operands[0],offset = offset.size_wasm32())), + Instruction::F64Load { offset } => results.push(format!("global::System.BitConverter.ToDouble(new global::System.Span((void*)({} + {offset}), 8))",operands[0],offset = offset.size_wasm32())), Instruction::I32Store { offset } | Instruction::PointerStore { offset } - | Instruction::LengthStore { offset } => uwriteln!(self.src, "BitConverter.TryWriteBytes(new Span((void*)({} + {offset}), 4), {});", operands[1], operands[0],offset = offset.size_wasm32()), + | Instruction::LengthStore { offset } => uwriteln!(self.src, "global::System.BitConverter.TryWriteBytes(new global::System.Span((void*)({} + {offset}), 4), {});", operands[1], operands[0],offset = offset.size_wasm32()), Instruction::I32Store8 { offset } => uwriteln!(self.src, "*(byte*)({} + {offset}) = (byte){};", operands[1], operands[0],offset = offset.size_wasm32()), - Instruction::I32Store16 { offset } => uwriteln!(self.src, "BitConverter.TryWriteBytes(new Span((void*)({} + {offset}), 2), (short){});", operands[1], operands[0],offset = offset.size_wasm32()), - Instruction::I64Store { offset } => uwriteln!(self.src, "BitConverter.TryWriteBytes(new Span((void*)({} + {offset}), 8), unchecked((long){}));", operands[1], operands[0],offset = offset.size_wasm32()), - Instruction::F32Store { offset } => uwriteln!(self.src, "BitConverter.TryWriteBytes(new Span((void*)({} + {offset}), 4), unchecked((float){}));", operands[1], operands[0],offset = offset.size_wasm32()), - Instruction::F64Store { offset } => uwriteln!(self.src, "BitConverter.TryWriteBytes(new Span((void*)({} + {offset}), 8), unchecked((double){}));", operands[1], operands[0],offset = offset.size_wasm32()), + Instruction::I32Store16 { offset } => uwriteln!(self.src, "global::System.BitConverter.TryWriteBytes(new global::System.Span((void*)({} + {offset}), 2), (short){});", operands[1], operands[0],offset = offset.size_wasm32()), + Instruction::I64Store { offset } => uwriteln!(self.src, "global::System.BitConverter.TryWriteBytes(new global::System.Span((void*)({} + {offset}), 8), unchecked((long){}));", operands[1], operands[0],offset = offset.size_wasm32()), + Instruction::F32Store { offset } => uwriteln!(self.src, "global::System.BitConverter.TryWriteBytes(new global::System.Span((void*)({} + {offset}), 4), unchecked((float){}));", operands[1], operands[0],offset = offset.size_wasm32()), + Instruction::F64Store { offset } => uwriteln!(self.src, "global::System.BitConverter.TryWriteBytes(new global::System.Span((void*)({} + {offset}), 8), unchecked((double){}));", operands[1], operands[0],offset = offset.size_wasm32()), Instruction::I64FromU64 => results.push(format!("unchecked((long)({}))", operands[0])), Instruction::I32FromChar => results.push(format!("((int){})", operands[0])), @@ -680,7 +680,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { break; }} - default: throw new ArgumentException("invalid discriminant: " + ({op})); + default: throw new global::System.ArgumentException("invalid discriminant: " + ({op})); }} "# ); @@ -748,7 +748,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { uwrite!( self.src, " - var {handle} = GCHandle.Alloc({list}, GCHandleType.Pinned); + var {handle} = global::System.Runtime.InteropServices.GCHandle.Alloc({list}, global::System.Runtime.InteropServices.GCHandleType.Pinned); var {ptr} = {handle}.AddrOfPinnedObject(); cleanups.Add(()=> {handle}.Free()); " @@ -766,8 +766,8 @@ impl Bindgen for FunctionBindgen<'_, '_> { self.src, " var {byte_length} = ({size}) * {list}.Length; - var {address} = NativeMemory.Alloc((nuint)({byte_length})); - {list}.AsSpan().CopyTo(new Span<{ty}>({address},{byte_length})); + var {address} = global::System.Runtime.InteropServices.NativeMemory.Alloc((nuint)({byte_length})); + global::System.MemoryExtensions.AsSpan({list}).CopyTo(new global::System.Span<{ty}>({address},{byte_length})); " ); @@ -787,7 +787,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { self.src, " var {array} = new {ty}[{length}]; - new Span<{ty}>((void*)({address}), {length}).CopyTo(new Span<{ty}>({array})); + new global::System.Span<{ty}>((void*)({address}), {length}).CopyTo(new global::System.Span<{ty}>({array})); " ); @@ -805,9 +805,9 @@ impl Bindgen for FunctionBindgen<'_, '_> { uwriteln!( self.src, " - var {utf8_bytes} = Encoding.UTF8.GetBytes({op}); + var {utf8_bytes} = global::System.Text.Encoding.UTF8.GetBytes({op}); var {length} = {utf8_bytes}.Length; - var {gc_handle} = GCHandle.Alloc({utf8_bytes}, GCHandleType.Pinned); + var {gc_handle} = global::System.Runtime.InteropServices.GCHandle.Alloc({utf8_bytes}, global::System.Runtime.InteropServices.GCHandleType.Pinned); var {str_ptr} = {gc_handle}.AddrOfPinnedObject(); " ); @@ -825,34 +825,21 @@ impl Bindgen for FunctionBindgen<'_, '_> { uwriteln!( self.src, " - var {string_span} = {op}.AsSpan(); - var {length} = Encoding.UTF8.GetByteCount({string_span}); - var {str_ptr} = NativeMemory.Alloc((nuint){length}); - Encoding.UTF8.GetBytes({string_span}, new Span({str_ptr}, {length})); + var {string_span} = global::System.MemoryExtensions.AsSpan({op}); + var {length} = global::System.Text.Encoding.UTF8.GetByteCount({string_span}); + var {str_ptr} = global::System.Runtime.InteropServices.NativeMemory.Alloc((nuint){length}); + global::System.Text.Encoding.UTF8.GetBytes({string_span}, new global::System.Span({str_ptr}, {length})); " ); results.push(format!("(int){str_ptr}")); } results.push(format!("{length}")); - if FunctionKind::Freestanding == *self.kind || self.interface_gen.direction == Direction::Export { - self.interface_gen.require_interop_using("System.Text"); - self.interface_gen.require_interop_using("System.Runtime.InteropServices"); - } else { - self.interface_gen.require_using("System.Text"); - self.interface_gen.require_using("System.Runtime.InteropServices"); - } } Instruction::StringLift { .. } => { - if FunctionKind::Freestanding == *self.kind || self.interface_gen.direction == Direction::Export { - self.interface_gen.require_interop_using("System.Text"); - } else { - self.interface_gen.require_using("System.Text"); - } - results.push(format!( - "Encoding.UTF8.GetString((byte*){}, {})", + "global::System.Text.Encoding.UTF8.GetString((byte*){}, {})", operands[0], operands[1] )); } @@ -895,8 +882,8 @@ impl Bindgen for FunctionBindgen<'_, '_> { else {{ var {buffer_size} = {size} * (nuint){list}.Count; - {address} = NativeMemory.AlignedAlloc({buffer_size}, {align}); - cleanups.Add(() => NativeMemory.AlignedFree({address})); + {address} = global::System.Runtime.InteropServices.NativeMemory.AlignedAlloc({buffer_size}, {align}); + cleanups.Add(() => global::System.Runtime.InteropServices.NativeMemory.AlignedFree({address})); }} " ); @@ -906,7 +893,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { uwrite!(self.src, " var {buffer_size} = {size} * (nuint){list}.Count; - void* {address} = NativeMemory.AlignedAlloc({buffer_size}, {align}); + void* {address} = global::System.Runtime.InteropServices.NativeMemory.AlignedAlloc({buffer_size}, {align}); " ); } @@ -948,7 +935,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { uwrite!( self.src, " - var {array} = new List<{ty}>({length}); + var {array} = new global::System.Collections.Generic.List<{ty}>({length}); for (int {index} = 0; {index} < {length}; ++{index}) {{ nint {base} = {address} + ({index} * {size}); {body} @@ -1054,7 +1041,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { } if self.needs_cleanup { - self.src.insert_str(0, "var cleanups = new List(); + self.src.insert_str(0, "var cleanups = new global::System.Collections.Generic.List(); "); uwriteln!(self.src, " @@ -1086,11 +1073,11 @@ impl Bindgen for FunctionBindgen<'_, '_> { Instruction::GuestDeallocate { .. } => { // the original alloc here comes from cabi_realloc implementation (wasi-libc in .net) - uwriteln!(self.src, r#"NativeMemory.Free((void*){});"#, operands[0]); + uwriteln!(self.src, r#"global::System.Runtime.InteropServices.NativeMemory.Free((void*){});"#, operands[0]); } Instruction::GuestDeallocateString => { - uwriteln!(self.src, r#"NativeMemory.Free((void*){});"#, operands[0]); + uwriteln!(self.src, r#"global::System.Runtime.InteropServices.NativeMemory.Free((void*){});"#, operands[0]); } Instruction::GuestDeallocateVariant { blocks } => { @@ -1150,7 +1137,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { ); } - uwriteln!(self.src, r#"NativeMemory.Free((void*){});"#, operands[0]); + uwriteln!(self.src, r#"global::System.Runtime.InteropServices.NativeMemory.Free((void*){});"#, operands[0]); } Instruction::HandleLower { @@ -1385,12 +1372,12 @@ fn list_element_info(ty: &Type) -> (usize, &'static str) { fn perform_cast(op: &String, cast: &Bitcast) -> String { match cast { - Bitcast::I32ToF32 => format!("BitConverter.Int32BitsToSingle((int){op})"), - Bitcast::I64ToF32 => format!("BitConverter.Int32BitsToSingle((int){op})"), - Bitcast::F32ToI32 => format!("BitConverter.SingleToInt32Bits({op})"), - Bitcast::F32ToI64 => format!("BitConverter.SingleToInt32Bits({op})"), - Bitcast::I64ToF64 => format!("BitConverter.Int64BitsToDouble({op})"), - Bitcast::F64ToI64 => format!("BitConverter.DoubleToInt64Bits({op})"), + Bitcast::I32ToF32 => format!("global::System.BitConverter.Int32BitsToSingle((int){op})"), + Bitcast::I64ToF32 => format!("global::System.BitConverter.Int32BitsToSingle((int){op})"), + Bitcast::F32ToI32 => format!("global::System.BitConverter.SingleToInt32Bits({op})"), + Bitcast::F32ToI64 => format!("global::System.BitConverter.SingleToInt32Bits({op})"), + Bitcast::I64ToF64 => format!("global::System.BitConverter.Int64BitsToDouble({op})"), + Bitcast::F64ToI64 => format!("global::System.BitConverter.DoubleToInt64Bits({op})"), Bitcast::I32ToI64 => format!("(long) ({op})"), Bitcast::I64ToI32 => format!("(int) ({op})"), Bitcast::I64ToP64 => format!("{op}"), diff --git a/crates/csharp/src/interface.rs b/crates/csharp/src/interface.rs index 56efa78bc..fa4464134 100644 --- a/crates/csharp/src/interface.rs +++ b/crates/csharp/src/interface.rs @@ -3,7 +3,7 @@ use crate::function::FunctionBindgen; use crate::function::ResourceInfo; use crate::world_generator::CSharp; use heck::{ToShoutySnakeCase, ToUpperCamelCase}; -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use std::fmt::Write; use std::ops::Deref; use wit_bindgen_core::abi::LiftLower; @@ -20,8 +20,6 @@ pub(crate) struct InterfaceFragment { pub(crate) csharp_src: String, pub(crate) csharp_interop_src: String, pub(crate) stub: String, - pub(crate) usings: HashSet, - pub(crate) interop_usings: HashSet, } pub(crate) struct InterfaceTypeAndFragments { @@ -49,8 +47,6 @@ pub(crate) struct InterfaceGenerator<'a> { pub(crate) resolve: &'a Resolve, pub(crate) name: &'a str, pub(crate) direction: Direction, - pub(crate) usings: HashSet, - pub(crate) interop_usings: HashSet, } impl InterfaceGenerator<'_> { @@ -162,8 +158,6 @@ impl InterfaceGenerator<'_> { csharp_src: self.src, csharp_interop_src: self.csharp_interop_src, stub: self.stub, - usings: self.usings, - interop_usings: self.interop_usings, }); } @@ -172,8 +166,6 @@ impl InterfaceGenerator<'_> { csharp_src: self.src, csharp_interop_src: self.csharp_interop_src, stub: self.stub, - usings: self.usings, - interop_usings: self.interop_usings, }); } @@ -261,14 +253,9 @@ impl InterfaceGenerator<'_> { let import_name = &func.name; - self.csharp_gen - .require_using("System.Runtime.InteropServices"); - let target = if let FunctionKind::Freestanding = &func.kind { - self.require_interop_using("System.Runtime.InteropServices"); &mut self.csharp_interop_src } else { - self.require_using("System.Runtime.InteropServices"); &mut self.src }; @@ -277,7 +264,7 @@ impl InterfaceGenerator<'_> { r#" internal static class {interop_camel_name}WasmInterop {{ - [DllImport("{import_module_name}", EntryPoint = "{import_name}"), WasmImportLinkage] + [global::System.Runtime.InteropServices.DllImportAttribute("{import_module_name}", EntryPoint = "{import_name}"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] internal static extern {wasm_result_type} wasmImport{interop_camel_name}({wasm_params}); }} "# @@ -462,11 +449,10 @@ impl InterfaceGenerator<'_> { let export_name = func.legacy_core_export_name(core_module_name.as_deref()); let access = self.csharp_gen.access_modifier(); - self.require_interop_using("System.Runtime.InteropServices"); uwrite!( self.csharp_interop_src, r#" - [UnmanagedCallersOnly(EntryPoint = "{export_name}")] + [global::System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute(EntryPoint = "{export_name}")] {access} static unsafe {wasm_result_type} {interop_name}({wasm_params}) {{ {vars} {src} @@ -502,7 +488,7 @@ impl InterfaceGenerator<'_> { uwrite!( self.csharp_interop_src, r#" - [UnmanagedCallersOnly(EntryPoint = "cabi_post_{export_name}")] + [global::System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute(EntryPoint = "cabi_post_{export_name}")] {access} static unsafe void cabi_post_{interop_name}({params}) {{ {src} }} @@ -526,7 +512,7 @@ impl InterfaceGenerator<'_> { self.stub, r#" {sig} {{ - throw new NotImplementedException(); + throw new global::System.NotImplementedException(); }} "# ); @@ -607,16 +593,19 @@ impl InterfaceGenerator<'_> { && self.direction == Direction::Import && parameter_type == ParameterType::Span { - format!("Span<{}>", self.type_name(ty)) + format!("global::System.Span<{}>", self.type_name(ty)) } else if crate::world_generator::is_primitive(ty) && self.direction == Direction::Import && parameter_type == ParameterType::Memory { - format!("Memory<{}>", self.type_name(ty)) + format!("global::System.Memory<{}>", self.type_name(ty)) } else if crate::world_generator::is_primitive(ty) { format!("{}[]", self.type_name(ty)) } else { - format!("List<{}>", self.type_name_with_qualifier(ty, qualifier)) + format!( + "global::System.Collections.Generic.List<{}>", + self.type_name_with_qualifier(ty, qualifier) + ) } } TypeDefKind::Tuple(tuple) => { @@ -725,20 +714,6 @@ impl InterfaceGenerator<'_> { } } - pub(crate) fn require_using(&mut self, using_ns: &str) { - if !self.usings.contains(using_ns) { - let using_ns_string = using_ns.to_string(); - self.usings.insert(using_ns_string); - } - } - - pub(crate) fn require_interop_using(&mut self, using_ns: &str) { - if !self.interop_usings.contains(using_ns) { - let using_ns_string = using_ns.to_string(); - self.interop_usings.insert(using_ns_string); - } - } - pub(crate) fn start_resource(&mut self, id: TypeId, key: Option<&WorldKey>) { let access = self.csharp_gen.access_modifier(); let qualified = self.type_name_with_qualifier(&Type::Id(id), true); @@ -754,7 +729,6 @@ impl InterfaceGenerator<'_> { .map(|key| self.resolve.name_world_key(key)) .unwrap_or_else(|| "$root".into()); - self.require_using("System.Runtime.InteropServices"); // As of this writing, we cannot safely drop a handle to an imported resource from a .NET finalizer // because it may still have one or more open child resources. Once WIT has explicit syntax for // indicating parent/child relationships, we should be able to use that information to keep track @@ -763,7 +737,7 @@ impl InterfaceGenerator<'_> { uwriteln!( self.src, r#" - {access} class {upper_camel}: IDisposable {{ + {access} class {upper_camel}: global::System.IDisposable {{ internal int Handle {{ get; set; }} {access} readonly record struct THandle(int Handle); @@ -776,7 +750,7 @@ impl InterfaceGenerator<'_> { Dispose(true); }} - [DllImport("{module_name}", EntryPoint = "[resource-drop]{name}"), WasmImportLinkage] + [global::System.Runtime.InteropServices.DllImportAttribute("{module_name}", EntryPoint = "[resource-drop]{name}"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] private static extern void wasmImportResourceDrop(int p0); protected virtual void Dispose(bool disposing) {{ @@ -793,11 +767,10 @@ impl InterfaceGenerator<'_> { .map(|s| format!("{}#", self.resolve.name_world_key(s))) .unwrap_or_else(String::new); - self.require_interop_using("System.Runtime.InteropServices"); uwrite!( self.csharp_interop_src, r#" - [UnmanagedCallersOnly(EntryPoint = "{prefix}[dtor]{name}")] + [global::System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute(EntryPoint = "{prefix}[dtor]{name}")] {access} static unsafe void wasmExportResourceDtor{upper_camel}(int rep) {{ var val = ({qualified}) {qualified}.repTable.Remove(rep); val.Handle = 0; @@ -812,7 +785,6 @@ impl InterfaceGenerator<'_> { .map(|key| format!("[export]{}", self.resolve.name_world_key(key))) .unwrap_or_else(|| "[export]$root".into()); - self.require_using("System.Runtime.InteropServices"); // The ergonomics of exported resources are not ideal, currently. Implementing such a resource // requires both extending a class and implementing an interface. The reason for the class is to // allow implementers to inherit code which tracks and disposes of the resource handle; the reason @@ -831,7 +803,7 @@ impl InterfaceGenerator<'_> { uwriteln!( self.src, r#" - {access} abstract class {upper_camel}: IDisposable {{ + {access} abstract class {upper_camel}: global::System.IDisposable {{ internal static RepTable<{upper_camel}> repTable = new (); internal int Handle {{ get; set; }} @@ -841,13 +813,13 @@ impl InterfaceGenerator<'_> { }} internal static class WasmInterop {{ - [DllImport("{module_name}", EntryPoint = "[resource-drop]{name}"), WasmImportLinkage] + [global::System.Runtime.InteropServices.DllImportAttribute("{module_name}", EntryPoint = "[resource-drop]{name}"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] internal static extern void wasmImportResourceDrop(int p0); - [DllImport("{module_name}", EntryPoint = "[resource-new]{name}"), WasmImportLinkage] + [global::System.Runtime.InteropServices.DllImportAttribute("{module_name}", EntryPoint = "[resource-new]{name}"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] internal static extern int wasmImportResourceNew(int p0); - [DllImport("{module_name}", EntryPoint = "[resource-rep]{name}"), WasmImportLinkage] + [global::System.Runtime.InteropServices.DllImportAttribute("{module_name}", EntryPoint = "[resource-rep]{name}"), global::System.Runtime.InteropServices.WasmImportLinkageAttribute] internal static extern int wasmImportResourceRep(int p0); }} @@ -1127,7 +1099,7 @@ impl<'a> CoreInterfaceGenerator<'a> for InterfaceGenerator<'a> { if (Tag == Tags.{tag}) return ({ty})value!; else - throw new ArgumentException("expected {tag}, got " + Tag); + throw new global::System.ArgumentException("expected {tag}, got " + Tag); }} }} "# diff --git a/crates/csharp/src/world_generator.rs b/crates/csharp/src/world_generator.rs index d30a5b596..e8a31fc98 100644 --- a/crates/csharp/src/world_generator.rs +++ b/crates/csharp/src/world_generator.rs @@ -24,9 +24,6 @@ use wit_parser::{ pub struct CSharp { pub(crate) opts: Opts, pub(crate) name: String, - pub(crate) usings: HashSet, - #[allow(unused)] - pub(crate) interop_usings: HashSet, pub(crate) return_area_size: usize, pub(crate) return_area_align: usize, pub(crate) tuple_counts: HashSet, @@ -73,8 +70,6 @@ impl CSharp { resolve, name, direction, - usings: HashSet::::new(), - interop_usings: HashSet::::new(), } } @@ -91,21 +86,6 @@ impl CSharp { (String::new(), String::new()) } } - - pub(crate) fn require_using(&mut self, using_ns: &str) { - if !self.usings.contains(using_ns) { - let using_ns_string = using_ns.to_string(); - self.usings.insert(using_ns_string); - } - } - - #[allow(unused)] - fn require_interop_using(&mut self, using_ns: &str) { - if !self.interop_usings.contains(using_ns) { - let using_ns_string = using_ns.to_string(); - self.interop_usings.insert(using_ns_string); - } - } } impl WorldGenerator for CSharp { @@ -315,8 +295,6 @@ impl WorldGenerator for CSharp { let access = self.access_modifier(); - let using_pos = src.len(); - uwrite!( src, " @@ -335,16 +313,6 @@ impl WorldGenerator for CSharp { .join("\n"), ); - let usings: Vec<_> = self - .world_fragments - .iter() - .flat_map(|f| &f.usings) - .cloned() - .collect(); - usings.iter().for_each(|u| { - self.require_using(u); - }); - let mut producers = wasm_metadata::Producers::empty(); producers.add( "processed-by", @@ -355,14 +323,13 @@ impl WorldGenerator for CSharp { src.push_str("}\n"); if self.needs_result { - self.require_using("System.Runtime.InteropServices"); uwrite!( src, r#" {access} readonly struct None {{}} - [StructLayout(LayoutKind.Sequential)] + [global::System.Runtime.InteropServices.StructLayoutAttribute(global::System.Runtime.InteropServices.LayoutKind.Sequential)] {access} readonly struct Result {{ {access} readonly byte Tag; @@ -396,7 +363,7 @@ impl WorldGenerator for CSharp { return (TOk)value; }} - throw new ArgumentException("expected k, got " + Tag); + throw new global::System.ArgumentException("expected k, got " + Tag); }} }} @@ -409,7 +376,7 @@ impl WorldGenerator for CSharp { return (TErr)value; }} - throw new ArgumentException("expected Err, got " + Tag); + throw new global::System.ArgumentException("expected Err, got " + Tag); }} }} @@ -424,7 +391,6 @@ impl WorldGenerator for CSharp { } if self.needs_option { - self.require_using("System.Diagnostics.CodeAnalysis"); uwrite!( src, r#" @@ -445,7 +411,7 @@ impl WorldGenerator for CSharp { {access} static Option None => none; - [MemberNotNullWhen(true, nameof(Value))] + [global::System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute(true, nameof(Value))] {access} bool HasValue {{ get; }} {access} T? Value {{ get; }} @@ -458,7 +424,7 @@ impl WorldGenerator for CSharp { uwrite!( src, r#" - {access} class WitException: Exception {{ + {access} class WitException: global::System.Exception {{ {access} object Value {{ get; }} {access} uint NestingLevel {{ get; }} @@ -489,26 +455,25 @@ impl WorldGenerator for CSharp { let (array_size, element_type) = dotnet_aligned_array(self.return_area_size, self.return_area_align); - self.require_using("System.Runtime.CompilerServices"); uwrite!( ret_area_str, " {access} static class InteropReturnArea {{ - [InlineArray({0})] - [StructLayout(LayoutKind.Sequential, Pack = {1})] + [global::System.Runtime.CompilerServices.InlineArrayAttribute({0})] + [global::System.Runtime.InteropServices.StructLayoutAttribute(global::System.Runtime.InteropServices.LayoutKind.Sequential, Pack = {1})] internal struct ReturnArea {{ private {2} buffer; internal unsafe nint AddressOfReturnArea() {{ - return (nint)Unsafe.AsPointer(ref buffer); + return (nint)global::System.Runtime.CompilerServices.Unsafe.AsPointer(ref buffer); }} }} - [ThreadStatic] - [FixedAddressValueType] + [global::System.ThreadStaticAttribute] + [global::System.Runtime.CompilerServices.FixedAddressValueTypeAttribute] internal static ReturnArea returnArea = default; }} ", @@ -530,20 +495,6 @@ impl WorldGenerator for CSharp { src.push_str("namespace exports {\n"); - src.push_str( - &self - .world_fragments - .iter() - .flat_map(|f| &f.interop_usings) - .into_iter() - .collect::>() // de-dup across world_fragments - .iter() - .map(|s| "using ".to_owned() + s + ";") - .collect::>() - .join("\n"), - ); - src.push_str("\n"); - src.push_str(&format!("{access} static class {name}World\n")); src.push_str("{"); @@ -560,16 +511,6 @@ impl WorldGenerator for CSharp { src.push_str("}\n"); - src.insert_str( - using_pos, - &self - .usings - .iter() - .map(|s| "using ".to_owned() + s + ";") - .collect::>() - .join("\n"), - ); - files.push(&format!("{name}.cs"), indent(&src).as_bytes()); let generate_stub = |name: String, files: &mut Files, stubs: Stubs| { @@ -707,7 +648,7 @@ impl WorldGenerator for CSharp { // temporarily add this attribute until it is available in dotnet 9 namespace System.Runtime.InteropServices {{ - internal partial class WasmImportLinkageAttribute : Attribute {{}} + internal partial class WasmImportLinkageAttribute : global::System.Attribute {{}} }} #endif "#, @@ -734,7 +675,6 @@ impl WorldGenerator for CSharp { if body.len() > 0 { let body = format!( "{header} - {0} namespace {namespace}; @@ -742,12 +682,6 @@ impl WorldGenerator for CSharp { {body} }} ", - fragments - .iter() - .flat_map(|f| &f.usings) - .map(|s| "using ".to_owned() + s + ";") - .collect::>() - .join("\n"), ); files.push(&format!("{full_name}.cs"), indent(&body).as_bytes()); @@ -763,7 +697,6 @@ impl WorldGenerator for CSharp { let class_name = interface_name.strip_prefix("I").unwrap(); let body = format!( "{header} - {0} namespace {namespace} {{ @@ -772,12 +705,6 @@ impl WorldGenerator for CSharp { }} }} ", - fragments - .iter() - .flat_map(|f| &f.interop_usings) - .map(|s| "using ".to_owned() + s + ";\n") - .collect::>() - .join(""), ); files.push(