summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephane Delcroix <stephane@delcroix.org>2017-04-28 10:39:16 +0200
committerGitHub <noreply@github.com>2017-04-28 10:39:16 +0200
commit84ba9edce46967d34b5c0cc92a0ca117d712ff7e (patch)
tree985915c6f8365f6791def072a68c23549bb83507
parent6ee219ca1db3f4d43370d39865c705d9c99ad38e (diff)
downloadxamarin-forms-84ba9edce46967d34b5c0cc92a0ca117d712ff7e.tar.gz
xamarin-forms-84ba9edce46967d34b5c0cc92a0ca117d712ff7e.tar.bz2
xamarin-forms-84ba9edce46967d34b5c0cc92a0ca117d712ff7e.zip
[XamlG] supports x:FieldModifier (#878)
* [XamlG] supports x:FieldModifier * adapt test as duplicate fields are now caught at XamlG time * [XamlG] supports UWP values in addition of WPF's for x:FieldModifier
-rw-r--r--Xamarin.Forms.Build.Tasks/XamlGTask.cs105
-rw-r--r--Xamarin.Forms.Xaml.UnitTests/FieldModifier.xaml11
-rw-r--r--Xamarin.Forms.Xaml.UnitTests/FieldModifier.xaml.cs42
-rw-r--r--Xamarin.Forms.Xaml.UnitTests/Issues/Issue2450.xaml18
-rw-r--r--Xamarin.Forms.Xaml.UnitTests/Issues/Issue2450.xaml.cs10
-rw-r--r--Xamarin.Forms.Xaml.UnitTests/Xamarin.Forms.Xaml.UnitTests.csproj6
-rw-r--r--Xamarin.Forms.Xaml.UnitTests/XamlgTests.cs110
-rw-r--r--Xamarin.Forms.Xaml/XamlParser.cs4
8 files changed, 210 insertions, 96 deletions
diff --git a/Xamarin.Forms.Build.Tasks/XamlGTask.cs b/Xamarin.Forms.Build.Tasks/XamlGTask.cs
index b13eec69..35db159f 100644
--- a/Xamarin.Forms.Build.Tasks/XamlGTask.cs
+++ b/Xamarin.Forms.Build.Tasks/XamlGTask.cs
@@ -60,7 +60,7 @@ namespace Xamarin.Forms.Build.Tasks
}
internal static void ParseXaml(TextReader xaml, out string rootType, out string rootNs, out CodeTypeReference baseType,
- out IDictionary<string, CodeTypeReference> namesAndTypes)
+ out IEnumerable<CodeMemberField> namedFields)
{
var xmlDoc = new XmlDocument();
xmlDoc.Load(xaml);
@@ -76,7 +76,7 @@ namespace Xamarin.Forms.Build.Tasks
rootType = null;
rootNs = null;
baseType = null;
- namesAndTypes = null;
+ namedFields = null;
return;
}
@@ -96,18 +96,16 @@ namespace Xamarin.Forms.Build.Tasks
rootType = null;
rootNs = null;
baseType = null;
- namesAndTypes = null;
+ namedFields = null;
return;
}
string rootAsm, targetPlatform;
XmlnsHelper.ParseXmlns(rootClass.Value, out rootType, out rootNs, out rootAsm, out targetPlatform);
- namesAndTypes = GetNamesAndTypes(root, nsmgr);
+ namedFields = GetCodeMemberFields(root, nsmgr);
- var typeArgsAttr = root.Attributes["TypeArguments", XAML2006]
- ?? root.Attributes["TypeArguments", XAML2009];
-
- var xmlType = new XmlType(root.NamespaceURI, root.LocalName, typeArgsAttr != null ? TypeArgumentsParser.ParseExpression(typeArgsAttr.Value, nsmgr, null): null);
+ var typeArguments = GetAttributeValue(root, "TypeArguments", XAML2006, XAML2009);
+ var xmlType = new XmlType(root.NamespaceURI, root.LocalName, typeArguments != null ? TypeArgumentsParser.ParseExpression(typeArguments, nsmgr, null): null);
baseType = GetType(xmlType, root.GetNamespaceOfPrefix);
}
@@ -117,7 +115,7 @@ namespace Xamarin.Forms.Build.Tasks
new CodeAttributeArgument(new CodePrimitiveExpression("0.0.0.0")));
internal static void GenerateCode(string rootType, string rootNs, CodeTypeReference baseType,
- IDictionary<string, CodeTypeReference> namesAndTypes, string xamlFile, string outFile)
+ IEnumerable<CodeMemberField> namedFields, string xamlFile, string outFile)
{
if (rootType == null)
{
@@ -151,28 +149,18 @@ namespace Xamarin.Forms.Build.Tasks
new CodeTypeReferenceExpression(new CodeTypeReference($"global::{typeof(Extensions).FullName}")),
"LoadFromXaml", new CodeThisReferenceExpression(), new CodeTypeOfExpression(declType.Name)));
- foreach (var entry in namesAndTypes)
+ foreach (var namedField in namedFields)
{
- string name = entry.Key;
- var type = entry.Value;
-
- var field = new CodeMemberField
- {
- Name = name,
- Type = type,
- CustomAttributes = { GeneratedCodeAttrDecl }
- };
-
- declType.Members.Add(field);
+ declType.Members.Add(namedField);
var find_invoke = new CodeMethodInvokeExpression(
new CodeMethodReferenceExpression(
new CodeTypeReferenceExpression(new CodeTypeReference($"global::{typeof(NameScopeExtensions).FullName}")),
- "FindByName", type),
- new CodeThisReferenceExpression(), new CodePrimitiveExpression(name));
+ "FindByName", namedField.Type),
+ new CodeThisReferenceExpression(), new CodePrimitiveExpression(namedField.Name));
CodeAssignStatement assign = new CodeAssignStatement(
- new CodeVariableReferenceExpression(name), find_invoke);
+ new CodeVariableReferenceExpression(namedField.Name), find_invoke);
initcomp.Statements.Add(assign);
}
@@ -185,21 +173,19 @@ namespace Xamarin.Forms.Build.Tasks
{
string rootType, rootNs;
CodeTypeReference baseType;
- IDictionary<string, CodeTypeReference> namesAndTypes;
+ IEnumerable<CodeMemberField> namedFields;
using (StreamReader reader = File.OpenText(xamlFile))
- ParseXaml(reader, out rootType, out rootNs, out baseType, out namesAndTypes);
+ ParseXaml(reader, out rootType, out rootNs, out baseType, out namedFields);
- GenerateCode(rootType, rootNs, baseType, namesAndTypes, Path.GetFullPath(xamlFile), outFile);
+ GenerateCode(rootType, rootNs, baseType, namedFields, Path.GetFullPath(xamlFile), outFile);
}
- static Dictionary<string, CodeTypeReference> GetNamesAndTypes(XmlNode root, XmlNamespaceManager nsmgr)
+ static IEnumerable<CodeMemberField> GetCodeMemberFields(XmlNode root, XmlNamespaceManager nsmgr)
{
- var res = new Dictionary<string, CodeTypeReference>();
-
var xPrefix = nsmgr.LookupPrefix(XAML2006) ?? nsmgr.LookupPrefix(XAML2009);
if (xPrefix == null)
- return null;
+ yield break;
XmlNodeList names =
root.SelectNodes(
@@ -210,20 +196,42 @@ namespace Xamarin.Forms.Build.Tasks
// Don't take the root canvas
if (node == root)
continue;
+ var name = GetAttributeValue(node, "Name", XAML2006, XAML2009);
+ var typeArguments = GetAttributeValue(node, "TypeArguments", XAML2006, XAML2009);
+ var fieldModifier = GetAttributeValue(node, "FieldModifier", XAML2006, XAML2009);
- XmlAttribute attr = node.Attributes["Name", XAML2006]
- ?? node.Attributes["Name", XAML2009];
- XmlAttribute typeArgsAttr = node.Attributes["TypeArguments", XAML2006]
- ?? node.Attributes["TypeArguments", XAML2009];
var xmlType = new XmlType(node.NamespaceURI, node.LocalName,
- typeArgsAttr != null
- ? TypeArgumentsParser.ParseExpression(typeArgsAttr.Value, nsmgr, null)
+ typeArguments != null
+ ? TypeArgumentsParser.ParseExpression(typeArguments, nsmgr, null)
: null);
- res[attr.Value] = GetType(xmlType, node.GetNamespaceOfPrefix);
- }
+ var access = MemberAttributes.Private;
+ if (fieldModifier!=null) {
+ switch (fieldModifier.ToLowerInvariant()){
+ default:
+ case "private":
+ access = MemberAttributes.Private;
+ break;
+ case "public":
+ access = MemberAttributes.Public;
+ break;
+ case "protected":
+ access = MemberAttributes.Family;
+ break;
+ case "internal":
+ case "notpublic": //WPF syntax
+ access = MemberAttributes.Assembly;
+ break;
+ }
+ }
- return res;
+ yield return new CodeMemberField {
+ Name = name,
+ Type = GetType(xmlType, node.GetNamespaceOfPrefix),
+ Attributes = access,
+ CustomAttributes = { GeneratedCodeAttrDecl }
+ };
+ }
}
static CodeTypeReference GetType(XmlType xmlType,
@@ -258,5 +266,22 @@ namespace Xamarin.Forms.Build.Tasks
throw new Exception($"Can't load types from xmlns {namespaceuri}");
return XmlnsHelper.ParseNamespaceFromXmlns(namespaceuri);
}
+
+ static string GetAttributeValue(XmlNode node, string localName, params string[] namespaceURIs)
+ {
+ if (node == null)
+ throw new ArgumentNullException(nameof(node));
+ if (localName == null)
+ throw new ArgumentNullException(nameof(localName));
+ if (namespaceURIs == null)
+ throw new ArgumentNullException(nameof(namespaceURIs));
+ foreach (var namespaceURI in namespaceURIs) {
+ var attr = node.Attributes[localName, namespaceURI];
+ if (attr == null)
+ continue;
+ return attr.Value;
+ }
+ return null;
+ }
}
} \ No newline at end of file
diff --git a/Xamarin.Forms.Xaml.UnitTests/FieldModifier.xaml b/Xamarin.Forms.Xaml.UnitTests/FieldModifier.xaml
new file mode 100644
index 00000000..a4623297
--- /dev/null
+++ b/Xamarin.Forms.Xaml.UnitTests/FieldModifier.xaml
@@ -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="clr-namespace:Xamarin.Forms.Xaml.UnitTests"
+ x:Class="Xamarin.Forms.Xaml.UnitTests.FieldModifier">
+ <StackLayout>
+ <Label x:Name="privateLabel" />
+ <Label x:Name="internalLabel" x:FieldModifier="NotPublic" />
+ <Label x:Name="publicLabel" x:FieldModifier="Public" />
+ </StackLayout>
+</ContentPage> \ No newline at end of file
diff --git a/Xamarin.Forms.Xaml.UnitTests/FieldModifier.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/FieldModifier.xaml.cs
new file mode 100644
index 00000000..fde0e777
--- /dev/null
+++ b/Xamarin.Forms.Xaml.UnitTests/FieldModifier.xaml.cs
@@ -0,0 +1,42 @@
+using System.Linq;
+using System.Reflection;
+using NUnit.Framework;
+
+namespace Xamarin.Forms.Xaml.UnitTests
+{
+ public partial class FieldModifier : ContentPage
+ {
+ public FieldModifier()
+ {
+ InitializeComponent();
+ }
+
+ public FieldModifier (bool useCompiledXaml)
+ {
+ //this stub will be replaced at compile time
+ }
+
+ [TestFixture]
+ public class FindByNameTests
+ {
+ [TestCase (false)]
+ [TestCase (true)]
+ public void TestFieldModifier (bool useCompiledXaml)
+ {
+ var layout = new FieldModifier();
+ Assert.That(layout.privateLabel, Is.Not.Null);
+ Assert.That(layout.internalLabel, Is.Not.Null);
+ Assert.That(layout.publicLabel, Is.Not.Null);
+
+ var fields = typeof(FieldModifier).GetTypeInfo().DeclaredFields;
+
+ Assert.That(fields.First(fi => fi.Name == "privateLabel").IsPrivate, Is.True);
+
+ Assert.That(fields.First(fi => fi.Name == "internalLabel").IsPrivate, Is.False);
+ Assert.That(fields.First(fi => fi.Name == "internalLabel").IsPublic, Is.False);
+
+ Assert.That(fields.First(fi => fi.Name == "publicLabel").IsPublic, Is.True);
+ }
+ }
+ }
+}
diff --git a/Xamarin.Forms.Xaml.UnitTests/Issues/Issue2450.xaml b/Xamarin.Forms.Xaml.UnitTests/Issues/Issue2450.xaml
index 385619e5..8fc57819 100644
--- a/Xamarin.Forms.Xaml.UnitTests/Issues/Issue2450.xaml
+++ b/Xamarin.Forms.Xaml.UnitTests/Issues/Issue2450.xaml
@@ -1,10 +1,16 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Xamarin.Forms.Xaml.UnitTests.Issue2450">
- <StackLayout>
- <Label x:Name="label0"/>
- <Label x:Name="label0"/>
- </StackLayout>
-</ContentPage>
+ <ContentPage.Resources>
+ <ResourceDictionary>
+ <DataTemplate x:Key="foo">
+ <ViewCell>
+ <Label x:Name="label0"/>
+ <Label x:Name="label0"/>
+ </ViewCell>
+ </DataTemplate>
+ </ResourceDictionary>
+ </ContentPage.Resources>
+</ContentPage> \ No newline at end of file
diff --git a/Xamarin.Forms.Xaml.UnitTests/Issues/Issue2450.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/Issues/Issue2450.xaml.cs
index 2d330934..d1a15659 100644
--- a/Xamarin.Forms.Xaml.UnitTests/Issues/Issue2450.xaml.cs
+++ b/Xamarin.Forms.Xaml.UnitTests/Issues/Issue2450.xaml.cs
@@ -29,15 +29,11 @@ namespace Xamarin.Forms.Xaml.UnitTests
}
[TestCase (false)]
- [TestCase (true)]
public void ThrowMeaningfulExceptionOnDuplicateXName (bool useCompiledXaml)
{
- if (useCompiledXaml)
- Assert.Throws(new XamlParseExceptionConstraint(8, 10, m => m == "An element with the name \"label0\" already exists in this NameScope"),
- () => MockCompiler.Compile(typeof(Issue2450)));
- else
- Assert.Throws(new XamlParseExceptionConstraint(8, 10, m => m == "An element with the name \"label0\" already exists in this NameScope"),
- () => new Issue2450(useCompiledXaml));
+ var layout = new Issue2450(useCompiledXaml);
+ Assert.Throws(new XamlParseExceptionConstraint(11, 13, m => m == "An element with the name \"label0\" already exists in this NameScope"),
+ () => (layout.Resources ["foo"] as Forms.DataTemplate).CreateContent());
}
}
}
diff --git a/Xamarin.Forms.Xaml.UnitTests/Xamarin.Forms.Xaml.UnitTests.csproj b/Xamarin.Forms.Xaml.UnitTests/Xamarin.Forms.Xaml.UnitTests.csproj
index 123a0d59..0d98f25a 100644
--- a/Xamarin.Forms.Xaml.UnitTests/Xamarin.Forms.Xaml.UnitTests.csproj
+++ b/Xamarin.Forms.Xaml.UnitTests/Xamarin.Forms.Xaml.UnitTests.csproj
@@ -482,6 +482,9 @@
<Compile Include="Issues\Bz55347.xaml.cs">
<DependentUpon>Bz55347.xaml</DependentUpon>
</Compile>
+ <Compile Include="FieldModifier.xaml.cs">
+ <DependentUpon>FieldModifier.xaml</DependentUpon>
+ </Compile>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="..\.nuspec\Xamarin.Forms.Debug.targets" />
@@ -884,6 +887,9 @@
<EmbeddedResource Include="Issues\Bz55347.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
+ <EmbeddedResource Include="FieldModifier.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ </EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
diff --git a/Xamarin.Forms.Xaml.UnitTests/XamlgTests.cs b/Xamarin.Forms.Xaml.UnitTests/XamlgTests.cs
index 9303539e..edf2d075 100644
--- a/Xamarin.Forms.Xaml.UnitTests/XamlgTests.cs
+++ b/Xamarin.Forms.Xaml.UnitTests/XamlgTests.cs
@@ -26,20 +26,20 @@ namespace Xamarin.Forms.Xaml.UnitTests
var reader = new StringReader (xaml);
string rootType, rootNs;
CodeTypeReference baseType;
- IDictionary<string,CodeTypeReference> namesAndTypes;
+ IEnumerable<CodeMemberField> codeMemberFields;
- XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out namesAndTypes);
+ XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out codeMemberFields);
Assert.NotNull (rootType);
Assert.NotNull (rootNs);
Assert.NotNull (baseType);
- Assert.NotNull (namesAndTypes);
+ Assert.NotNull (codeMemberFields);
Assert.AreEqual ("CustomView", rootType);
Assert.AreEqual ("Xamarin.Forms.Xaml.UnitTests", rootNs);
Assert.AreEqual ("Xamarin.Forms.View", baseType.BaseType);
- Assert.AreEqual (1, namesAndTypes.Count);
- Assert.AreEqual ("label0", namesAndTypes.First().Key);
- Assert.AreEqual ("Xamarin.Forms.Label", namesAndTypes.First().Value.BaseType);
+ Assert.AreEqual (1, codeMemberFields.Count());
+ Assert.AreEqual ("label0", codeMemberFields.First().Name);
+ Assert.AreEqual ("Xamarin.Forms.Label", codeMemberFields.First().Type.BaseType);
}
[Test]
@@ -55,20 +55,20 @@ namespace Xamarin.Forms.Xaml.UnitTests
var reader = new StringReader (xaml);
string rootType, rootNs;
CodeTypeReference baseType;
- IDictionary<string,CodeTypeReference> namesAndTypes;
+ IEnumerable<CodeMemberField> codeMemberFields;
- XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out namesAndTypes);
+ XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out codeMemberFields);
Assert.NotNull (rootType);
Assert.NotNull (rootNs);
Assert.NotNull (baseType);
- Assert.NotNull (namesAndTypes);
+ Assert.NotNull (codeMemberFields);
Assert.AreEqual ("CustomView", rootType);
Assert.AreEqual ("Xamarin.Forms.Xaml.UnitTests", rootNs);
Assert.AreEqual ("Xamarin.Forms.View", baseType.BaseType);
- Assert.AreEqual (1, namesAndTypes.Count);
- Assert.AreEqual ("label0", namesAndTypes.First().Key);
- Assert.AreEqual ("Xamarin.Forms.Label", namesAndTypes.First().Value.BaseType);
+ Assert.AreEqual (1, codeMemberFields.Count());
+ Assert.AreEqual ("label0", codeMemberFields.First().Name);
+ Assert.AreEqual ("Xamarin.Forms.Label", codeMemberFields.First().Type.BaseType);
}
[Test]
@@ -92,13 +92,12 @@ namespace Xamarin.Forms.Xaml.UnitTests
var reader = new StringReader (xaml);
string rootType, rootNs;
CodeTypeReference baseType;
- IDictionary<string,CodeTypeReference> namesAndTypes;
-
- XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out namesAndTypes);
- Assert.AreEqual (1, namesAndTypes.Count);
- Assert.AreEqual ("listView", namesAndTypes.First ().Key);
- Assert.AreEqual ("CustomListViewSample.CustomListView", namesAndTypes.First ().Value.BaseType);
+ IEnumerable<CodeMemberField> codeMemberFields;
+ XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out codeMemberFields);
+ Assert.AreEqual (1, codeMemberFields.Count());
+ Assert.AreEqual ("listView", codeMemberFields.First ().Name);
+ Assert.AreEqual ("CustomListViewSample.CustomListView", codeMemberFields.First ().Type.BaseType);
}
[Test]
@@ -122,12 +121,12 @@ namespace Xamarin.Forms.Xaml.UnitTests
var reader = new StringReader (xaml);
string rootType, rootNs;
CodeTypeReference baseType;
- IDictionary<string,CodeTypeReference> namesAndTypes;
+ IEnumerable<CodeMemberField> codeMemberFields;
- XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out namesAndTypes);
- Assert.Contains ("included", namesAndTypes.Keys.ToList());
- Assert.False (namesAndTypes.Keys.Contains ("notincluded"));
- Assert.AreEqual (1, namesAndTypes.Count);
+ XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out codeMemberFields);
+ Assert.Contains ("included", codeMemberFields.Select(cmf => cmf.Name).ToList());
+ Assert.False (codeMemberFields.Select(cmf => cmf.Name).Contains ("notincluded"));
+ Assert.AreEqual (1, codeMemberFields.Count());
}
[Test]
@@ -152,11 +151,11 @@ namespace Xamarin.Forms.Xaml.UnitTests
var reader = new StringReader (xaml);
string rootType, rootNs;
CodeTypeReference baseType;
- IDictionary<string,CodeTypeReference> namesAndTypes;
+ IEnumerable<CodeMemberField> codeMemberFields;
- XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out namesAndTypes);
- Assert.False (namesAndTypes.Keys.Contains ("notincluded"));
- Assert.AreEqual (0, namesAndTypes.Count);
+ XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out codeMemberFields);
+ Assert.False (codeMemberFields.Select(cmf => cmf.Name).Contains ("notincluded"));
+ Assert.AreEqual (0, codeMemberFields.Count());
}
[Test]
@@ -171,9 +170,9 @@ namespace Xamarin.Forms.Xaml.UnitTests
var reader = new StringReader (xaml);
string rootType, rootNs;
CodeTypeReference baseType;
- IDictionary<string,CodeTypeReference> namesAndTypes;
+ IEnumerable<CodeMemberField> codeMemberFields;
- XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out namesAndTypes);
+ XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out codeMemberFields);
Assert.AreEqual ("FooBar", rootType);
Assert.AreEqual ("Xamarin.Forms.Foo`1", baseType.BaseType);
Assert.AreEqual (1, baseType.TypeArguments.Count);
@@ -192,9 +191,9 @@ namespace Xamarin.Forms.Xaml.UnitTests
var reader = new StringReader (xaml);
string rootType, rootNs;
CodeTypeReference baseType;
- IDictionary<string,CodeTypeReference> namesAndTypes;
+ IEnumerable<CodeMemberField> codeMemberFields;
- XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out namesAndTypes);
+ XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out codeMemberFields);
Assert.AreEqual ("FooBar", rootType);
Assert.AreEqual ("Xamarin.Forms.Foo`2", baseType.BaseType);
Assert.AreEqual (2, baseType.TypeArguments.Count);
@@ -214,9 +213,9 @@ namespace Xamarin.Forms.Xaml.UnitTests
var reader = new StringReader (xaml);
string rootType, rootNs;
CodeTypeReference baseType;
- IDictionary<string,CodeTypeReference> namesAndTypes;
+ IEnumerable<CodeMemberField> codeMemberFields;
- XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out namesAndTypes);
+ XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out codeMemberFields);
Assert.AreEqual ("FooBar", rootType);
Assert.AreEqual ("Xamarin.Forms.Foo`2", baseType.BaseType);
Assert.AreEqual (2, baseType.TypeArguments.Count);
@@ -239,9 +238,9 @@ namespace Xamarin.Forms.Xaml.UnitTests
var reader = new StringReader (xaml);
string rootType, rootNs;
CodeTypeReference baseType;
- IDictionary<string,CodeTypeReference> namesAndTypes;
+ IEnumerable<CodeMemberField> codeMemberFields;
- XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out namesAndTypes);
+ XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out codeMemberFields);
Assert.AreEqual ("FooBar", rootType);
Assert.AreEqual ("Xamarin.Forms.Foo`2", baseType.BaseType);
Assert.AreEqual (2, baseType.TypeArguments.Count);
@@ -264,9 +263,9 @@ namespace Xamarin.Forms.Xaml.UnitTests
var reader = new StringReader (xaml);
string rootType, rootNs;
CodeTypeReference baseType;
- IDictionary<string,CodeTypeReference> namesAndTypes;
+ IEnumerable<CodeMemberField> codeMemberFields;
- XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out namesAndTypes);
+ XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out codeMemberFields);
Assert.AreEqual ("FooBar", rootType);
Assert.AreEqual ("Xamarin.Forms.Foo`2", baseType.BaseType);
Assert.AreEqual (2, baseType.TypeArguments.Count);
@@ -288,13 +287,40 @@ namespace Xamarin.Forms.Xaml.UnitTests
using (var reader = new StringReader (xaml)) {
string rootType, rootNs;
CodeTypeReference baseType;
- IDictionary<string,CodeTypeReference> namesAndTypes;
+ IEnumerable<CodeMemberField> codeMemberFields;
- XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out namesAndTypes);
+ XamlGTask.ParseXaml (reader, out rootType, out rootNs, out baseType, out codeMemberFields);
Assert.IsTrue (baseType.Options.HasFlag (CodeTypeReferenceOptions.GlobalReference));
- Assert.IsTrue (namesAndTypes.Values.First ().Options.HasFlag (CodeTypeReferenceOptions.GlobalReference));
+ Assert.IsTrue (codeMemberFields.Select(cmf => cmf.Type).First ().Options.HasFlag (CodeTypeReferenceOptions.GlobalReference));
}
}
- }
-}
+ [Test]
+ public void FieldModifier()
+ {
+ var xaml = @"
+ <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.FieldModifier"">
+ <StackLayout>
+ <Label x:Name=""privateLabel"" />
+ <Label x:Name=""internalLabel"" x:FieldModifier=""NotPublic"" />
+ <Label x:Name=""publicLabel"" x:FieldModifier=""Public"" />
+ </StackLayout>
+ </ContentPage>";
+
+ using (var reader = new StringReader(xaml))
+ {
+ string rootType, rootNs;
+ CodeTypeReference baseType;
+ IEnumerable<CodeMemberField> codeMemberFields;
+
+ XamlGTask.ParseXaml(reader, out rootType, out rootNs, out baseType, out codeMemberFields);
+ Assert.That(codeMemberFields.First(cmf => cmf.Name == "privateLabel").Attributes, Is.EqualTo(MemberAttributes.Private));
+ Assert.That(codeMemberFields.First(cmf => cmf.Name == "internalLabel").Attributes, Is.EqualTo(MemberAttributes.Assembly));
+ Assert.That(codeMemberFields.First(cmf => cmf.Name == "publicLabel").Attributes, Is.EqualTo(MemberAttributes.Public));
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.Forms.Xaml/XamlParser.cs b/Xamarin.Forms.Xaml/XamlParser.cs
index eb078597..26936c98 100644
--- a/Xamarin.Forms.Xaml/XamlParser.cs
+++ b/Xamarin.Forms.Xaml/XamlParser.cs
@@ -213,12 +213,13 @@ namespace Xamarin.Forms.Xaml
propertyName = XmlName.xName;
break;
case "x:Class":
+ case "x:FieldModifier":
continue;
default:
Debug.WriteLine("Unhandled attribute {0}", reader.Name);
continue;
}
- }
+ }
if (reader.NamespaceURI == "http://schemas.microsoft.com/winfx/2009/xaml")
{
@@ -237,6 +238,7 @@ namespace Xamarin.Forms.Xaml
propertyName = XmlName.xDataType;
break;
case "x:Class":
+ case "x:FieldModifier":
continue;
case "x:FactoryMethod":
propertyName = XmlName.xFactoryMethod;