diff --git a/crates/csharp/src/lib.rs b/crates/csharp/src/lib.rs index bae63c208..6d815f366 100644 --- a/crates/csharp/src/lib.rs +++ b/crates/csharp/src/lib.rs @@ -588,6 +588,14 @@ impl WorldGenerator for CSharp { NestingLevel = level; }} }} + + {access} class WitException: WitException {{ + {access} T TypedValue {{ get {{ return (T)this.Value;}} }} + + {access} WitException(T v, uint level) : base(v!, level) + {{ + }} + }} "#, ) } @@ -2889,6 +2897,7 @@ impl Bindgen for FunctionBindgen<'_, '_> { if !self.results.is_empty() { self.gen.gen.needs_wit_exception = true; let cases = cases.join("\n"); + // r#"}} catch (WitException<{err_ty}> e) {{ uwriteln!( self.src, r#"}} catch (WitException e) {{ @@ -2952,10 +2961,9 @@ impl Bindgen for FunctionBindgen<'_, '_> { 1 => { let mut payload_is_void = false; let mut previous = operands[0].clone(); - let mut vars = Vec::with_capacity(self.results.len()); + let mut vars: Vec::<(String, Option)> = Vec::<(String, Option)>::with_capacity(self.results.len()); if let Direction::Import = self.gen.direction { for ty in &self.results { - vars.push(previous.clone()); let tmp = self.locals.tmp("tmp"); uwrite!( self.src, @@ -2964,21 +2972,29 @@ impl Bindgen for FunctionBindgen<'_, '_> { var {tmp} = {previous}.AsOk; " ); - previous = tmp; let TypeDefKind::Result(result) = &self.gen.resolve.types[*ty].kind else { unreachable!(); }; + let exception_name = result.err + .map(|ty| self.gen.type_name_with_qualifier(&ty, true)); + vars.push((previous.clone(), exception_name)); payload_is_void = result.ok.is_none(); + previous = tmp; } } uwriteln!(self.src, "return {};", if payload_is_void { "" } else { &previous }); for (level, var) in vars.iter().enumerate().rev() { self.gen.gen.needs_wit_exception = true; + let (var_name, exception_name) = var; + let exception_name = match exception_name { + Some(type_name) => &format!("WitException<{}>",type_name), + None => "WitException", + }; uwrite!( self.src, "\ }} else {{ - throw new WitException({var}.AsErr!, {level}); + throw new {exception_name}({var_name}.AsErr!, {level}); }} " ); diff --git a/tests/runtime/results/wasm.cs b/tests/runtime/results/wasm.cs index 81ca3296b..63af4b29b 100644 --- a/tests/runtime/results/wasm.cs +++ b/tests/runtime/results/wasm.cs @@ -1,77 +1,54 @@ -using ResultsWorld.wit.imports.test.results; - namespace ResultsWorld.wit.exports.test.results { public class TestImpl : ITest { public static float StringError(float a) { - return ResultsWorld.wit.imports.test.results.TestInterop.StringError(a); + return imports.test.results.TestInterop.StringError(a); } public static float EnumError(float a) { try { - return ResultsWorld.wit.imports.test.results.TestInterop.EnumError(a); - } catch (WitException e) { - switch ((ResultsWorld.wit.imports.test.results.ITest.E) e.Value) { - case ResultsWorld.wit.imports.test.results.ITest.E.A: - throw new WitException(ITest.E.A, 0); - case ResultsWorld.wit.imports.test.results.ITest.E.B: - throw new WitException(ITest.E.B, 0); - case ResultsWorld.wit.imports.test.results.ITest.E.C: - throw new WitException(ITest.E.C, 0); - default: - throw new Exception("unreachable"); - } + return imports.test.results.TestInterop.EnumError(a); + } catch (WitException e) { + throw new WitException(e.TypedValue, 0); } } public static float RecordError(float a) { try { - return ResultsWorld.wit.imports.test.results.TestInterop.RecordError(a); - } catch (WitException e) { - var value = (ResultsWorld.wit.imports.test.results.ITest.E2) e.Value; - throw new WitException(new ITest.E2(value.line, value.column), 0); + return imports.test.results.TestInterop.RecordError(a); + } catch (WitException e) { + throw new WitException(new ITest.E2(e.TypedValue.line, e.TypedValue.column), 0); } } public static float VariantError(float a) { try { - return ResultsWorld.wit.imports.test.results.TestInterop.VariantError(a); - } catch (WitException e) { - var value = (ResultsWorld.wit.imports.test.results.ITest.E3) e.Value; - switch (value.Tag) { - case ResultsWorld.wit.imports.test.results.ITest.E3.Tags.E1: - switch (value.AsE1) { - case ResultsWorld.wit.imports.test.results.ITest.E.A: - throw new WitException(ITest.E3.E1(ITest.E.A), 0); - case ResultsWorld.wit.imports.test.results.ITest.E.B: - throw new WitException(ITest.E3.E1(ITest.E.B), 0); - case ResultsWorld.wit.imports.test.results.ITest.E.C: - throw new WitException(ITest.E3.E1(ITest.E.C), 0); - default: - throw new Exception("unreachable"); - } - case ResultsWorld.wit.imports.test.results.ITest.E3.Tags.E2: { - throw new WitException(ITest.E3.E2(new ITest.E2(value.AsE2.line, value.AsE2.column)), 0); - } - default: - throw new Exception("unreachable"); - } + 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); + } + catch { + throw new Exception("unreachable"); } } public static uint EmptyError(uint a) { - return ResultsWorld.wit.imports.test.results.TestInterop.EmptyError(a); + return imports.test.results.TestInterop.EmptyError(a); } public static void DoubleError(uint a) { - ResultsWorld.wit.imports.test.results.TestInterop.DoubleError(a); + imports.test.results.TestInterop.DoubleError(a); } } }