зеркало из https://github.com/DeGsoft/maui-linux.git
[XamlC] resolve generic EventArgs (#1020)
This commit is contained in:
Родитель
171fa0faec
Коммит
56fc6218ff
|
@ -764,14 +764,16 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
|
||||
static bool CanConnectEvent(VariableDefinition parent, string localName)
|
||||
{
|
||||
return parent.VariableType.GetEvent(ed => ed.Name == localName) != null;
|
||||
TypeReference _;
|
||||
return parent.VariableType.GetEvent(ed => ed.Name == localName, out _) != null;
|
||||
}
|
||||
|
||||
static IEnumerable<Instruction> ConnectEvent(VariableDefinition parent, string localName, INode valueNode, IXmlLineInfo iXmlLineInfo, ILContext context)
|
||||
{
|
||||
var elementType = parent.VariableType;
|
||||
var module = context.Body.Method.Module;
|
||||
var eventinfo = elementType.GetEvent(ed => ed.Name == localName);
|
||||
TypeReference eventDeclaringTypeRef;
|
||||
var eventinfo = elementType.GetEvent(ed => ed.Name == localName, out eventDeclaringTypeRef);
|
||||
|
||||
// IL_0007: ldloc.0
|
||||
// IL_0008: ldarg.0
|
||||
|
@ -810,7 +812,9 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
var ctor = module.ImportReference(eventinfo.EventType.Resolve().GetConstructors().First());
|
||||
ctor = ctor.ResolveGenericParameters(eventinfo.EventType, module);
|
||||
yield return Instruction.Create(OpCodes.Newobj, module.ImportReference(ctor));
|
||||
yield return Instruction.Create(OpCodes.Callvirt, module.ImportReference(eventinfo.AddMethod));
|
||||
var adder = module.ImportReference(eventinfo.AddMethod);
|
||||
adder = adder.ResolveGenericParameters(eventDeclaringTypeRef, module);
|
||||
yield return Instruction.Create(OpCodes.Callvirt, module.ImportReference(adder));
|
||||
}
|
||||
|
||||
static bool CanSetDynamicResource(FieldReference bpRef, INode valueNode, ILContext context)
|
||||
|
|
|
@ -56,17 +56,42 @@ namespace Xamarin.Forms.Build.Tasks
|
|||
return typeDef.BaseType.GetProperty(predicate, out declaringTypeRef);
|
||||
}
|
||||
|
||||
public static EventDefinition GetEvent(this TypeReference typeRef, Func<EventDefinition, bool> predicate)
|
||||
public static EventDefinition GetEvent(this TypeReference typeRef, Func<EventDefinition, bool> predicate,
|
||||
out TypeReference declaringTypeRef)
|
||||
{
|
||||
declaringTypeRef = typeRef;
|
||||
var typeDef = typeRef.Resolve();
|
||||
var events = typeDef.Events.Where(predicate);
|
||||
if (events.Any())
|
||||
return events.Single();
|
||||
if (events.Any()) {
|
||||
var ev = events.Single();
|
||||
return ev.ResolveGenericEvent(declaringTypeRef);
|
||||
}
|
||||
if (typeDef.BaseType == null || typeDef.BaseType.FullName == "System.Object")
|
||||
return null;
|
||||
return typeDef.BaseType.GetEvent(predicate);
|
||||
return typeDef.BaseType.GetEvent(predicate, out declaringTypeRef);
|
||||
}
|
||||
|
||||
//this resolves generic eventargs (https://bugzilla.xamarin.com/show_bug.cgi?id=57574)
|
||||
static EventDefinition ResolveGenericEvent(this EventDefinition eventDef, TypeReference declaringTypeRef)
|
||||
{
|
||||
if (eventDef == null)
|
||||
throw new ArgumentNullException(nameof(eventDef));
|
||||
if (declaringTypeRef == null)
|
||||
throw new ArgumentNullException(nameof(declaringTypeRef));
|
||||
if (!eventDef.EventType.IsGenericInstance)
|
||||
return eventDef;
|
||||
if (eventDef.EventType.Resolve().FullName != "System.EventHandler`1")
|
||||
return eventDef;
|
||||
|
||||
var git = eventDef.EventType as GenericInstanceType;
|
||||
var ga = git.GenericArguments.First();
|
||||
ga = ga.ResolveGenericParameters(declaringTypeRef);
|
||||
git.GenericArguments[0] = ga;
|
||||
eventDef.EventType = git;
|
||||
|
||||
return eventDef;
|
||||
|
||||
}
|
||||
public static FieldDefinition GetField(this TypeReference typeRef, Func<FieldDefinition, bool> predicate,
|
||||
out TypeReference declaringTypeRef)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:local="clr-namespace:Xamarin.Forms.Xaml.UnitTests"
|
||||
x:Class="Xamarin.Forms.Xaml.UnitTests.Bz57574">
|
||||
<local:Bz57574Notificator x:Name="notificator"
|
||||
x:TypeArguments="x:String"
|
||||
Notified="OnNotified"/>
|
||||
</ContentPage>
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Forms.Core.UnitTests;
|
||||
|
||||
namespace Xamarin.Forms.Xaml.UnitTests
|
||||
{
|
||||
public class Bz57574NotificationEventArgs<T> : EventArgs
|
||||
{
|
||||
public T Message { get; set; }
|
||||
}
|
||||
|
||||
public class Bz57574Notificator<T> : View
|
||||
{
|
||||
public void Notify(T message)
|
||||
{
|
||||
Notified?.Invoke(this, new Bz57574NotificationEventArgs<T> { Message = message });
|
||||
}
|
||||
|
||||
public event EventHandler<Bz57574NotificationEventArgs<T>> Notified;
|
||||
}
|
||||
|
||||
public partial class Bz57574
|
||||
{
|
||||
public Bz57574()
|
||||
{
|
||||
notificator.Notified += OnNotified;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public Bz57574(bool useCompiledXaml)
|
||||
{
|
||||
//this stub will be replaced at compile time
|
||||
}
|
||||
|
||||
|
||||
string notification;
|
||||
public void OnNotified(object sender, Bz57574NotificationEventArgs<string> args)
|
||||
{
|
||||
notification = args.Message;
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
class Tests
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Device.PlatformServices = new MockPlatformServices();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Device.PlatformServices = null;
|
||||
Application.Current = null;
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public void EventWithGenericEventHandlers(bool useCompiledXaml)
|
||||
{
|
||||
var layout = new Bz57574(useCompiledXaml);
|
||||
Assume.That(layout.notification, Is.Null);
|
||||
layout.notificator.Notify("Foo");
|
||||
Assert.That(layout.notification, Is.EqualTo("Foo"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -495,6 +495,9 @@
|
|||
<DependentUpon>Bz53350.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="XamlC\MethodDefinitionExtensionsTests.cs" />
|
||||
<Compile Include="Issues\Bz57574.xaml.cs">
|
||||
<DependentUpon>Bz57574.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\.nuspec\Xamarin.Forms.Debug.targets" />
|
||||
|
@ -905,6 +908,9 @@
|
|||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Issues\Bz53350.xaml">
|
||||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Issues\Bz57574.xaml">
|
||||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
Загрузка…
Ссылка в новой задаче