[X] allow previewer fallback on rootnode (#5413)
authorStephane Delcroix <stephane@delcroix.org>
Thu, 28 Feb 2019 19:41:34 +0000 (20:41 +0100)
committerSamantha Houts <samantha.houts@xamarin.com>
Thu, 28 Feb 2019 19:43:15 +0000 (11:43 -0800)
* [X] allow previewer fallback on rootnode

- fixes #5410

* additional test case

Xamarin.Forms.Xaml.UnitTests/DesignTimeLoaderTests.cs
Xamarin.Forms.Xaml/XamlParser.cs

index f3dbfc0..1c9e16f 100644 (file)
@@ -550,6 +550,62 @@ namespace Xamarin.Forms.Xaml.UnitTests
                        Assert.DoesNotThrow(() => XamlLoader.Create(xaml, true));
                        Assert.That(exceptions.Count, Is.EqualTo(1));
                }
+
+               [Test]
+               public void CanResolveRootNode()
+               {
+                       string assemblyName = null;
+                       string clrNamespace = null;
+                       string typeName = null;
+
+
+                       XamlLoader.FallbackTypeResolver = (fallbackTypeInfos, type) =>
+                       {
+                               assemblyName = fallbackTypeInfos?[1].AssemblyName;
+                               clrNamespace = fallbackTypeInfos?[1].ClrNamespace;
+                               typeName = fallbackTypeInfos?[1].TypeName;
+                               return type ?? typeof(MockView);
+                       };
+
+                       var xaml = @"
+                                               <local:MissingType xmlns=""http://xamarin.com/schemas/2014/forms""
+                                                       xmlns:x=""http://schemas.microsoft.com/winfx/2009/xaml""
+                                                       xmlns:local=""clr-namespace:my.namespace;assembly=my.assembly"">
+                                               </local:MissingType>";
+
+                       XamlLoader.Create(xaml, true);
+                       Assert.That(assemblyName, Is.EqualTo("my.assembly"));
+                       Assert.That(clrNamespace, Is.EqualTo("my.namespace"));
+                       Assert.That(typeName, Is.EqualTo("MissingType"));
+               }
+
+               [Test]
+               public void CanResolveRootNodeWithoutAssembly()
+               {
+                       string assemblyName = null;
+                       string clrNamespace = null;
+                       string typeName = null;
+
+
+                       XamlLoader.FallbackTypeResolver = (fallbackTypeInfos, type) =>
+                       {
+                               assemblyName = fallbackTypeInfos?[1].AssemblyName;
+                               clrNamespace = fallbackTypeInfos?[1].ClrNamespace;
+                               typeName = fallbackTypeInfos?[1].TypeName;
+                               return type ?? typeof(MockView);
+                       };
+
+                       var xaml = @"
+                                               <local:MissingType xmlns=""http://xamarin.com/schemas/2014/forms""
+                                                       xmlns:x=""http://schemas.microsoft.com/winfx/2009/xaml""
+                                                       xmlns:local=""using:my.namespace"">
+                                               </local:MissingType>";
+
+                       XamlLoader.Create(xaml, true);
+                       Assert.That(assemblyName, Is.EqualTo(null));
+                       Assert.That(clrNamespace, Is.EqualTo("my.namespace"));
+                       Assert.That(typeName, Is.EqualTo("MissingType"));
+               }
        }
 
        public class InstantiateThrows
index b571e6a..afa3971 100644 (file)
@@ -408,41 +408,27 @@ namespace Xamarin.Forms.Xaml
                        var namespaceURI = xmlType.NamespaceUri;
                        var elementName = xmlType.Name;
                        var typeArguments = xmlType.TypeArguments;
-                       potentialTypes = null;                  
+                       potentialTypes = null;
 
-                       foreach (var xmlnsDef in xmlnsDefinitions)
-                       {
+                       foreach (var xmlnsDef in xmlnsDefinitions) {
                                if (xmlnsDef.XmlNamespace != namespaceURI)
                                        continue;
                                lookupAssemblies.Add(xmlnsDef);
                        }
 
-                       if (lookupAssemblies.Count == 0)
-                       {
-                               if (defaultAssemblyName == null)
-                                       return null;
-
-                               string ns;
-                               string typename;
-                               string asmstring;
-                               string targetPlatform;
-
-                               XmlnsHelper.ParseXmlns(namespaceURI, out typename, out ns, out asmstring, out targetPlatform);
+                       if (lookupAssemblies.Count == 0) {
+                               XmlnsHelper.ParseXmlns(namespaceURI, out _, out var ns, out var asmstring, out _);
                                asmstring = asmstring ?? defaultAssemblyName;
                                if (namespaceURI != null && ns != null)
-                                       lookupAssemblies.Add(new XmlnsDefinitionAttribute(namespaceURI, ns)
-                                       {
-                                               AssemblyName = asmstring
-                                       });
+                                       lookupAssemblies.Add(new XmlnsDefinitionAttribute(namespaceURI, ns) { AssemblyName = asmstring });
                        }
 
                        var lookupNames = new List<string>();
-                       if (elementName != "DataTemplate" && !elementName.EndsWith("Extension"))
+                       if (elementName != "DataTemplate" && !elementName.EndsWith("Extension", StringComparison.Ordinal))
                                lookupNames.Add(elementName + "Extension");
                        lookupNames.Add(elementName);
 
-                       for (var i = 0; i < lookupNames.Count; i++)
-                       {
+                       for (var i = 0; i < lookupNames.Count; i++) {
                                var name = lookupNames[i];
                                if (name.Contains(":"))
                                        name = name.Substring(name.LastIndexOf(':') + 1);
@@ -453,9 +439,8 @@ namespace Xamarin.Forms.Xaml
                        
                        potentialTypes = new List<XamlLoader.FallbackTypeInfo>();
                        foreach (string typeName in lookupNames)
-                               foreach (XmlnsDefinitionAttribute xmlnsDefinitionAttribute in lookupAssemblies)                         
-                                       potentialTypes.Add(new XamlLoader.FallbackTypeInfo
-                                       {
+                               foreach (XmlnsDefinitionAttribute xmlnsDefinitionAttribute in lookupAssemblies) 
+                                       potentialTypes.Add(new XamlLoader.FallbackTypeInfo {
                                                ClrNamespace = xmlnsDefinitionAttribute.ClrNamespace,
                                                TypeName = typeName,
                                                AssemblyName = xmlnsDefinitionAttribute.AssemblyName,