[Xaml[C]] consider subclass of RDs as RDs (#2487)

- fixes #2483
This commit is contained in:
Stephane Delcroix 2018-04-20 05:50:47 +02:00 коммит произвёл Jason Smith
Родитель 8f0e91dd7f
Коммит d228656ec0
18 изменённых файлов: 141 добавлений и 13 удалений

Просмотреть файл

@ -30,6 +30,13 @@ namespace Xamarin.Forms.Build.Tasks
public bool VisitNodeOnDataTemplate => false;
public bool SkipChildren(INode node, INode parentNode) => false;
public bool IsResourceDictionary(ElementNode node)
{
var parentVar = Context.Variables[(IElementNode)node];
return parentVar.VariableType.FullName == "Xamarin.Forms.ResourceDictionary"
|| parentVar.VariableType.Resolve().BaseType?.FullName == "Xamarin.Forms.ResourceDictionary";
}
public void Visit(ValueNode node, INode parentNode)
{
Context.Values[node] = node.Value;
@ -526,4 +533,4 @@ namespace Xamarin.Forms.Build.Tasks
}
}
}
}
}

Просмотреть файл

@ -30,6 +30,13 @@ namespace Xamarin.Forms.Build.Tasks
public bool VisitNodeOnDataTemplate => true;
public bool SkipChildren(INode node, INode parentNode) => false;
public bool IsResourceDictionary(ElementNode node)
{
var parentVar = Context.Variables[(IElementNode)node];
return parentVar.VariableType.FullName == "Xamarin.Forms.ResourceDictionary"
|| parentVar.VariableType.Resolve().BaseType?.FullName == "Xamarin.Forms.ResourceDictionary";
}
public void Visit(ValueNode node, INode parentNode)
{
}

Просмотреть файл

@ -19,6 +19,13 @@ namespace Xamarin.Forms.Build.Tasks
public bool VisitNodeOnDataTemplate => false;
public bool SkipChildren(INode node, INode parentNode) => false;
public bool IsResourceDictionary(ElementNode node)
{
var parentVar = Context.Variables[(IElementNode)node];
return parentVar.VariableType.FullName == "Xamarin.Forms.ResourceDictionary"
|| parentVar.VariableType.Resolve().BaseType?.FullName == "Xamarin.Forms.ResourceDictionary";
}
public void Visit(ValueNode node, INode parentNode)
{
if (!IsXNameProperty(node, parentNode))

Просмотреть файл

@ -23,6 +23,13 @@ namespace Xamarin.Forms.Build.Tasks
public bool VisitNodeOnDataTemplate => false;
public bool SkipChildren(INode node, INode parentNode) => false;
public bool IsResourceDictionary(ElementNode node)
{
var parentVar = Context.Variables[(IElementNode)node];
return parentVar.VariableType.FullName == "Xamarin.Forms.ResourceDictionary"
|| parentVar.VariableType.Resolve().BaseType?.FullName == "Xamarin.Forms.ResourceDictionary";
}
public void Visit(ValueNode node, INode parentNode)
{
Context.Scopes[node] = Context.Scopes[parentNode];

Просмотреть файл

@ -44,6 +44,13 @@ namespace Xamarin.Forms.Build.Tasks
public bool VisitNodeOnDataTemplate => true;
public bool SkipChildren(INode node, INode parentNode) => false;
public bool IsResourceDictionary(ElementNode node)
{
var parentVar = Context.Variables[(IElementNode)node];
return parentVar.VariableType.FullName == "Xamarin.Forms.ResourceDictionary"
|| parentVar.VariableType.Resolve().BaseType?.FullName == "Xamarin.Forms.ResourceDictionary";
}
ModuleDefinition Module { get; }
public void Visit(ValueNode node, INode parentNode)

Просмотреть файл

@ -65,6 +65,8 @@ namespace Xamarin.Forms.Build.Tasks
{
}
public bool IsResourceDictionary(ElementNode node) => IsResourceDictionary((IElementNode)node);
bool IsResourceDictionary(IElementNode node)
{
var parentVar = Context.Variables[(IElementNode)node];

Просмотреть файл

@ -0,0 +1,11 @@
<?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="using:Xamarin.Forms.Xaml.UnitTests"
x:Class="Xamarin.Forms.Xaml.UnitTests.Gh2483">
<ContentPage.Resources>
<local:Gh2483Rd MergedWith="local:Gh2483Custom">
<Color x:Key="foo">Pink</Color>
</local:Gh2483Rd>
</ContentPage.Resources>
</ContentPage>

Просмотреть файл

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using Xamarin.Forms.Core.UnitTests;
using Xamarin.Forms;
namespace Xamarin.Forms.Xaml.UnitTests
{
public class Gh2483Rd : ResourceDictionary
{
}
public class Gh2483Custom : ResourceDictionary
{
public Gh2483Custom()
{
Add("foo", Color.Orange);
}
}
public partial class Gh2483 : ContentPage
{
public Gh2483()
{
InitializeComponent();
}
public Gh2483(bool useCompiledXaml)
{
//this stub will be replaced at compile time
}
[TestFixture]
class Tests
{
[SetUp]
public void Setup()
{
Device.PlatformServices = new MockPlatformServices();
}
[TearDown]
public void TearDown()
{
Device.PlatformServices = null;
}
[TestCase(true), TestCase(false)]
public void DupeKeyRd(bool useCompiledXaml)
{
var layout = new Gh2483(useCompiledXaml);
Assert.Pass();
}
}
}
}

Просмотреть файл

@ -597,6 +597,9 @@
<Compile Include="Issues\Gh2171.xaml.cs">
<DependentUpon>Gh2171.xaml</DependentUpon>
</Compile>
<Compile Include="Issues\Gh2483.xaml.cs">
<DependentUpon>Gh2483.xaml</DependentUpon>
</Compile>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
@ -1081,6 +1084,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Include="Issues\Gh2483.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />

Просмотреть файл

@ -36,6 +36,7 @@ namespace Xamarin.Forms.Xaml
public bool StopOnResourceDictionary { get; }
public bool VisitNodeOnDataTemplate => true;
public bool SkipChildren(INode node, INode parentNode) => false;
public bool IsResourceDictionary(ElementNode node) => typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]);
public void Visit(ValueNode node, INode parentNode)
{
@ -691,4 +692,4 @@ namespace Xamarin.Forms.Xaml
return true;
}
}
}
}

Просмотреть файл

@ -28,6 +28,7 @@ namespace Xamarin.Forms.Xaml
public bool StopOnResourceDictionary => false;
public bool VisitNodeOnDataTemplate => false;
public bool SkipChildren(INode node, INode parentNode) => false;
public bool IsResourceDictionary(ElementNode node) => typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]);
public void Visit(ValueNode node, INode parentNode)
{
@ -382,4 +383,4 @@ namespace Xamarin.Forms.Xaml
return value;
}
}
}
}

Просмотреть файл

@ -33,6 +33,7 @@ namespace Xamarin.Forms.Xaml
public bool StopOnResourceDictionary => false;
public bool VisitNodeOnDataTemplate => true;
public bool SkipChildren(INode node, INode parentNode) => false;
public bool IsResourceDictionary(ElementNode node) => false;
public void Visit(ValueNode node, INode parentNode)
{
@ -184,4 +185,4 @@ namespace Xamarin.Forms.Xaml
}
}
}
}
}

Просмотреть файл

@ -21,6 +21,8 @@ namespace Xamarin.Forms.Xaml
public bool StopOnResourceDictionary => false;
public bool VisitNodeOnDataTemplate => false;
public bool IsResourceDictionary(ElementNode node) => typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]);
public void Visit(ValueNode node, INode parentNode)
{
if (!typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)]))

Просмотреть файл

@ -19,6 +19,7 @@ namespace Xamarin.Forms.Xaml
public bool StopOnResourceDictionary => false;
public bool VisitNodeOnDataTemplate => true;
public bool SkipChildren(INode node, INode parentNode) => false;
public bool IsResourceDictionary(ElementNode node) => false;
public void Visit(ValueNode node, INode parentNode)
{
@ -72,4 +73,4 @@ namespace Xamarin.Forms.Xaml
return node != null && node.XmlType.Name == "VisualStateGroup" && node.Parent is IListNode;
}
}
}
}

Просмотреть файл

@ -10,6 +10,7 @@ namespace Xamarin.Forms.Xaml
public bool StopOnResourceDictionary => false;
public bool VisitNodeOnDataTemplate => true;
public bool SkipChildren(INode node, INode parentNode) => false;
public bool IsResourceDictionary(ElementNode node) => false;
public void Visit(ElementNode node, INode parentNode)
{
@ -75,4 +76,4 @@ namespace Xamarin.Forms.Xaml
{
}
}
}
}

Просмотреть файл

@ -1,5 +1,11 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Xml;
using Xamarin.Forms.Internals;
using Xamarin.Forms.Xaml.Internals;
namespace Xamarin.Forms.Xaml
{
@ -7,16 +13,18 @@ namespace Xamarin.Forms.Xaml
{
public RegisterXNamesVisitor(HydrationContext context)
{
Context = context;
Values = context.Values;
}
Dictionary<INode, object> Values { get; }
HydrationContext Context { get; }
public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown;
public bool StopOnDataTemplate => true;
public bool StopOnResourceDictionary => false;
public bool VisitNodeOnDataTemplate => false;
public bool SkipChildren(INode node, INode parentNode) => false;
public bool IsResourceDictionary(ElementNode node) => typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]);
public void Visit(ValueNode node, INode parentNode)
{
@ -62,4 +70,4 @@ namespace Xamarin.Forms.Xaml
return false;
}
}
}
}

Просмотреть файл

@ -161,11 +161,9 @@ namespace Xamarin.Forms.Xaml
return false;
}
bool IsResourceDictionary() => XmlType.Name == "ResourceDictionary";
protected bool SkipChildren(IXamlNodeVisitor visitor, INode node, INode parentNode) =>
(visitor.StopOnDataTemplate && IsDataTemplate(parentNode))
|| (visitor.StopOnResourceDictionary && IsResourceDictionary())
|| (visitor.StopOnResourceDictionary && visitor.IsResourceDictionary(this))
|| visitor.SkipChildren(node, parentNode);
protected bool SkipVisitNode(IXamlNodeVisitor visitor, INode parentNode) =>
@ -253,4 +251,4 @@ namespace Xamarin.Forms.Xaml
return false;
}
}
}
}

Просмотреть файл

@ -15,6 +15,7 @@ namespace Xamarin.Forms.Xaml
void Visit(RootNode node, INode parentNode);
void Visit(ListNode node, INode parentNode);
bool SkipChildren(INode node, INode parentNode);
bool IsResourceDictionary(ElementNode node);
}
enum TreeVisitingMode {
@ -45,5 +46,6 @@ namespace Xamarin.Forms.Xaml
public void Visit(RootNode node, INode parentNode) => action(node, parentNode);
public void Visit(ListNode node, INode parentNode) => action(node, parentNode);
public bool SkipChildren(INode node, INode parentNode) => false;
public bool IsResourceDictionary(ElementNode node) => false;
}
}
}