--- /dev/null
+<BindableObject xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Xamarin.Forms.Xaml.UnitTests.DuplicatePropertyElements">
+ <BindableObject.BindingContext>0</BindableObject.BindingContext>
+ <BindableObject.BindingContext>0</BindableObject.BindingContext>
+</BindableObject>
--- /dev/null
+using NUnit.Framework;
+
+namespace Xamarin.Forms.Xaml.UnitTests
+{
+ [XamlCompilation(XamlCompilationOptions.Skip)]
+ public partial class DuplicatePropertyElements : BindableObject
+ {
+ public DuplicatePropertyElements(bool useCompiledXaml)
+ {
+ //this stub will be replaced at compile time
+ }
+
+ [TestFixture]
+ public static class Tests
+ {
+ [TestCase(false)]
+ [TestCase(true)]
+ public static void ThrowXamlParseException(bool useCompiledXaml)
+ {
+ Assert.Throws<XamlParseException>(useCompiledXaml ?
+ (TestDelegate)(() => MockCompiler.Compile(typeof(DuplicatePropertyElements))) :
+ () => new DuplicatePropertyElements(useCompiledXaml));
+ }
+ }
+ }
+}
--- /dev/null
+<BindableObject xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:system="clr-namespace:System;assembly=mscorlib.dll" x:Class="Xamarin.Forms.Xaml.UnitTests.DuplicateXArgumentsElements">
+ <BindableObject.BindingContext>
+ <system:Uri>
+ <x:Arguments>https://example.com/</x:Arguments>
+ <x:Arguments>https://example.com/</x:Arguments>
+ </system:Uri>
+ </BindableObject.BindingContext>
+</BindableObject>
--- /dev/null
+using NUnit.Framework;
+
+namespace Xamarin.Forms.Xaml.UnitTests
+{
+ [XamlCompilation(XamlCompilationOptions.Skip)]
+ public partial class DuplicateXArgumentsElements : BindableObject
+ {
+ public DuplicateXArgumentsElements(bool useCompiledXaml)
+ {
+ //this stub will be replaced at compile time
+ }
+
+ [TestFixture]
+ public static class Tests
+ {
+ [TestCase(false)]
+ [TestCase(true)]
+ public static void ThrowXamlParseException(bool useCompiledXaml)
+ {
+ Assert.Throws<XamlParseException>(useCompiledXaml ?
+ (TestDelegate)(() => MockCompiler.Compile(typeof(DuplicateXArgumentsElements))) :
+ () => new DuplicateXArgumentsElements(useCompiledXaml));
+ }
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<BindableObject xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Xamarin.Forms.Xaml.UnitTests.MultipleDataTemplateChildElements">
+ <BindableObject.BindingContext>
+ <DataTemplate>
+ <Page />
+ <Page />
+ </DataTemplate>
+ </BindableObject.BindingContext>
+</BindableObject>
--- /dev/null
+using NUnit.Framework;
+
+namespace Xamarin.Forms.Xaml.UnitTests
+{
+ [XamlCompilation(XamlCompilationOptions.Skip)]
+ public partial class MultipleDataTemplateChildElements : BindableObject
+ {
+ public MultipleDataTemplateChildElements(bool useCompiledXaml)
+ {
+ //this stub will be replaced at compile time
+ }
+
+ [TestFixture]
+ public static class Tests
+ {
+ [TestCase(false)]
+ [TestCase(true)]
+ public static void ThrowXamlParseException(bool useCompiledXaml)
+ {
+ Assert.Throws<XamlParseException>(useCompiledXaml ?
+ (TestDelegate)(() => MockCompiler.Compile(typeof(MultipleDataTemplateChildElements))) :
+ () => new MultipleDataTemplateChildElements(useCompiledXaml));
+ }
+ }
+ }
+}
else //Attached BP
name = new XmlName(reader.NamespaceURI, reader.LocalName);
+ if (node.Properties.ContainsKey(name))
+ throw new XamlParseException($"'{reader.Name}' is a duplicate property name.", (IXmlLineInfo)reader);
+
INode prop = null;
if (reader.IsEmptyElement)
Debug.WriteLine($"Unexpected empty element '<{reader.Name} />'", (IXmlLineInfo)reader);
else
prop = ReadNode(reader);
+
if (prop != null)
node.Properties.Add(name, prop);
}
// 2. Xaml2009 primitives, x:Arguments, ...
else if (reader.NamespaceURI == X2009Uri && reader.LocalName == "Arguments") {
+ if (node.Properties.ContainsKey(XmlName.xArguments))
+ throw new XamlParseException($"'x:Arguments' is a duplicate directive name.", (IXmlLineInfo)reader);
+
var prop = ReadNode(reader);
if (prop != null)
node.Properties.Add(XmlName.xArguments, prop);
// 3. DataTemplate (should be handled by 4.)
else if (node.XmlType.NamespaceUri == XFUri &&
(node.XmlType.Name == "DataTemplate" || node.XmlType.Name == "ControlTemplate")) {
+ if (node.Properties.ContainsKey(XmlName._CreateContent))
+ throw new XamlParseException($"Multiple child elements in {node.XmlType.Name}", (IXmlLineInfo)reader);
+
var prop = ReadNode(reader, true);
if (prop != null)
node.Properties.Add(XmlName._CreateContent, prop);