Fixd invalid node list produced for deferred members
This commit is contained in:
Родитель
caf3c44e54
Коммит
21b948c95c
|
@ -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>
|
Загрузка…
Ссылка в новой задаче