Fixd invalid node list produced for deferred members

This commit is contained in:
Yaroslav Bugaria 2018-05-22 02:38:37 +03:00
Родитель caf3c44e54
Коммит 21b948c95c
6 изменённых файлов: 88 добавлений и 3 удалений

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

@ -354,13 +354,14 @@ namespace Portable.Xaml
xt = new XamlType (sti.Namespace, sti.Name, sti.TypeName.TypeArguments?.Select(xxtn => sctx.GetXamlType (xxtn)).ToArray (), sctx);
}
// It could still be GetObject if current_member
// is not a directive and current type is not
// It could still be GetObject if current_member is not defer-loaded, it
// is not a directive, and current type is not
// a markup extension.
// (I'm not very sure about the condition;
// it could be more complex.)
// seealso: bug #682131
if (!ReferenceEquals(currentMember, null)
&& ReferenceEquals(currentMember.DeferringLoader, null)
&& !xt.CanAssignTo(currentMember.Type)
&& !ReferenceEquals(xt, XamlLanguage.Reference)
&& (

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

@ -219,6 +219,7 @@
<Content Include="XmlFiles\DefaultNamespaces_WithDefinedNamespace.xml" />
<Content Include="XmlFiles\DeferredLoadingCollectionContainer.xml" />
<Content Include="XmlFiles\DeferredLoadingContainerMember.xml" />
<Content Include="XmlFiles\DeferredLoadingContainerMember2.xml" />
<Content Include="XmlFiles\DeferredLoadingContainerMemberStringType.xml" />
<Content Include="XmlFiles\DeferredLoadingContainerType.xml" />
<Content Include="XmlFiles\DeferredLoadingWithInvalidType.xml" />

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

@ -1392,8 +1392,23 @@ namespace MonoTests.Portable.Xaml
{
throw new NotImplementedException();
}
}
}
public class TestDeferredLoader<T> : XamlDeferringLoader
{
public override object Load(XamlReader xamlReader, IServiceProvider serviceProvider)
{
var list = new XamlNodeList(xamlReader.SchemaContext);
XamlServices.Transform(xamlReader, list.Writer);
return new Func<T>(() => (T)XamlServices.Load(list.GetReader()));
}
public override XamlReader Save(object value, IServiceProvider serviceProvider)
{
throw new NotImplementedException();
}
}
public class DeferredLoadingChild
{
@ -1416,6 +1431,13 @@ namespace MonoTests.Portable.Xaml
{
[XamlDeferLoad(typeof(TestDeferredLoader), typeof(DeferredLoadingChild))]
public DeferredLoadingChild Child { get; set; }
}
[ContentProperty("Child")]
public class DeferredLoadingContainerMember2
{
[XamlDeferLoad(typeof(TestDeferredLoader<TestClass4>), typeof(TestClass4))]
public Func<TestClass4> Child { get; set; }
}
[ContentProperty("Item")]

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

@ -1787,6 +1787,18 @@ namespace MonoTests.Portable.Xaml
Assert.IsInstanceOf<DeferredLoadingChild>(obj, "#7");
Assert.AreEqual("Blah", ((DeferredLoadingChild)obj).Foo, "#8");
}
}
[Test]
public void Write_DeferredLoadingContainerMember2()
{
using (var xr = GetReader("DeferredLoadingContainerMember2.xml"))
{
var res = (DeferredLoadingContainerMember2)XamlServices.Load(xr);
var obj = res.Child();
Assert.AreEqual("Blah", obj.Foo);
}
}
[Test]

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

@ -1164,5 +1164,51 @@ namespace MonoTests.Portable.Xaml
Assert.IsFalse(reader.Read()); // EOF
}
/// <summary>
/// Tests that a property marked with [XamlDeferLoad] whose actual type is not compatible with the deferred content
/// produces a valid XAML node list.
/// </summary>
[Test]
public void Read_DeferLoadedProperty()
{
var xaml = File.ReadAllText(Compat.GetTestFile("DeferredLoadingContainerMember2.xml")).UpdateXml();
var reader = GetReaderText(xaml);
reader.Read(); // xmlns
Assert.AreEqual(reader.NodeType, XamlNodeType.NamespaceDeclaration);
reader.Read(); // <DeferredLoadingContainerMember2>
Assert.AreEqual(reader.NodeType, XamlNodeType.StartObject);
ReadBase(reader);
reader.Read(); // StartMember
Assert.AreEqual(reader.NodeType, XamlNodeType.StartMember);
reader.Read(); // <DeferredLoadingChild>
Assert.AreEqual(reader.NodeType, XamlNodeType.StartObject);
Assert.AreEqual(reader.Type, reader.SchemaContext.GetXamlType(typeof(TestClass4)));
reader.Read(); // StartMember (Foo)
Assert.AreEqual(reader.NodeType, XamlNodeType.StartMember);
reader.Read(); // "Blah"
Assert.AreEqual(reader.NodeType, XamlNodeType.Value);
reader.Read(); // EndMember
Assert.AreEqual(reader.NodeType, XamlNodeType.EndMember);
reader.Read(); // </DeferredLoadingChild>
Assert.AreEqual(reader.NodeType, XamlNodeType.EndObject);
reader.Read(); // EndMember
Assert.AreEqual(reader.NodeType, XamlNodeType.EndMember);
reader.Read(); // </DeferredLoadingContainerMember2>
Assert.AreEqual(reader.NodeType, XamlNodeType.EndObject);
Assert.IsFalse(reader.Read()); // EOF
}
}
}

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

@ -0,0 +1,3 @@
<DeferredLoadingContainerMember2 xmlns="clr-namespace:MonoTests.Portable.Xaml;assembly=Portable.Xaml_test_net_4_5">
<TestClass4 Foo="Blah"/>
</DeferredLoadingContainerMember2>