XamlLoader should not ignore x:TypeArguments on root node (#5804)

This commit is contained in:
Tim Barham 2019-04-05 15:31:28 +10:00 коммит произвёл GitHub
Родитель c733bb4bb9
Коммит 53979c8297
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 30 добавлений и 6 удалений

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

@ -607,7 +607,6 @@ namespace Xamarin.Forms.Xaml.UnitTests
string clrNamespace = null;
string typeName = null;
XamlLoader.FallbackTypeResolver = (fallbackTypeInfos, type) =>
{
assemblyName = fallbackTypeInfos?[1].AssemblyName;
@ -682,6 +681,24 @@ namespace Xamarin.Forms.Xaml.UnitTests
Assert.DoesNotThrow(() => XamlLoader.Create(xaml, true));
Assert.That(exceptions.Count, Is.GreaterThanOrEqualTo(1));
}
[Test]
public void MissingGenericRootTypeProvidesCorrectTypeName()
{
var xaml = @"
<local:GenericContentPage xmlns=""http://xamarin.com/schemas/2014/forms""
xmlns:x=""http://schemas.microsoft.com/winfx/2009/xaml""
xmlns:local=""clr-namespace:MissingNamespace""
x:TypeArguments=""x:Object"" />";
XamlLoader.FallbackTypeResolver = (p, type) =>
{
Assert.That(p.Select(i => i.TypeName), Has.Some.EqualTo("GenericContentPage`1"));
return typeof(ContentPage);
};
Assert.DoesNotThrow(() => XamlLoader.Create(xaml, true));
}
}
public class InstantiateThrows

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

@ -119,7 +119,8 @@ namespace Xamarin.Forms.Xaml
continue;
}
var rootnode = new RuntimeRootNode(new XmlType(reader.NamespaceURI, reader.Name, null), null, (IXmlNamespaceResolver)reader);
var typeArguments = XamlParser.GetTypeArguments(reader);
var rootnode = new RuntimeRootNode(new XmlType(reader.NamespaceURI, reader.Name, typeArguments), null, (IXmlNamespaceResolver)reader);
XamlParser.ParseXaml(rootnode, reader);
var visitorContext = new HydrationContext {
ExceptionHandler = exceptionHandler,

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

@ -155,10 +155,7 @@ namespace Xamarin.Forms.Xaml
var attributes = ParseXamlAttributes(reader, out xmlns);
var prefixes = PrefixesToIgnore(xmlns);
IList<XmlType> typeArguments = null;
if (attributes.Any(kvp => kvp.Key == XmlName.xTypeArguments))
typeArguments = ((ValueNode)attributes.First(kvp => kvp.Key == XmlName.xTypeArguments).Value).Value as IList<XmlType>;
var typeArguments = GetTypeArguments(attributes);
node = new ElementNode(new XmlType(elementNsUri, elementName, typeArguments), elementNsUri,
reader as IXmlNamespaceResolver, elementXmlInfo.LineNumber, elementXmlInfo.LinePosition);
@ -185,6 +182,15 @@ namespace Xamarin.Forms.Xaml
throw new XamlParseException("Closing PropertyElement expected", (IXmlLineInfo)reader);
}
internal static IList<XmlType> GetTypeArguments(XmlReader reader) => GetTypeArguments(ParseXamlAttributes(reader, out _));
static IList<XmlType> GetTypeArguments(IList<KeyValuePair<XmlName, INode>> attributes)
{
return attributes.Any(kvp => kvp.Key == XmlName.xTypeArguments)
? ((ValueNode)attributes.First(kvp => kvp.Key == XmlName.xTypeArguments).Value).Value as IList<XmlType>
: null;
}
static IList<KeyValuePair<XmlName, INode>> ParseXamlAttributes(XmlReader reader, out IList<KeyValuePair<string,string>> xmlns)
{
Debug.Assert(reader.NodeType == XmlNodeType.Element);