Added support for custom event delegates that have a return type.
This commit is contained in:
Родитель
22dafe66f1
Коммит
75425d5e67
|
@ -33,12 +33,21 @@ namespace Etg.SimpleStubs.CodeGen
|
|||
ParameterSyntax[] parameters = GetEventParameters(eventSymbol, isCustomDelegateEvent);
|
||||
string onEventArgs;
|
||||
string eventTriggerArgs;
|
||||
string methodReturnType = "void";
|
||||
string customDelegateReturnType = "";
|
||||
bool hasReturnType = false;
|
||||
|
||||
if (isCustomDelegateEvent)
|
||||
{
|
||||
IMethodSymbol delegateInvokeMethodSymbol = ((INamedTypeSymbol)(eventSymbol.OriginalDefinition).Type).DelegateInvokeMethod;
|
||||
onEventArgs = StubbingUtils.FormatParameters(delegateInvokeMethodSymbol);
|
||||
eventTriggerArgs = onEventArgs;
|
||||
if (!delegateInvokeMethodSymbol.ReturnsVoid)
|
||||
{
|
||||
hasReturnType = true;
|
||||
customDelegateReturnType = delegateInvokeMethodSymbol.ReturnType.GetFullyQualifiedName();
|
||||
methodReturnType = $"global::System.Collections.Generic.IEnumerable<{customDelegateReturnType}>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -59,25 +68,46 @@ namespace Etg.SimpleStubs.CodeGen
|
|||
string onEventMethodName = "On_" + eventName;
|
||||
|
||||
// Create OnEvent method
|
||||
MethodDeclarationSyntax onEventMethodDclr = SF.MethodDeclaration(SF.ParseTypeName("void"), onEventMethodName)
|
||||
BlockSyntax onEventMethodDclrBlock;
|
||||
if (hasReturnType)
|
||||
{
|
||||
onEventMethodDclrBlock = SF.Block(
|
||||
SF.ParseStatement($"{eventType} handler = {eventName};\n"),
|
||||
SF.ParseStatement("if (handler == null) {{ yield break; }}\n"),
|
||||
SF.ParseStatement($"foreach (var listener in handler.GetInvocationList()){{ if (listener.DynamicInvoke({onEventArgs}) is {customDelegateReturnType} ret){{ yield return ret; }} }}"));
|
||||
}
|
||||
else
|
||||
{
|
||||
onEventMethodDclrBlock = SF.Block(
|
||||
SF.ParseStatement($"{eventType} handler = {eventName};\n"),
|
||||
SF.ParseStatement($"if (handler != null) {{ handler({onEventArgs}); }}\n"));
|
||||
}
|
||||
|
||||
MethodDeclarationSyntax onEventMethodDclr = SF.MethodDeclaration(SF.ParseTypeName(methodReturnType), onEventMethodName)
|
||||
.AddModifiers(SF.Token(SyntaxKind.ProtectedKeyword))
|
||||
.AddParameterListParameters(parameters)
|
||||
.WithBody(SF.Block(
|
||||
SF.ParseStatement($"{eventType} handler = {eventName};\n"),
|
||||
SF.ParseStatement($"if (handler != null) {{ handler({onEventArgs}); }}\n")
|
||||
));
|
||||
.WithBody(onEventMethodDclrBlock);
|
||||
|
||||
classDclr = classDclr.AddMembers(onEventMethodDclr);
|
||||
|
||||
// Create event trigger method
|
||||
string eventTriggerMethodName = eventName + "_Raise";
|
||||
MethodDeclarationSyntax eventTriggerMethod = SF.MethodDeclaration(SF.ParseTypeName("void"),
|
||||
|
||||
BlockSyntax eventTriggerMethodBlock;
|
||||
if (hasReturnType)
|
||||
{
|
||||
eventTriggerMethodBlock = SF.Block(SF.ParseStatement($"return {onEventMethodName}({eventTriggerArgs});\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
eventTriggerMethodBlock = SF.Block(SF.ParseStatement($"{onEventMethodName}({eventTriggerArgs});\n"));
|
||||
}
|
||||
|
||||
MethodDeclarationSyntax eventTriggerMethod = SF.MethodDeclaration(SF.ParseTypeName(methodReturnType),
|
||||
eventTriggerMethodName)
|
||||
.AddModifiers(SF.Token(SyntaxKind.PublicKeyword))
|
||||
.AddParameterListParameters(parameters)
|
||||
.WithBody(SF.Block(
|
||||
SF.ParseStatement($"{onEventMethodName}({eventTriggerArgs});\n")
|
||||
));
|
||||
.WithBody(eventTriggerMethodBlock);
|
||||
classDclr = classDclr.AddMembers(eventTriggerMethod);
|
||||
|
||||
return classDclr;
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace TestClassLibrary
|
|||
|
||||
void SetGenericValue<T>(T value);
|
||||
}
|
||||
|
||||
|
||||
public interface IIgnoredInterface : IDisposable
|
||||
{
|
||||
}
|
||||
|
@ -126,10 +126,15 @@ namespace TestClassLibrary
|
|||
}
|
||||
|
||||
public delegate void CustomDelegateBasedHandler(int arg1, string arg2, object arg3);
|
||||
public delegate string CustomDelegateBasedHandlerWithReturnType(object sender, EventArgs eventArgs);
|
||||
public delegate string CustomDelegateBasedHandlerWithReturnType<T>(T eventArgs);
|
||||
|
||||
public interface ICustomDelegateBasedEventExample
|
||||
{
|
||||
event CustomDelegateBasedHandler CustomDelegateEventOccurred;
|
||||
|
||||
event CustomDelegateBasedHandlerWithReturnType CustomDelegateWithReturnTypeEventOccurred;
|
||||
event CustomDelegateBasedHandlerWithReturnType<string> CustomDelegateWithReturnTypeWithParameterEventOccurred;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using TestClassLibrary;
|
||||
|
||||
|
@ -44,5 +46,37 @@ namespace TestClassLibraryTest
|
|||
Assert.AreEqual("test", arg2);
|
||||
Assert.AreEqual(typeof(Random), arg3.GetType());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestCustomDelegateBasedWithReturnTypeEventStub()
|
||||
{
|
||||
var stub = new StubICustomDelegateBasedEventExample();
|
||||
stub.CustomDelegateWithReturnTypeEventOccurred += (sender, args) => "Teststring1";
|
||||
stub.CustomDelegateWithReturnTypeEventOccurred += (sender, args) => "Teststring2";
|
||||
stub.CustomDelegateWithReturnTypeEventOccurred += (sender, args) => "Teststring3";
|
||||
|
||||
var receivedList = stub.CustomDelegateWithReturnTypeEventOccurred_Raise(stub, EventArgs.Empty).ToList();
|
||||
|
||||
Assert.AreEqual(receivedList.Count, 3);
|
||||
Assert.AreEqual(receivedList[0], "Teststring1");
|
||||
Assert.AreEqual(receivedList[1], "Teststring2");
|
||||
Assert.AreEqual(receivedList[2], "Teststring3");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestCustomDelegateBasedWithReturnTypeWithParameterEventStub()
|
||||
{
|
||||
var stub = new StubICustomDelegateBasedEventExample();
|
||||
stub.CustomDelegateWithReturnTypeWithParameterEventOccurred += args => args + "Teststring1";
|
||||
stub.CustomDelegateWithReturnTypeWithParameterEventOccurred += args => args + "Teststring2";
|
||||
stub.CustomDelegateWithReturnTypeWithParameterEventOccurred += args => args + "Teststring3";
|
||||
|
||||
var receivedList = stub.CustomDelegateWithReturnTypeWithParameterEventOccurred_Raise("My").ToList();
|
||||
|
||||
Assert.AreEqual(receivedList.Count, 3);
|
||||
Assert.AreEqual(receivedList[0], "MyTeststring1");
|
||||
Assert.AreEqual(receivedList[1], "MyTeststring2");
|
||||
Assert.AreEqual(receivedList[2], "MyTeststring3");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче