From dd85f48c435ab94d6494f6e32219e25061ba47df Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 22 May 2019 12:37:54 +0300 Subject: [PATCH] Update target and declaring types for properties of the root object with x:Class, fixes #2520 --- .../XamlCompilerTaskExecutor.cs | 3 ++- .../AvaloniaXamlIlCompiler.cs | 24 ++++++++++++++--- .../Avalonia.Markup.Xaml/XamlIl/xamlil.github | 2 +- .../Avalonia.Markup.Xaml.UnitTests.csproj | 3 ++- .../Xaml/XamlIlClassWithCustomProperty.xaml | 6 +++++ .../Xaml/XamlIlTests.cs | 26 +++++++++++++++++++ 6 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlClassWithCustomProperty.xaml diff --git a/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs index ec668f2a2b..df840464c1 100644 --- a/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs +++ b/src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs @@ -150,7 +150,8 @@ namespace Avalonia.Build.Tasks classType = typeSystem.TargetAssembly.FindType(tn.Text); if (classType == null) throw new XamlIlParseException($"Unable to find type `{tn.Text}`", classDirective); - initialRoot.Type = new XamlIlAstClrTypeReference(classDirective, classType, false); + compiler.OverrideRootType(parsed, + new XamlIlAstClrTypeReference(classDirective, classType, false)); initialRoot.Children.Remove(classDirective); } diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs index 65149a65de..b84f50fa8d 100644 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlCompiler.cs @@ -112,13 +112,31 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions rootType = new XamlIlAstClrTypeReference(rootObject, overrideRootType, false); } - rootObject.Type = rootType; + OverrideRootType(parsed, rootType); Transform(parsed); Compile(parsed, tb, _contextType, PopulateName, BuildName, "__AvaloniaXamlIlNsInfo", baseUri, fileSource); } - - + + public void OverrideRootType(XamlIlDocument doc, IXamlIlAstTypeReference newType) + { + var root = (XamlIlAstObjectNode)doc.Root; + var oldType = root.Type; + if (oldType.Equals(newType)) + return; + + root.Type = newType; + foreach (var child in root.Children.OfType()) + { + if (child.Property is XamlIlAstNamePropertyReference prop) + { + if (prop.DeclaringType.Equals(oldType)) + prop.DeclaringType = newType; + if (prop.TargetType.Equals(oldType)) + prop.TargetType = newType; + } + } + } } } diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github b/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github index 50920ece52..1e3ffc3154 160000 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github @@ -1 +1 @@ -Subproject commit 50920ece52647b19760f65b417940da125101365 +Subproject commit 1e3ffc315401f0b2eb96a0e79b25c2fc19a80d78 diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj b/tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj index c9eb72757f..3107f4cf22 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj @@ -32,7 +32,8 @@ Designer - + + diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlClassWithCustomProperty.xaml b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlClassWithCustomProperty.xaml new file mode 100644 index 0000000000..330561a2c6 --- /dev/null +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlClassWithCustomProperty.xaml @@ -0,0 +1,6 @@ + + + diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs index 175479e3ff..795aba153a 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs @@ -141,6 +141,22 @@ namespace Avalonia.Markup.Xaml.UnitTests Assert.Equal(20, w.Args.ClickCount); } } + + [Fact] + public void Custom_Properties_Should_Work_With_XClass() + { + var precompiled = new XamlIlClassWithCustomProperty(); + Assert.Equal("123", precompiled.Test); + var loaded = (XamlIlClassWithCustomProperty)AvaloniaXamlLoader.Parse(@" + + +"); + Assert.Equal("321", loaded.Test); + + } } public class XamlIlBugTestsEventHandlerCodeBehind : Window @@ -172,6 +188,16 @@ namespace Avalonia.Markup.Xaml.UnitTests } } + public class XamlIlClassWithCustomProperty : UserControl + { + public string Test { get; set; } + + public XamlIlClassWithCustomProperty() + { + AvaloniaXamlLoader.Load(this); + } + } + public class XamlIlBugTestsBrushToColorConverter : IMultiValueConverter { public object Convert(IList values, Type targetType, object parameter, CultureInfo culture)