Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace TUnit.Mocks.Generated

public global::IConfigProvider GetConfigProvider()
{
return _engine.HandleCallWithReturn<global::IConfigProvider>(1, "GetConfigProvider", global::System.Array.Empty<object?>(), default!);
return (global::IConfigProvider)_engine.HandleCallWithReturn<object?>(1, "GetConfigProvider", global::System.Array.Empty<object?>(), null)!;
}

[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
Expand Down Expand Up @@ -80,10 +80,10 @@ namespace TUnit.Mocks.Generated
return new IMyService_GetValue_M0_MockCall(global::TUnit.Mocks.Mock.GetEngine(mock), 0, "GetValue", matchers);
}

public static global::TUnit.Mocks.MockMethodCall<global::IConfigProvider> GetConfigProvider(this global::TUnit.Mocks.Mock<global::IMyService> mock)
public static global::TUnit.Mocks.MockMethodCall<object?> GetConfigProvider(this global::TUnit.Mocks.Mock<global::IMyService> mock)
{
var matchers = global::System.Array.Empty<global::TUnit.Mocks.Arguments.IArgumentMatcher>();
return new global::TUnit.Mocks.MockMethodCall<global::IConfigProvider>(global::TUnit.Mocks.Mock.GetEngine(mock), 1, "GetConfigProvider", matchers);
return new global::TUnit.Mocks.MockMethodCall<object?>(global::TUnit.Mocks.Mock.GetEngine(mock), 1, "GetConfigProvider", matchers);
}
}

Expand Down
80 changes: 79 additions & 1 deletion TUnit.Mocks.SourceGenerator/Builders/MockBridgeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,14 @@ private static void GenerateStaticPropertyDim(CodeWriter writer, MockMemberModel
writer.OpenBrace();
writer.AppendLine($"var __engine = {safeName}_StaticEngine.Engine;");
writer.AppendLine("if (__engine is null) return default!;");
writer.AppendLine($"return __engine.HandleCallWithReturn<{prop.ReturnType}>({prop.MemberId}, \"get_{prop.Name}\", global::System.Array.Empty<object?>(), {prop.SmartDefault});");
if (prop.IsReturnTypeStaticAbstractInterface)
{
writer.AppendLine($"return ({prop.ReturnType})__engine.HandleCallWithReturn<object?>({prop.MemberId}, \"get_{prop.Name}\", global::System.Array.Empty<object?>(), null)!;");
}
else
{
writer.AppendLine($"return __engine.HandleCallWithReturn<{prop.ReturnType}>({prop.MemberId}, \"get_{prop.Name}\", global::System.Array.Empty<object?>(), {prop.SmartDefault});");
}
writer.CloseBrace();
}

Expand Down Expand Up @@ -158,51 +165,122 @@ private static void GenerateStaticEngineDispatchBody(CodeWriter writer, MockMemb
else if (method.IsVoid && method.IsAsync)
{
if (method.IsValueTask)
{
writer.AppendLine("if (__engine is null) return default(global::System.Threading.Tasks.ValueTask);");
}
else
{
writer.AppendLine("if (__engine is null) return global::System.Threading.Tasks.Task.CompletedTask;");
}

using (writer.Block("try"))
{
writer.AppendLine($"__engine.HandleCall({method.MemberId}, \"{method.Name}\", {argsArray});");
MockImplBuilder.EmitOutRefReadback(writer, method);
if (method.IsValueTask)
{
writer.AppendLine("return default(global::System.Threading.Tasks.ValueTask);");
}
else
{
writer.AppendLine("return global::System.Threading.Tasks.Task.CompletedTask;");
}
}
using (writer.Block("catch (global::System.Exception __ex)"))
{
if (method.IsValueTask)
{
writer.AppendLine("return new global::System.Threading.Tasks.ValueTask(global::System.Threading.Tasks.Task.FromException(__ex));");
}
else
{
writer.AppendLine("return global::System.Threading.Tasks.Task.FromException(__ex);");
}
}
}
else if (method.IsAsync && method.IsReturnTypeStaticAbstractInterface)
{
// Async method whose unwrapped return type has static abstract members (CS8920).
// Use object? and cast instead.
if (method.IsValueTask)
{
writer.AppendLine($"if (__engine is null) return new global::System.Threading.Tasks.ValueTask<{method.UnwrappedReturnType}>(default!);");
}
else
{
writer.AppendLine($"if (__engine is null) return global::System.Threading.Tasks.Task.FromResult<{method.UnwrappedReturnType}>(default!);");
}

using (writer.Block("try"))
{
writer.AppendLine($"var __result = ({method.UnwrappedReturnType})__engine.HandleCallWithReturn<object?>({method.MemberId}, \"{method.Name}\", {argsArray}, null)!;");
MockImplBuilder.EmitOutRefReadback(writer, method);
if (method.IsValueTask)
{
writer.AppendLine($"return new global::System.Threading.Tasks.ValueTask<{method.UnwrappedReturnType}>(__result);");
}
else
{
writer.AppendLine($"return global::System.Threading.Tasks.Task.FromResult<{method.UnwrappedReturnType}>(__result);");
}
}
using (writer.Block("catch (global::System.Exception __ex)"))
{
if (method.IsValueTask)
{
writer.AppendLine($"return new global::System.Threading.Tasks.ValueTask<{method.UnwrappedReturnType}>(global::System.Threading.Tasks.Task.FromException<{method.UnwrappedReturnType}>(__ex));");
}
else
{
writer.AppendLine($"return global::System.Threading.Tasks.Task.FromException<{method.UnwrappedReturnType}>(__ex);");
}
}
}
else if (method.IsAsync)
{
if (method.IsValueTask)
{
writer.AppendLine($"if (__engine is null) return new global::System.Threading.Tasks.ValueTask<{method.UnwrappedReturnType}>({method.UnwrappedSmartDefault});");
}
else
{
writer.AppendLine($"if (__engine is null) return global::System.Threading.Tasks.Task.FromResult<{method.UnwrappedReturnType}>({method.UnwrappedSmartDefault});");
}

using (writer.Block("try"))
{
writer.AppendLine($"var __result = __engine.HandleCallWithReturn<{method.UnwrappedReturnType}>({method.MemberId}, \"{method.Name}\", {argsArray}, {method.UnwrappedSmartDefault});");
MockImplBuilder.EmitOutRefReadback(writer, method);
if (method.IsValueTask)
{
writer.AppendLine($"return new global::System.Threading.Tasks.ValueTask<{method.UnwrappedReturnType}>(__result);");
}
else
{
writer.AppendLine($"return global::System.Threading.Tasks.Task.FromResult<{method.UnwrappedReturnType}>(__result);");
}
}
using (writer.Block("catch (global::System.Exception __ex)"))
{
if (method.IsValueTask)
{
writer.AppendLine($"return new global::System.Threading.Tasks.ValueTask<{method.UnwrappedReturnType}>(global::System.Threading.Tasks.Task.FromException<{method.UnwrappedReturnType}>(__ex));");
}
else
{
writer.AppendLine($"return global::System.Threading.Tasks.Task.FromException<{method.UnwrappedReturnType}>(__ex);");
}
}
}
else if (method.IsReturnTypeStaticAbstractInterface)
{
// Return type has static abstract members — can't use as generic type argument (CS8920).
// Use object? and cast instead.
writer.AppendLine("if (__engine is null) return default!;");
writer.AppendLine($"var __result = __engine.HandleCallWithReturn<object?>({method.MemberId}, \"{method.Name}\", {argsArray}, null);");
MockImplBuilder.EmitOutRefReadback(writer, method);
writer.AppendLine($"return ({method.ReturnType})__result!;");
}
else
{
writer.AppendLine("if (__engine is null) return default!;");
Expand Down
Loading
Loading