Add support for custom delegate-based events
This commit is contained in:
Родитель
9db4667a9c
Коммит
1e0e828a6a
|
@ -28,17 +28,31 @@ namespace Etg.SimpleStubs.CodeGen
|
|||
classDclr = classDclr.AddMembers(eventDclr);
|
||||
|
||||
string eventName = eventSymbol.Name;
|
||||
ParameterSyntax[] parameters = GetEventParameters(eventSymbol);
|
||||
string onEventArgs = "sender";
|
||||
string eventTriggerArgs = "sender";
|
||||
if (parameters.Count() == 2)
|
||||
|
||||
bool isCustomDelegateEvent = IsCustomDelegateBasedEvent(eventSymbol, semanticModel);
|
||||
ParameterSyntax[] parameters = GetEventParameters(eventSymbol, isCustomDelegateEvent);
|
||||
string onEventArgs;
|
||||
string eventTriggerArgs;
|
||||
|
||||
if (isCustomDelegateEvent)
|
||||
{
|
||||
onEventArgs += ", args";
|
||||
eventTriggerArgs += ", args";
|
||||
IMethodSymbol delegateInvokeMethodSymbol = ((INamedTypeSymbol)(eventSymbol.OriginalDefinition).Type).DelegateInvokeMethod;
|
||||
onEventArgs = StubbingUtils.FormatParameters(delegateInvokeMethodSymbol);
|
||||
eventTriggerArgs = onEventArgs;
|
||||
}
|
||||
else if (parameters.Count() == 1)
|
||||
else
|
||||
{
|
||||
onEventArgs += ", null";
|
||||
onEventArgs = "sender";
|
||||
eventTriggerArgs = "sender";
|
||||
if (parameters.Count() == 2)
|
||||
{
|
||||
onEventArgs += ", args";
|
||||
eventTriggerArgs += ", args";
|
||||
}
|
||||
else if (parameters.Count() == 1)
|
||||
{
|
||||
onEventArgs += ", null";
|
||||
}
|
||||
}
|
||||
|
||||
string eventType = GetEventType(eventSymbol);
|
||||
|
@ -69,17 +83,25 @@ namespace Etg.SimpleStubs.CodeGen
|
|||
return classDclr;
|
||||
}
|
||||
|
||||
private static ParameterSyntax[] GetEventParameters(IEventSymbol eventSymbol)
|
||||
private static ParameterSyntax[] GetEventParameters(IEventSymbol eventSymbol, bool isCustomDelegateEvent)
|
||||
{
|
||||
List<ParameterSyntax> parameters = new List<ParameterSyntax>
|
||||
{
|
||||
SF.Parameter(SF.Identifier("sender")).WithType(SF.ParseTypeName("object"))
|
||||
};
|
||||
|
||||
var parameters = new List<ParameterSyntax>();
|
||||
INamedTypeSymbol type = (INamedTypeSymbol) (eventSymbol.Type);
|
||||
if (type.TypeArguments.Any())
|
||||
|
||||
if (isCustomDelegateEvent)
|
||||
{
|
||||
parameters.Add(SF.Parameter(SF.Identifier("args"))
|
||||
.WithType(SF.ParseTypeName(type.TypeArguments[0].Name)));
|
||||
IMethodSymbol delegateInvokeMethodSymbol = ((INamedTypeSymbol)(eventSymbol.OriginalDefinition).Type).DelegateInvokeMethod;
|
||||
parameters.AddRange(RoslynUtils.GetMethodParameterSyntaxList(delegateInvokeMethodSymbol).ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
parameters.Add(SF.Parameter(SF.Identifier("sender")).WithType(SF.ParseTypeName("object")));
|
||||
if (type.TypeArguments.Any())
|
||||
{
|
||||
parameters.Add(SF.Parameter(SF.Identifier("args"))
|
||||
.WithType(SF.ParseTypeName(type.TypeArguments[0].Name)));
|
||||
}
|
||||
}
|
||||
|
||||
return parameters.ToArray();
|
||||
|
@ -100,5 +122,18 @@ namespace Etg.SimpleStubs.CodeGen
|
|||
{
|
||||
return eventSymbol.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
}
|
||||
|
||||
private static bool IsCustomDelegateBasedEvent(IEventSymbol eventSymbol, SemanticModel semanticModel)
|
||||
{
|
||||
var genericEventType = semanticModel.Compilation.GetTypeByMetadataName("System.EventHandler`1");
|
||||
var eventType = semanticModel.Compilation.GetTypeByMetadataName("System.EventHandler");
|
||||
|
||||
if (eventSymbol.Type.MetadataName.Equals(genericEventType.MetadataName) || eventSymbol.Type.MetadataName.Equals(eventType.MetadataName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
using Microsoft.CodeAnalysis.Formatting;
|
||||
using Microsoft.CodeAnalysis.MSBuild;
|
||||
|
||||
namespace Etg.SimpleStubs.CodeGen.Utils
|
||||
{
|
||||
|
|
|
@ -113,4 +113,11 @@ namespace TestClassLibrary
|
|||
|
||||
void SetBoo<T, A>(T t, A a) where T : class, IDisposable, new() where A : new();
|
||||
}
|
||||
|
||||
public delegate void CustomDelegateBasedHandler(int arg1, string arg2, object arg3);
|
||||
|
||||
public interface ICustomDelegateBasedEventExample
|
||||
{
|
||||
event CustomDelegateBasedHandler CustomDelegateEventOccurred;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using TestClassLibrary;
|
||||
|
||||
namespace TestClassLibraryTest
|
||||
|
@ -16,11 +17,32 @@ namespace TestClassLibraryTest
|
|||
{
|
||||
sender = s;
|
||||
newNumber = num;
|
||||
}
|
||||
;
|
||||
};
|
||||
|
||||
stub.PhoneNumberChanged_Raise(this, 55);
|
||||
Assert.AreEqual(55, newNumber);
|
||||
Assert.AreEqual(this, sender);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestCustomDelegateBasedEventStub()
|
||||
{
|
||||
int arg1 = 0;
|
||||
string arg2 = null;
|
||||
object arg3 = null;
|
||||
var stub = new StubICustomDelegateBasedEventExample();
|
||||
stub.CustomDelegateEventOccurred += (i, s, o) =>
|
||||
{
|
||||
arg1 = i;
|
||||
arg2 = s;
|
||||
arg3 = o;
|
||||
};
|
||||
|
||||
stub.CustomDelegateEventOccurred_Raise(55, "test", new Random(1));
|
||||
|
||||
Assert.AreEqual(55, arg1);
|
||||
Assert.AreEqual("test", arg2);
|
||||
Assert.AreEqual(typeof(Random), arg3.GetType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче