зеркало из 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)
|
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)
|
static IEnumerable<Instruction> ConnectEvent(VariableDefinition parent, string localName, INode valueNode, IXmlLineInfo iXmlLineInfo, ILContext context)
|
||||||
{
|
{
|
||||||
var elementType = parent.VariableType;
|
var elementType = parent.VariableType;
|
||||||
var module = context.Body.Method.Module;
|
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_0007: ldloc.0
|
||||||
// IL_0008: ldarg.0
|
// IL_0008: ldarg.0
|
||||||
|
@ -810,7 +812,9 @@ namespace Xamarin.Forms.Build.Tasks
|
||||||
var ctor = module.ImportReference(eventinfo.EventType.Resolve().GetConstructors().First());
|
var ctor = module.ImportReference(eventinfo.EventType.Resolve().GetConstructors().First());
|
||||||
ctor = ctor.ResolveGenericParameters(eventinfo.EventType, module);
|
ctor = ctor.ResolveGenericParameters(eventinfo.EventType, module);
|
||||||
yield return Instruction.Create(OpCodes.Newobj, module.ImportReference(ctor));
|
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)
|
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);
|
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 typeDef = typeRef.Resolve();
|
||||||
var events = typeDef.Events.Where(predicate);
|
var events = typeDef.Events.Where(predicate);
|
||||||
if (events.Any())
|
if (events.Any()) {
|
||||||
return events.Single();
|
var ev = events.Single();
|
||||||
|
return ev.ResolveGenericEvent(declaringTypeRef);
|
||||||
|
}
|
||||||
if (typeDef.BaseType == null || typeDef.BaseType.FullName == "System.Object")
|
if (typeDef.BaseType == null || typeDef.BaseType.FullName == "System.Object")
|
||||||
return null;
|
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,
|
public static FieldDefinition GetField(this TypeReference typeRef, Func<FieldDefinition, bool> predicate,
|
||||||
out TypeReference declaringTypeRef)
|
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>
|
<DependentUpon>Bz53350.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="XamlC\MethodDefinitionExtensionsTests.cs" />
|
<Compile Include="XamlC\MethodDefinitionExtensionsTests.cs" />
|
||||||
|
<Compile Include="Issues\Bz57574.xaml.cs">
|
||||||
|
<DependentUpon>Bz57574.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<Import Project="..\.nuspec\Xamarin.Forms.Debug.targets" />
|
<Import Project="..\.nuspec\Xamarin.Forms.Debug.targets" />
|
||||||
|
@ -905,6 +908,9 @@
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Issues\Bz53350.xaml">
|
<EmbeddedResource Include="Issues\Bz53350.xaml">
|
||||||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Issues\Bz57574.xaml">
|
||||||
|
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче