From 65508e7789c1dea1a62ea71b939048e63eb18929 Mon Sep 17 00:00:00 2001 From: Stephane Delcroix Date: Fri, 8 Sep 2023 16:35:26 +0200 Subject: [PATCH] [X] don't expant types to Extension for x:Static if a type name exists with an Extension suffix, xaml rules require us to use that. But not for x:Static - fixes #11833 --- .../CompiledMarkupExtensions/StaticExtension.cs | 2 +- .../src/Build.Tasks/ExpandMarkupsVisitor.cs | 2 +- src/Controls/src/Build.Tasks/XmlTypeExtensions.cs | 14 +++++++------- src/Controls/src/Core/IXamlTypeResolver.cs | 2 +- .../PublicAPI/net-android/PublicAPI.Shipped.txt | 2 +- .../Core/PublicAPI/net-ios/PublicAPI.Shipped.txt | 2 +- .../net-maccatalyst/PublicAPI.Shipped.txt | 2 +- .../Core/PublicAPI/net-tizen/PublicAPI.Shipped.txt | 2 +- .../PublicAPI/net-windows/PublicAPI.Shipped.txt | 2 +- .../src/Core/PublicAPI/net/PublicAPI.Shipped.txt | 2 +- .../PublicAPI/netstandard/PublicAPI.Shipped.txt | 2 +- src/Controls/src/Xaml/ApplyPropertiesVisitor.cs | 2 +- src/Controls/src/Xaml/CreateValuesVisitor.cs | 2 +- .../src/Xaml/MarkupExtensions/StaticExtension.cs | 2 +- src/Controls/src/Xaml/XamlParser.cs | 9 +++++++-- src/Controls/src/Xaml/XamlServiceProvider.cs | 14 +++++++------- src/Controls/src/Xaml/XmlTypeXamlExtensions.cs | 5 +++-- src/Controls/tests/Xaml.UnitTests/LoaderTests.cs | 2 +- 18 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/Controls/src/Build.Tasks/CompiledMarkupExtensions/StaticExtension.cs b/src/Controls/src/Build.Tasks/CompiledMarkupExtensions/StaticExtension.cs index 76d23cffc4ac..55b1d4d6a403 100644 --- a/src/Controls/src/Build.Tasks/CompiledMarkupExtensions/StaticExtension.cs +++ b/src/Controls/src/Build.Tasks/CompiledMarkupExtensions/StaticExtension.cs @@ -24,7 +24,7 @@ public IEnumerable ProvideValue(IElementNode node, ModuleDefinition var typename = member.Substring(0, dotIdx); var membername = member.Substring(dotIdx + 1); - var typeRef = module.ImportReference(XmlTypeExtensions.GetTypeReference(context.Cache, typename, module, node as BaseNode)); + var typeRef = module.ImportReference(XmlTypeExtensions.GetTypeReference(context.Cache, typename, module, node as BaseNode, expandToExtension: false)); var fieldRef = GetFieldReference(context.Cache, typeRef, membername, module); var propertyDef = GetPropertyDefinition(context.Cache, typeRef, membername, module); diff --git a/src/Controls/src/Build.Tasks/ExpandMarkupsVisitor.cs b/src/Controls/src/Build.Tasks/ExpandMarkupsVisitor.cs index 824697d7298b..2aa8034e939b 100644 --- a/src/Controls/src/Build.Tasks/ExpandMarkupsVisitor.cs +++ b/src/Controls/src/Build.Tasks/ExpandMarkupsVisitor.cs @@ -190,7 +190,7 @@ public INode Parse(string match, ref string remaining, IServiceProvider serviceP //The order of lookup is to look for the Extension-suffixed class name first and then look for the class name without the Extension suffix. XmlType type = new XmlType(namespaceuri, name + "Extension", typeArguments); - if (!type.TryGetTypeReference(contextProvider.Context.Cache, contextProvider.Context.Module, null, out _)) + if (!type.TryGetTypeReference(contextProvider.Context.Cache, contextProvider.Context.Module, null, expandToExtension: true, out _)) type = new XmlType(namespaceuri, name, typeArguments); if (type == null) diff --git a/src/Controls/src/Build.Tasks/XmlTypeExtensions.cs b/src/Controls/src/Build.Tasks/XmlTypeExtensions.cs index de34074a2742..f11ac9eb3b88 100644 --- a/src/Controls/src/Build.Tasks/XmlTypeExtensions.cs +++ b/src/Controls/src/Build.Tasks/XmlTypeExtensions.cs @@ -50,12 +50,12 @@ static IList GatherXmlnsDefinitionAttributes(ModuleDef return xmlnsDefinitions; } - public static TypeReference GetTypeReference(XamlCache cache, string typeName, ModuleDefinition module, BaseNode node) + public static TypeReference GetTypeReference(XamlCache cache, string typeName, ModuleDefinition module, BaseNode node, bool expandToExtension = true) { try { XmlType xmlType = TypeArgumentsParser.ParseSingle(typeName, node.NamespaceResolver, (IXmlLineInfo)node); - return GetTypeReference(xmlType, cache, module, node as IXmlLineInfo); + return GetTypeReference(xmlType, cache, module, node as IXmlLineInfo, expandToExtension: expandToExtension); } catch (XamlParseException) { @@ -63,12 +63,12 @@ public static TypeReference GetTypeReference(XamlCache cache, string typeName, M } } - public static TypeReference GetTypeReference(XamlCache cache, string namespaceURI, string typename, ModuleDefinition module, IXmlLineInfo xmlInfo) + public static TypeReference GetTypeReference(XamlCache cache, string namespaceURI, string typename, ModuleDefinition module, IXmlLineInfo xmlInfo, bool expandToExtension = true) { return new XmlType(namespaceURI, typename, null).GetTypeReference(cache, module, xmlInfo); } - public static bool TryGetTypeReference(this XmlType xmlType, XamlCache cache, ModuleDefinition module, IXmlLineInfo xmlInfo, out TypeReference typeReference) + public static bool TryGetTypeReference(this XmlType xmlType, XamlCache cache, ModuleDefinition module, IXmlLineInfo xmlInfo, bool expandToExtension, out TypeReference typeReference) { IList xmlnsDefinitions = cache.GetXmlsDefinitions(module, GatherXmlnsDefinitionAttributes); @@ -81,7 +81,7 @@ public static bool TryGetTypeReference(this XmlType xmlType, XamlCache cache, Mo if (type is not null && type.IsPublicOrVisibleInternal(module)) return type; return null; - }); + }, expandToExtension: expandToExtension); if (type != null && typeArguments != null && type.HasGenericParameters) type = module.ImportReference(type).MakeGenericInstanceType(typeArguments.Select(x => x.GetTypeReference(cache, module, xmlInfo)).ToArray()); @@ -89,9 +89,9 @@ public static bool TryGetTypeReference(this XmlType xmlType, XamlCache cache, Mo return (typeReference = (type == null) ? null : module.ImportReference(type)) != null; } - public static TypeReference GetTypeReference(this XmlType xmlType, XamlCache cache, ModuleDefinition module, IXmlLineInfo xmlInfo) + public static TypeReference GetTypeReference(this XmlType xmlType, XamlCache cache, ModuleDefinition module, IXmlLineInfo xmlInfo, bool expandToExtension = true) { - if (TryGetTypeReference(xmlType, cache, module, xmlInfo, out TypeReference typeReference)) + if (TryGetTypeReference(xmlType, cache, module, xmlInfo, expandToExtension: expandToExtension, out TypeReference typeReference)) return typeReference; throw new BuildException(BuildExceptionCode.TypeResolution, xmlInfo, null, $"{xmlType.NamespaceUri}:{xmlType.Name}"); diff --git a/src/Controls/src/Core/IXamlTypeResolver.cs b/src/Controls/src/Core/IXamlTypeResolver.cs index 49c3e175d499..00b6c97f410e 100644 --- a/src/Controls/src/Core/IXamlTypeResolver.cs +++ b/src/Controls/src/Core/IXamlTypeResolver.cs @@ -5,7 +5,7 @@ namespace Microsoft.Maui.Controls.Xaml { public interface IXamlTypeResolver { - Type Resolve(string qualifiedTypeName, IServiceProvider serviceProvider = null); + Type Resolve(string qualifiedTypeName, IServiceProvider serviceProvider = null, bool expandToExtension = true); bool TryResolve(string qualifiedTypeName, out Type type); } } \ No newline at end of file diff --git a/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Shipped.txt b/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Shipped.txt index bc6e0632fd8e..c01273697fcc 100644 --- a/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Shipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Shipped.txt @@ -1888,7 +1888,7 @@ ~Microsoft.Maui.Controls.Xaml.IReferenceProvider.FindByName(string name) -> object ~Microsoft.Maui.Controls.Xaml.IRootObjectProvider.RootObject.get -> object ~Microsoft.Maui.Controls.Xaml.IValueProvider.ProvideValue(System.IServiceProvider serviceProvider) -> object -~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null) -> System.Type +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null, bool expandToExtension = true) -> System.Type ~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.TryResolve(string qualifiedTypeName, out System.Type type) -> bool ~Microsoft.Maui.Controls.Xaml.IXmlLineInfoProvider.XmlLineInfo.get -> System.Xml.IXmlLineInfo ~Microsoft.Maui.Controls.Xaml.XamlParseException.XamlParseException(string message, System.Exception innerException) -> void diff --git a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Shipped.txt b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Shipped.txt index 92ab1bbb6309..4247067c3a07 100644 --- a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Shipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Shipped.txt @@ -1847,7 +1847,7 @@ ~Microsoft.Maui.Controls.Xaml.IReferenceProvider.FindByName(string name) -> object ~Microsoft.Maui.Controls.Xaml.IRootObjectProvider.RootObject.get -> object ~Microsoft.Maui.Controls.Xaml.IValueProvider.ProvideValue(System.IServiceProvider serviceProvider) -> object -~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null) -> System.Type +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null, bool expandToExtension = true) -> System.Type ~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.TryResolve(string qualifiedTypeName, out System.Type type) -> bool ~Microsoft.Maui.Controls.Xaml.IXmlLineInfoProvider.XmlLineInfo.get -> System.Xml.IXmlLineInfo ~Microsoft.Maui.Controls.Xaml.XamlParseException.XamlParseException(string message, System.Exception innerException) -> void diff --git a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Shipped.txt b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Shipped.txt index 92ab1bbb6309..4247067c3a07 100644 --- a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Shipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Shipped.txt @@ -1847,7 +1847,7 @@ ~Microsoft.Maui.Controls.Xaml.IReferenceProvider.FindByName(string name) -> object ~Microsoft.Maui.Controls.Xaml.IRootObjectProvider.RootObject.get -> object ~Microsoft.Maui.Controls.Xaml.IValueProvider.ProvideValue(System.IServiceProvider serviceProvider) -> object -~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null) -> System.Type +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null, bool expandToExtension = true) -> System.Type ~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.TryResolve(string qualifiedTypeName, out System.Type type) -> bool ~Microsoft.Maui.Controls.Xaml.IXmlLineInfoProvider.XmlLineInfo.get -> System.Xml.IXmlLineInfo ~Microsoft.Maui.Controls.Xaml.XamlParseException.XamlParseException(string message, System.Exception innerException) -> void diff --git a/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Shipped.txt b/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Shipped.txt index ba7dcea67a25..682bb70e18ff 100644 --- a/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Shipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Shipped.txt @@ -1666,7 +1666,7 @@ ~Microsoft.Maui.Controls.Xaml.IReferenceProvider.FindByName(string name) -> object ~Microsoft.Maui.Controls.Xaml.IRootObjectProvider.RootObject.get -> object ~Microsoft.Maui.Controls.Xaml.IValueProvider.ProvideValue(System.IServiceProvider serviceProvider) -> object -~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null) -> System.Type +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null, bool expandToExtension = true) -> System.Type ~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.TryResolve(string qualifiedTypeName, out System.Type type) -> bool ~Microsoft.Maui.Controls.Xaml.IXmlLineInfoProvider.XmlLineInfo.get -> System.Xml.IXmlLineInfo ~Microsoft.Maui.Controls.Xaml.XamlParseException.XamlParseException(string message, System.Exception innerException) -> void diff --git a/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Shipped.txt b/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Shipped.txt index bc3a72d2f293..1dc995450c21 100644 --- a/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Shipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Shipped.txt @@ -1736,7 +1736,7 @@ ~Microsoft.Maui.Controls.Xaml.IReferenceProvider.FindByName(string name) -> object ~Microsoft.Maui.Controls.Xaml.IRootObjectProvider.RootObject.get -> object ~Microsoft.Maui.Controls.Xaml.IValueProvider.ProvideValue(System.IServiceProvider serviceProvider) -> object -~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null) -> System.Type +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null, bool expandToExtension = true) -> System.Type ~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.TryResolve(string qualifiedTypeName, out System.Type type) -> bool ~Microsoft.Maui.Controls.Xaml.IXmlLineInfoProvider.XmlLineInfo.get -> System.Xml.IXmlLineInfo ~Microsoft.Maui.Controls.Xaml.XamlParseException.XamlParseException(string message, System.Exception innerException) -> void diff --git a/src/Controls/src/Core/PublicAPI/net/PublicAPI.Shipped.txt b/src/Controls/src/Core/PublicAPI/net/PublicAPI.Shipped.txt index 3792b5f9c96a..fa569a7d99e9 100644 --- a/src/Controls/src/Core/PublicAPI/net/PublicAPI.Shipped.txt +++ b/src/Controls/src/Core/PublicAPI/net/PublicAPI.Shipped.txt @@ -1662,7 +1662,7 @@ ~Microsoft.Maui.Controls.Xaml.IReferenceProvider.FindByName(string name) -> object ~Microsoft.Maui.Controls.Xaml.IRootObjectProvider.RootObject.get -> object ~Microsoft.Maui.Controls.Xaml.IValueProvider.ProvideValue(System.IServiceProvider serviceProvider) -> object -~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null) -> System.Type +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null, bool expandToExtension = true) -> System.Type ~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.TryResolve(string qualifiedTypeName, out System.Type type) -> bool ~Microsoft.Maui.Controls.Xaml.IXmlLineInfoProvider.XmlLineInfo.get -> System.Xml.IXmlLineInfo ~Microsoft.Maui.Controls.Xaml.XamlParseException.XamlParseException(string message, System.Exception innerException) -> void diff --git a/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Shipped.txt b/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Shipped.txt index 3792b5f9c96a..fa569a7d99e9 100644 --- a/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Shipped.txt +++ b/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Shipped.txt @@ -1662,7 +1662,7 @@ ~Microsoft.Maui.Controls.Xaml.IReferenceProvider.FindByName(string name) -> object ~Microsoft.Maui.Controls.Xaml.IRootObjectProvider.RootObject.get -> object ~Microsoft.Maui.Controls.Xaml.IValueProvider.ProvideValue(System.IServiceProvider serviceProvider) -> object -~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null) -> System.Type +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, System.IServiceProvider serviceProvider = null, bool expandToExtension = true) -> System.Type ~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.TryResolve(string qualifiedTypeName, out System.Type type) -> bool ~Microsoft.Maui.Controls.Xaml.IXmlLineInfoProvider.XmlLineInfo.get -> System.Xml.IXmlLineInfo ~Microsoft.Maui.Controls.Xaml.XamlParseException.XamlParseException(string message, System.Exception innerException) -> void diff --git a/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs b/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs index 0b810b3879bd..7cbefa087b30 100644 --- a/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs +++ b/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs @@ -306,7 +306,7 @@ static bool GetRealNameAndType(ref Type elementType, string namespaceURI, ref st localname = localname.Substring(dotIdx + 1); XamlParseException xpe; elementType = XamlParser.GetElementType(new XmlType(namespaceURI, typename, null), lineInfo, - rootElement.GetType().Assembly, out xpe); + rootElement.GetType().Assembly, true, out xpe); if (xpe != null) throw xpe; diff --git a/src/Controls/src/Xaml/CreateValuesVisitor.cs b/src/Controls/src/Xaml/CreateValuesVisitor.cs index a7460a9fc0bb..903d0585ea37 100644 --- a/src/Controls/src/Xaml/CreateValuesVisitor.cs +++ b/src/Controls/src/Xaml/CreateValuesVisitor.cs @@ -48,7 +48,7 @@ public void Visit(ElementNode node, INode parentNode) { object value = null; - var type = XamlParser.GetElementType(node.XmlType, node, Context.RootElement?.GetType().Assembly, + var type = XamlParser.GetElementType(node.XmlType, node, Context.RootElement?.GetType().Assembly, true, out XamlParseException xpe); if (xpe != null) { diff --git a/src/Controls/src/Xaml/MarkupExtensions/StaticExtension.cs b/src/Controls/src/Xaml/MarkupExtensions/StaticExtension.cs index 6f878f2e04bf..cdcdc6708966 100644 --- a/src/Controls/src/Xaml/MarkupExtensions/StaticExtension.cs +++ b/src/Controls/src/Xaml/MarkupExtensions/StaticExtension.cs @@ -26,7 +26,7 @@ public object ProvideValue(IServiceProvider serviceProvider) var typename = Member.Substring(0, dotIdx); var membername = Member.Substring(dotIdx + 1); - var type = typeResolver.Resolve(typename, serviceProvider); + var type = typeResolver.Resolve(typename, serviceProvider, expandToExtension: false); var pinfo = type.GetRuntimeProperties().FirstOrDefault(pi => pi.Name == membername && pi.GetMethod.IsStatic); if (pinfo != null) diff --git a/src/Controls/src/Xaml/XamlParser.cs b/src/Controls/src/Xaml/XamlParser.cs index fb00409662f6..40fd328eddea 100644 --- a/src/Controls/src/Xaml/XamlParser.cs +++ b/src/Controls/src/Xaml/XamlParser.cs @@ -357,11 +357,15 @@ static void GatherXmlnsDefinitionAttributes() } } +<<<<<<< HEAD [RequiresUnreferencedCode(TrimmerConstants.XamlRuntimeParsingNotSupportedWarning)] #if !NETSTANDARD [RequiresDynamicCode(TrimmerConstants.XamlRuntimeParsingNotSupportedWarning)] #endif public static Type GetElementType(XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly, +======= + public static Type GetElementType(XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly, bool expandToExtension, +>>>>>>> 4c8c9eadfe ([X] don't expant types to Extension for x:Static) out XamlParseException exception) { bool hasRetriedNsSearch = false; @@ -379,7 +383,8 @@ public static Type GetElementType(XmlType xmlType, IXmlLineInfo xmlInfo, Assembl if (t is not null && t.IsPublicOrVisibleInternal(currentAssembly)) return t; return null; - }); + }, + expandToExtension); var typeArguments = xmlType.TypeArguments; exception = null; @@ -403,7 +408,7 @@ public static Type GetElementType(XmlType xmlType, IXmlLineInfo xmlInfo, Assembl XamlParseException innerexception = null; var args = typeArguments.Select(delegate (XmlType xmltype) { - var t = GetElementType(xmltype, xmlInfo, currentAssembly, out XamlParseException xpe); + var t = GetElementType(xmltype, xmlInfo, currentAssembly, true, out XamlParseException xpe); if (xpe != null) { innerexception = xpe; diff --git a/src/Controls/src/Xaml/XamlServiceProvider.cs b/src/Controls/src/Xaml/XamlServiceProvider.cs index f69c958fe0fb..49b62bb23ade 100644 --- a/src/Controls/src/Xaml/XamlServiceProvider.cs +++ b/src/Controls/src/Xaml/XamlServiceProvider.cs @@ -207,9 +207,9 @@ internal XamlTypeResolver(IXmlNamespaceResolver namespaceResolver, GetTypeFromXm this.getTypeFromXmlName = getTypeFromXmlName ?? throw new ArgumentNullException(); } - Type IXamlTypeResolver.Resolve(string qualifiedTypeName, IServiceProvider serviceProvider) + Type IXamlTypeResolver.Resolve(string qualifiedTypeName, IServiceProvider serviceProvider, bool expandToExtension) { - var type = Resolve(qualifiedTypeName, serviceProvider, out XamlParseException e); + var type = Resolve(qualifiedTypeName, serviceProvider, expandToExtension: expandToExtension, out XamlParseException e); if (e != null) throw e; return type; @@ -217,18 +217,18 @@ Type IXamlTypeResolver.Resolve(string qualifiedTypeName, IServiceProvider servic bool IXamlTypeResolver.TryResolve(string qualifiedTypeName, out Type type) { - type = Resolve(qualifiedTypeName, null, out XamlParseException exception); + type = Resolve(qualifiedTypeName, null, true, out XamlParseException exception); return exception == null; } internal bool TryResolve(XmlType xmlType, out Type type) { XamlParseException exception; - type = getTypeFromXmlName(xmlType, null, currentAssembly, out exception); + type = getTypeFromXmlName(xmlType, null, currentAssembly, true, out exception); return exception == null; } - Type Resolve(string qualifiedTypeName, IServiceProvider serviceProvider, out XamlParseException exception) + Type Resolve(string qualifiedTypeName, IServiceProvider serviceProvider, bool expandToExtension, out XamlParseException exception) { IXmlLineInfo xmlLineInfo = null; if (serviceProvider != null) @@ -238,10 +238,10 @@ Type Resolve(string qualifiedTypeName, IServiceProvider serviceProvider, out Xam } var xmlType = TypeArgumentsParser.ParseSingle(qualifiedTypeName, namespaceResolver, xmlLineInfo); - return getTypeFromXmlName(xmlType, xmlLineInfo, currentAssembly, out exception); + return getTypeFromXmlName(xmlType, xmlLineInfo, currentAssembly, expandToExtension, out exception); } - internal delegate Type GetTypeFromXmlName(XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly, out XamlParseException exception); + internal delegate Type GetTypeFromXmlName(XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly, bool expandToExtension, out XamlParseException exception); } class XamlRootObjectProvider : IRootObjectProvider diff --git a/src/Controls/src/Xaml/XmlTypeXamlExtensions.cs b/src/Controls/src/Xaml/XmlTypeXamlExtensions.cs index bc30f025d49b..3b681ff1e755 100644 --- a/src/Controls/src/Xaml/XmlTypeXamlExtensions.cs +++ b/src/Controls/src/Xaml/XmlTypeXamlExtensions.cs @@ -37,7 +37,8 @@ static class XmlTypeXamlExtensions this XmlType xmlType, IEnumerable xmlnsDefinitions, string defaultAssemblyName, - Func<(string typeName, string clrNamespace, string assemblyName), T> refFromTypeInfo) + Func<(string typeName, string clrNamespace, string assemblyName), T> refFromTypeInfo, + bool expandToExtension = true) where T : class { var lookupAssemblies = new List(); @@ -61,7 +62,7 @@ static class XmlTypeXamlExtensions } var lookupNames = new List(capacity: 2); - if (elementName != "DataTemplate" && !elementName.EndsWith("Extension", StringComparison.Ordinal)) + if (expandToExtension && elementName != "DataTemplate" && !elementName.EndsWith("Extension", StringComparison.Ordinal)) lookupNames.Add(elementName + "Extension"); lookupNames.Add(elementName); diff --git a/src/Controls/tests/Xaml.UnitTests/LoaderTests.cs b/src/Controls/tests/Xaml.UnitTests/LoaderTests.cs index 4ad6d3d0376f..995c78e1172b 100644 --- a/src/Controls/tests/Xaml.UnitTests/LoaderTests.cs +++ b/src/Controls/tests/Xaml.UnitTests/LoaderTests.cs @@ -792,7 +792,7 @@ public void StyleWithoutTargetTypeThrows() public void BindingIsResolvedAsBindingExtension() // https://github.com/xamarin/Microsoft.Maui.Controls/issues/3606#issuecomment-422377338 { - var bindingType = XamlParser.GetElementType(new XmlType("http://schemas.microsoft.com/dotnet/2021/maui", "Binding", null), null, null, out var ex); + var bindingType = XamlParser.GetElementType(new XmlType("http://schemas.microsoft.com/dotnet/2021/maui", "Binding", null), null, null, true, out var ex); Assert.That(ex, Is.Null); Assert.That(bindingType, Is.EqualTo(typeof(BindingExtension))); var module = ModuleDefinition.CreateModule("foo", new ModuleParameters()