From 0145dcc4b922591f128c402b3c46dfe2748ba6fd Mon Sep 17 00:00:00 2001 From: Max Katz Date: Sat, 6 May 2023 22:56:27 -0400 Subject: [PATCH] Fix nested ResourceDictionaries --- ...oniaXamlIlThemeVariantProviderTransformer.cs | 10 +++++++++- .../AvaloniaXamlIlWellKnownTypes.cs | 2 ++ .../Xaml/ResourceDictionaryTests.cs | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlThemeVariantProviderTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlThemeVariantProviderTransformer.cs index 05df8be1b6..256a7472f3 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlThemeVariantProviderTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlThemeVariantProviderTransformer.cs @@ -10,7 +10,8 @@ internal class AvaloniaXamlIlThemeVariantProviderTransformer : IXamlAstTransform { public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) { - var type = context.GetAvaloniaTypes().IThemeVariantProvider; + var avTypes = context.GetAvaloniaTypes(); + var type = avTypes.IThemeVariantProvider; if (!(node is XamlAstObjectNode on && type.IsAssignableFrom(on.Type.GetClrType()))) return node; @@ -21,6 +22,13 @@ internal class AvaloniaXamlIlThemeVariantProviderTransformer : IXamlAstTransform if (keyDirective is null) return node; + var themeDictionariesColl = avTypes.IDictionaryT.MakeGenericType(avTypes.ThemeVariant, avTypes.IThemeVariantProvider); + if (context.ParentNodes().FirstOrDefault() is not XamlAstXamlPropertyValueNode propertyValueNode + || !themeDictionariesColl.IsAssignableFrom(propertyValueNode.Property.GetClrProperty().Getter.ReturnType)) + { + return node; + } + var keyProp = type.Properties.First(p => p.Name == "Key"); on.Children.Add(new XamlAstXamlPropertyValueNode(keyDirective, new XamlAstClrProperty(keyDirective, keyProp, context.Configuration), diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs index b5c0c7734d..c5c3cdd123 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs @@ -65,6 +65,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers public IXamlType Int { get; } public IXamlType Long { get; } public IXamlType Uri { get; } + public IXamlType IDictionaryT { get; } public IXamlType FontFamily { get; } public IXamlConstructor FontFamilyConstructorUriName { get; } public IXamlType Thickness { get; } @@ -194,6 +195,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers Int = cfg.TypeSystem.GetType("System.Int32"); Long = cfg.TypeSystem.GetType("System.Int64"); Uri = cfg.TypeSystem.GetType("System.Uri"); + IDictionaryT = cfg.TypeSystem.GetType("System.Collections.Generic.IDictionary`2"); FontFamily = cfg.TypeSystem.GetType("Avalonia.Media.FontFamily"); FontFamilyConstructorUriName = FontFamily.GetConstructor(new List { Uri, XamlIlTypes.String }); ThemeVariant = cfg.TypeSystem.GetType("Avalonia.Styling.ThemeVariant"); diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/ResourceDictionaryTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/ResourceDictionaryTests.cs index e73ef456af..b1b7a74dd3 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/ResourceDictionaryTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/ResourceDictionaryTests.cs @@ -385,6 +385,23 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml Assert.Equal(Colors.Blue, ((ISolidColorBrush)userControl.FindResource("brush")!).Color); } + [Fact] + public void ResourceDictionary_Can_Be_Put_Inside_Of_ResourceDictionary() + { + using (StyledWindow()) + { + var xaml = @" + + +"; + var resources = (ResourceDictionary)AvaloniaRuntimeXamlLoader.Load(xaml); + var nested = (ResourceDictionary)resources["NotAThemeVariantKey"]; + + Assert.NotNull(nested); + } + } + private IDisposable StyledWindow(params (string, string)[] assets) { var services = TestServices.StyledWindow.With(