Open ds1709 opened 7 months ago
In my local fork I created three unit tests for various scenarios. But I had to add InternalsVisibleTo
attribute in Avalonia.Build.Tasks
project to get access to it's internal classes.
Here's the code:
[Fact]
public void Transform_Does_Not_Fail_For_Object_With_Whitespaces()
{
// <Object>\n\t\n\t\n\t</Object>
var doc = XDocumentXamlParser.Parse("<root/>");
var typeSystem = new CecilTypeSystem(new[]
{
GetType().Assembly.Location,
typeof(void).Assembly.Location,
});
var context = CreateContext(typeSystem, doc);
var objectType = typeSystem.GetType("System.Object");
var node = new XamlAstObjectNode(doc.Root, new XamlAstClrTypeReference(doc.Root, objectType, false));
node.Children.Add(new XamlAstTextNode(doc.Root, "\n\t"));
node.Children.Add(new XamlAstTextNode(doc.Root, "\n\t"));
node.Children.Add(new XamlAstTextNode(doc.Root, "\n\t"));
var transformer = new ResolveContentPropertyTransformer();
transformer.Transform(context, node);
Assert.True(true);
}
[Fact]
public void Transform_Fail_For_Object_With_Content()
{
// <Object><Int32>1<Int32></Object>
var doc = XDocumentXamlParser.Parse("<root/>");
var typeSystem = new CecilTypeSystem(new[]
{
GetType().Assembly.Location,
typeof(void).Assembly.Location,
});
var context = CreateContext(typeSystem, doc);
var objectType = typeSystem.GetType("System.Object");
var intType = typeSystem.GetType("System.Int32");
var node = new XamlAstObjectNode(doc.Root, new XamlAstClrTypeReference(doc.Root, objectType, false));
node.Children.Add(new XamlConstantNode(doc.Root, intType, 1));
var transformer = new ResolveContentPropertyTransformer();
var ex = Assert.Throws<XamlTransformException>(() => transformer.Transform(context, node));
}
[Fact]
public void Transform_Fail_For_Object_With_Content_And_Whitespaces()
{
// <Object>\n\t<Int32>1<Int32>\n\t</Object>
var doc = XDocumentXamlParser.Parse("<root/>");
var typeSystem = new CecilTypeSystem(new[]
{
GetType().Assembly.Location,
typeof(void).Assembly.Location,
});
var context = CreateContext(typeSystem, doc);
var objectType = typeSystem.GetType("System.Object");
var intType = typeSystem.GetType("System.Int32");
var node = new XamlAstObjectNode(doc.Root, new XamlAstClrTypeReference(doc.Root, objectType, false));
node.Children.Add(new XamlAstTextNode(doc.Root, "\n\t"));
node.Children.Add(new XamlConstantNode(doc.Root, intType, 1));
node.Children.Add(new XamlAstTextNode(doc.Root, "\n\t"));
var transformer = new ResolveContentPropertyTransformer();
var ex = Assert.Throws<XamlTransformException>(() => transformer.Transform(context, node));
}
private AstTransformationContext CreateContext(IXamlTypeSystem typeSystem, XamlDocument doc)
{
var thisAssembly = typeSystem.FindAssembly(typeof(ResolveContentPropertyTransformerTest).Assembly.GetName().Name);
var mapping = new XamlLanguageTypeMappings(typeSystem, false);
var compilerConfig = new TransformerConfiguration(typeSystem, thisAssembly, mapping);
return new AstTransformationContext(compilerConfig, doc);
}
Transform_Does_Not_Fail_For_Object_With_Whitespaces: fails. Transform_Fail_For_Object_With_Content: success. Transform_Fail_For_Object_With_Content_And_Whitespaces: fails.
A little more on the topic.
if (adders.Count == 0)
. Why should we continue to handle element in this case?
Describe the bug
There'e multiple scenarios when compilling axaml throws internal compiller error (
ArgumentOutOfRangeException
). This exception occures when you have in source axaml file any xml elements of types which has noContent
property and has no anyAdd
method, but contains any nested elements. I faced with this trying to add objects intoDataGrid
, but it reproduces for other object types.To Reproduce
Scenario 1 (DataGrid):
Scenario 2 (Object):
In both scenarios on compilling:
Expected behavior
Copmpilation error
No Content property or any Add methods found for type <type name>
.Avalonia version
11.1.0-beta1
OS
No response
Additional context
This error occures if object in xaml which has no
Content
property and has no anyAdd
method has nested element(s) and whitespaces. The problem is here (body ofTransform
method):In reproduce scenarios, nested elemnt
<sys:Int32>1<sys:Int32>
is surrounded by indent spaces, so owner element contains three child elements (children count is3
,c
value is2
). In first loop step call ofWhitespaceNormalization.RemoveWhitespaceNodes
removes spaces, so now child count is1
, but loop iterator after decrement is1
. So, next loop step fails onni.Children[c]
.