summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Xaml
diff options
context:
space:
mode:
authorStephane Delcroix <stephane@delcroix.org>2016-11-17 20:31:05 +0100
committerGitHub <noreply@github.com>2016-11-17 20:31:05 +0100
commit054ecf2704ac5d736ffb97c2932e1e078041008a (patch)
tree6e11e80a370b9ed96c473a03ecc4bbdfefa62cbe /Xamarin.Forms.Xaml
parent122f0e3e6060711d6c3b2b8523236b8a057434df (diff)
downloadxamarin-forms-054ecf2704ac5d736ffb97c2932e1e078041008a.tar.gz
xamarin-forms-054ecf2704ac5d736ffb97c2932e1e078041008a.tar.bz2
xamarin-forms-054ecf2704ac5d736ffb97c2932e1e078041008a.zip
[Xaml] cleanup xmlns usage, add XmlnsDefinition (#531)
* [Xaml] cleanup xmlns usage, add XmlnsDefinition * docs
Diffstat (limited to 'Xamarin.Forms.Xaml')
-rw-r--r--Xamarin.Forms.Xaml/Properties/AssemblyInfo.cs11
-rw-r--r--Xamarin.Forms.Xaml/TypeArgumentsParser.cs18
-rw-r--r--Xamarin.Forms.Xaml/XamlParser.cs64
-rw-r--r--Xamarin.Forms.Xaml/XamlServiceProvider.cs2
-rw-r--r--Xamarin.Forms.Xaml/XmlnsHelper.cs13
5 files changed, 70 insertions, 38 deletions
diff --git a/Xamarin.Forms.Xaml/Properties/AssemblyInfo.cs b/Xamarin.Forms.Xaml/Properties/AssemblyInfo.cs
index 58c48d26..d6b8ae9c 100644
--- a/Xamarin.Forms.Xaml/Properties/AssemblyInfo.cs
+++ b/Xamarin.Forms.Xaml/Properties/AssemblyInfo.cs
@@ -1,5 +1,6 @@
using System.Reflection;
using System.Runtime.CompilerServices;
+using Xamarin.Forms;
using Xamarin.Forms.Internals;
// Information about this assembly is defined by the following attributes.
@@ -23,4 +24,12 @@ using Xamarin.Forms.Internals;
[assembly: InternalsVisibleTo("Xamarin.Forms.Xaml.UnitTests")]
[assembly: InternalsVisibleTo("Xamarin.Forms.Build.Tasks")]
[assembly: InternalsVisibleTo("Xamarin.Forms.Xaml.Design")]
-[assembly: Preserve] \ No newline at end of file
+[assembly: Preserve]
+
+[assembly: XmlnsDefinition("http://xamarin.com/schemas/2014/forms", "Xamarin.Forms.Xaml")]
+[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml", "Xamarin.Forms.Xaml")]
+[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml", "System", AssemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
+[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml", "System", AssemblyName = "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
+[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2009/xaml", "Xamarin.Forms.Xaml")]
+[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2009/xaml", "System", AssemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
+[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2009/xaml", "System", AssemblyName = "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] \ No newline at end of file
diff --git a/Xamarin.Forms.Xaml/TypeArgumentsParser.cs b/Xamarin.Forms.Xaml/TypeArgumentsParser.cs
index 59b2dd0a..525b4d74 100644
--- a/Xamarin.Forms.Xaml/TypeArgumentsParser.cs
+++ b/Xamarin.Forms.Xaml/TypeArgumentsParser.cs
@@ -47,8 +47,22 @@ namespace Xamarin.Forms.Xaml
type.Substring(type.IndexOf('(') + 1, type.LastIndexOf(')') - type.IndexOf('(') - 1), resolver, lineinfo);
type = type.Substring(0, type.IndexOf('('));
}
- var namespaceuri = type.Contains(":") ? resolver.LookupNamespace(type.Split(':')[0].Trim()) : "";
- return new XmlType(namespaceuri, type, typeArguments);
+
+ var split = type.Split(':');
+ if (split.Length > 2)
+ return null;
+
+ string prefix, name;
+ if (split.Length == 2) {
+ prefix = split [0];
+ name = split [1];
+ } else {
+ prefix = "";
+ name = split [0];
+ }
+
+ var namespaceuri = resolver.LookupNamespace(prefix);
+ return new XmlType(namespaceuri, name, typeArguments);
}
}
} \ No newline at end of file
diff --git a/Xamarin.Forms.Xaml/XamlParser.cs b/Xamarin.Forms.Xaml/XamlParser.cs
index f2ac3197..9e841b9f 100644
--- a/Xamarin.Forms.Xaml/XamlParser.cs
+++ b/Xamarin.Forms.Xaml/XamlParser.cs
@@ -34,7 +34,7 @@ using System.Xml;
namespace Xamarin.Forms.Xaml
{
- internal static class XamlParser
+ static class XamlParser
{
public static void ParseXaml(RootNode rootNode, XmlReader reader)
{
@@ -83,16 +83,16 @@ namespace Xamarin.Forms.Xaml
var prop = ReadNode(reader);
if (prop != null)
node.Properties.Add(XmlName.xArguments, prop);
- // 3. DataTemplate (should be handled by 4.)
}
+ // 3. DataTemplate (should be handled by 4.)
else if (node.XmlType.NamespaceUri == "http://xamarin.com/schemas/2014/forms" &&
(node.XmlType.Name == "DataTemplate" || node.XmlType.Name == "ControlTemplate"))
{
var prop = ReadNode(reader, true);
if (prop != null)
node.Properties.Add(XmlName._CreateContent, prop);
- // 4. Implicit content, implicit collection, or collection syntax. Add to CollectionItems, resolve case later.
}
+ // 4. Implicit content, implicit collection, or collection syntax. Add to CollectionItems, resolve case later.
else
{
var item = ReadNode(reader, true);
@@ -191,7 +191,10 @@ namespace Xamarin.Forms.Xaml
continue;
}
- var propertyName = new XmlName(reader.NamespaceURI, reader.LocalName);
+ var namespaceUri = reader.NamespaceURI;
+ if (reader.LocalName.Contains(".") && namespaceUri == "")
+ namespaceUri = ((IXmlNamespaceResolver)reader).LookupNamespace("");
+ var propertyName = new XmlName(namespaceUri, reader.LocalName);
object value = reader.Value;
@@ -283,39 +286,56 @@ namespace Xamarin.Forms.Xaml
((IXmlLineInfo)reader).LinePosition);
}
+ static IList<XmlnsDefinitionAttribute> s_xmlnsDefinitions;
+
+ static void GatherXmlnsDefinitionAttributes()
+ {
+ //this could be extended to look for [XmlnsDefinition] in all assemblies
+ var assemblies = new [] {
+ typeof(View).GetTypeInfo().Assembly,
+ typeof(XamlLoader).GetTypeInfo().Assembly,
+ };
+
+ s_xmlnsDefinitions = new List<XmlnsDefinitionAttribute>();
+
+ foreach (var assembly in assemblies)
+ foreach (XmlnsDefinitionAttribute attribute in assembly.GetCustomAttributes(typeof(XmlnsDefinitionAttribute))) {
+ s_xmlnsDefinitions.Add(attribute);
+ attribute.AssemblyName = attribute.AssemblyName ?? assembly.FullName;
+ }
+ }
+
public static Type GetElementType(XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly,
out XamlParseException exception)
{
+ if (s_xmlnsDefinitions == null)
+ GatherXmlnsDefinitionAttributes();
+
var namespaceURI = xmlType.NamespaceUri;
var elementName = xmlType.Name;
var typeArguments = xmlType.TypeArguments;
exception = null;
- var lookupAssemblies = new List<Tuple<string, string>>(); //namespace, assemblyqualifiednamed
+ var lookupAssemblies = new List<XmlnsDefinitionAttribute>();
var lookupNames = new List<string>();
- if (!XmlnsHelper.IsCustom(namespaceURI))
- {
- lookupAssemblies.Add(new Tuple<string, string>("Xamarin.Forms", typeof (View).GetTypeInfo().Assembly.FullName));
- lookupAssemblies.Add(new Tuple<string, string>("Xamarin.Forms.Xaml", typeof (XamlLoader).GetTypeInfo().Assembly.FullName));
- }
- else if (namespaceURI == "http://schemas.microsoft.com/winfx/2009/xaml" ||
- namespaceURI == "http://schemas.microsoft.com/winfx/2006/xaml")
- {
- lookupAssemblies.Add(new Tuple<string, string>("Xamarin.Forms.Xaml", typeof (XamlLoader).GetTypeInfo().Assembly.FullName));
- lookupAssemblies.Add(new Tuple<string, string>("System", typeof (object).GetTypeInfo().Assembly.FullName)); //mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- lookupAssemblies.Add(new Tuple<string, string>("System", typeof (Uri).GetTypeInfo().Assembly.FullName)); //System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+ foreach (var xmlnsDef in s_xmlnsDefinitions) {
+ if (xmlnsDef.XmlNamespace != namespaceURI)
+ continue;
+ lookupAssemblies.Add(xmlnsDef);
}
- else
- {
+
+ if (lookupAssemblies.Count == 0) {
string ns, asmstring, _;
XmlnsHelper.ParseXmlns(namespaceURI, out _, out ns, out asmstring, out _);
- lookupAssemblies.Add(new Tuple<string, string>(ns, asmstring ?? currentAssembly.FullName));
+ lookupAssemblies.Add(new XmlnsDefinitionAttribute(namespaceURI, ns) {
+ AssemblyName = asmstring ?? currentAssembly.FullName
+ });
}
lookupNames.Add(elementName);
- if (namespaceURI == "http://schemas.microsoft.com/winfx/2009/xaml")
- lookupNames.Add(elementName + "Extension");
+ lookupNames.Add(elementName + "Extension");
+
for (var i = 0; i < lookupNames.Count; i++)
{
var name = lookupNames[i];
@@ -329,7 +349,7 @@ namespace Xamarin.Forms.Xaml
Type type = null;
foreach (var asm in lookupAssemblies) {
foreach (var name in lookupNames)
- if ((type = Type.GetType($"{asm.Item1}.{name}, {asm.Item2}")) != null)
+ if ((type = Type.GetType($"{asm.ClrNamespace}.{name}, {asm.AssemblyName}")) != null)
break;
if (type != null)
break;
diff --git a/Xamarin.Forms.Xaml/XamlServiceProvider.cs b/Xamarin.Forms.Xaml/XamlServiceProvider.cs
index 5599cbbc..19dd96f5 100644
--- a/Xamarin.Forms.Xaml/XamlServiceProvider.cs
+++ b/Xamarin.Forms.Xaml/XamlServiceProvider.cs
@@ -231,7 +231,7 @@ namespace Xamarin.Forms.Xaml.Internals
xmlLineInfo = lineInfoProvider.XmlLineInfo;
}
- var namespaceuri = prefix == null ? "" : namespaceResolver.LookupNamespace(prefix);
+ var namespaceuri = namespaceResolver.LookupNamespace(prefix);
if (namespaceuri == null)
{
exception = new XamlParseException(string.Format("No xmlns declaration for prefix \"{0}\"", prefix), xmlLineInfo);
diff --git a/Xamarin.Forms.Xaml/XmlnsHelper.cs b/Xamarin.Forms.Xaml/XmlnsHelper.cs
index e3e37de4..e29dbc0c 100644
--- a/Xamarin.Forms.Xaml/XmlnsHelper.cs
+++ b/Xamarin.Forms.Xaml/XmlnsHelper.cs
@@ -2,19 +2,8 @@ using System;
namespace Xamarin.Forms.Xaml
{
- internal static class XmlnsHelper
+ static class XmlnsHelper
{
- public static bool IsCustom(string ns)
- {
- switch (ns)
- {
- case "":
- case "http://xamarin.com/schemas/2014/forms":
- return false;
- }
- return true;
- }
-
public static string ParseNamespaceFromXmlns(string xmlns)
{
string typeName;