From 488a556138487411833cdccdaa55532fe8c08c5f Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Fri, 16 Oct 2020 17:09:05 +0200 Subject: [PATCH] fix(XamlFileGenerator): XAML markup extension requires full name #2918 --- .../XamlGenerator/XamlFileGenerator.cs | 29 +++++++++++++------ .../CustomMarkupExtensions.xaml | 11 +++++++ .../CustomMarkupExtensions.xaml.cs | 8 +++++ .../App/Xaml/Test_MarkupExtension.xaml | 11 +++++++ .../App/Xaml/Test_MarkupExtension.xaml.cs | 3 ++ .../Given_MarkupExtension.cs | 5 +++- 6 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs b/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs index 35e0e0e60768..b8e423d0ed3f 100644 --- a/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs +++ b/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs @@ -21,6 +21,7 @@ using System.Runtime.CompilerServices; using Uno.UI.Xaml; + namespace Uno.UI.SourceGenerators.XamlGenerator { internal partial class XamlFileGenerator @@ -1678,20 +1679,27 @@ private bool HasDescendantsWithMarkupExtension(XamlObjectDefinition xamlObjectDe return false; } - private bool IsCustomMarkupExtensionType(XamlType xamlType) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private INamedTypeSymbol? GetMarkupExtensionType(XamlType xamlType) { if (xamlType == null) { - return false; + return null; } // Adjustment for Uno.Xaml parser which returns the namespace in the name var xamlTypeName = xamlType.Name.Contains(':') ? xamlType.Name.Split(':').LastOrDefault() : xamlType.Name; + var extendedXamlTypeName = xamlTypeName + "Extension"; - // Determine if the type is a custom markup extension - return _markupExtensionTypes.Any(ns => ns.Name.Equals(xamlTypeName, StringComparison.InvariantCulture)); + // return the type of custom markup extension + return _markupExtensionTypes.FirstOrDefault(ns => ns.Name.Equals(xamlTypeName, StringComparison.InvariantCulture) + || ns.Name.Equals(extendedXamlTypeName, StringComparison.InvariantCulture)); } + private bool IsCustomMarkupExtensionType(XamlType xamlType) => + // Determine if the type is a custom markup extension + GetMarkupExtensionType(xamlType) != null; + private bool IsXamlTypeConverter(INamedTypeSymbol symbol) { return _xamlConversionTypes.Any(ns => ns.Equals(symbol)); @@ -3604,24 +3612,25 @@ private string GetCustomMarkupExtensionValue(XamlMemberDefinition member) var markupTypeDef = member .Objects .FirstOrDefault(o => IsCustomMarkupExtensionType(o.Type)); - + var markupType = GetMarkupExtensionType(markupTypeDef.Type); // Build a string of all its properties var properties = markupTypeDef .Members .Select(m => { - var resourceName = GetSimpleStaticResourceRetrieval(m); - + var propertyType = markupType.GetAllPropertiesWithName(m.Member.Name)? + .FirstOrDefault()?.Type as INamedTypeSymbol; + var resourceName = GetSimpleStaticResourceRetrieval(m, propertyType); var value = resourceName != null ? resourceName - : BuildLiteralValue(m, owner: member); + : BuildLiteralValue(m, propertyType: propertyType, owner: member); return "{0} = {1}".InvariantCultureFormat(m.Member.Name, value); }) .JoinBy(", "); // Get the full globalized namespaces for the custom markup extension and also for IMarkupExtensionOverrides - var markupType = GetType(markupTypeDef.Type); + var markupTypeFullName = GetGlobalizedTypeName(markupType.GetFullName()); var xamlMarkupFullName = GetGlobalizedTypeName(XamlConstants.Types.IMarkupExtensionOverrides); @@ -4106,6 +4115,8 @@ string Inner() propertyType = propertyType ?? FindPropertyType(member.Member); + + if (propertyType != null) { var s = BuildLiteralValue(propertyType, memberValue, owner, member.Member.Name, objectUid); diff --git a/src/SourceGenerators/XamlGenerationTests/CustomMarkupExtensions.xaml b/src/SourceGenerators/XamlGenerationTests/CustomMarkupExtensions.xaml index 7995f04ed44b..28a847ff9a9d 100644 --- a/src/SourceGenerators/XamlGenerationTests/CustomMarkupExtensions.xaml +++ b/src/SourceGenerators/XamlGenerationTests/CustomMarkupExtensions.xaml @@ -62,6 +62,17 @@ + + + + + + + + + + + diff --git a/src/SourceGenerators/XamlGenerationTests/CustomMarkupExtensions.xaml.cs b/src/SourceGenerators/XamlGenerationTests/CustomMarkupExtensions.xaml.cs index b1f23326b7bc..122c28c26fa7 100644 --- a/src/SourceGenerators/XamlGenerationTests/CustomMarkupExtensions.xaml.cs +++ b/src/SourceGenerators/XamlGenerationTests/CustomMarkupExtensions.xaml.cs @@ -103,6 +103,14 @@ protected override object ProvideValue() } } + public class TestMarkupSuffixExtension : MarkupExtension + { + protected override object ProvideValue() + { + return null; + } + } + public class ComplexObject { public string StringProp { get; set; } diff --git a/src/Uno.UI.Tests/App/Xaml/Test_MarkupExtension.xaml b/src/Uno.UI.Tests/App/Xaml/Test_MarkupExtension.xaml index 30186c9125f5..c7c98ead799f 100644 --- a/src/Uno.UI.Tests/App/Xaml/Test_MarkupExtension.xaml +++ b/src/Uno.UI.Tests/App/Xaml/Test_MarkupExtension.xaml @@ -9,6 +9,7 @@ From a Resource String + From a Resource String FullName @@ -47,6 +48,16 @@ + + + + + + + diff --git a/src/Uno.UI.Tests/App/Xaml/Test_MarkupExtension.xaml.cs b/src/Uno.UI.Tests/App/Xaml/Test_MarkupExtension.xaml.cs index eeabe1337dbd..9543e1b6ce27 100644 --- a/src/Uno.UI.Tests/App/Xaml/Test_MarkupExtension.xaml.cs +++ b/src/Uno.UI.Tests/App/Xaml/Test_MarkupExtension.xaml.cs @@ -32,6 +32,9 @@ public sealed partial class Test_MarkupExtension : UserControl public TextBlock TestText8 => Text8; public TextBlock TestText9 => Text9; public TextBlock TestText10 => Text10; + public TextBlock TestText11 => Text11; + public TextBlock TestText12 => Text12; + public TextBlock TestText13 => Text13; public Test_MarkupExtension() { diff --git a/src/Uno.UI.Tests/Windows_UI_Xaml/MarkupExtensionTests/Given_MarkupExtension.cs b/src/Uno.UI.Tests/Windows_UI_Xaml/MarkupExtensionTests/Given_MarkupExtension.cs index 5b09b6971d8d..f146e3bdc6a2 100644 --- a/src/Uno.UI.Tests/Windows_UI_Xaml/MarkupExtensionTests/Given_MarkupExtension.cs +++ b/src/Uno.UI.Tests/Windows_UI_Xaml/MarkupExtensionTests/Given_MarkupExtension.cs @@ -38,6 +38,9 @@ public void When_ExtensionProvidesValues() Assert.AreEqual(22.0, control.TestText9.FontSize); Assert.AreEqual(3, control.TestText9.MaxLines); Assert.IsInstanceOfType(control.TestText10.DataContext, typeof(TestEntityObject)); + Assert.AreEqual("Just a simple ... fullname markup extension", control.TestText11.Text); + Assert.AreEqual("From a Resource String FullName markup extension", control.TestText12.Text); + Assert.AreEqual("String from attached property Fullname markup extension", control.TestText13.Text); } finally { @@ -47,7 +50,7 @@ public void When_ExtensionProvidesValues() } [MarkupExtensionReturnType(ReturnType = typeof(string))] - public class SimpleMarkupExt : Windows.UI.Xaml.Markup.MarkupExtension + public class SimpleMarkupExtExtension : Windows.UI.Xaml.Markup.MarkupExtension { public string TextValue { get; set; }