File: SimplifyTypeExtensionVisitor.cs
Web Access
Project: src\src\Controls\src\Xaml\Controls.Xaml.csproj (Microsoft.Maui.Controls.Xaml)
using System;
using System.Linq;
 
#nullable disable
 
namespace Microsoft.Maui.Controls.Xaml
{
	class SimplifyTypeExtensionVisitor : IXamlNodeVisitor
	{
		public TreeVisitingMode VisitingMode => TreeVisitingMode.BottomUp;
		public bool StopOnDataTemplate => false;
		public bool VisitNodeOnDataTemplate => true;
		public bool StopOnResourceDictionary => false;
		public bool IsResourceDictionary(ElementNode node) => false;
		public bool SkipChildren(INode node, INode parentNode) => false;
 
		public void Visit(ValueNode node, INode parentNode)
		{
		}
 
		public void Visit(MarkupNode node, INode parentNode)
		{
			//markup was already expanded to element
		}
 
		public void Visit(ElementNode node, INode parentNode)
		{
			// Only simplify property setter of TypeExtension and x:Type
			// TargetType="{x:Type typeNameValue}" -> TargetType="typeNameValue"
			// x:DataType="{x:Type typeNameValue}" -> x:DataType="typeNameValue"
 
			if (IsValueOfXDataTypeOrTargetType(node, parentNode, out XmlName propertyName)
				&& IsTypeExtension(node, out ValueNode typeNameValueNode))
			{
				(parentNode as IElementNode).Properties[propertyName] = typeNameValueNode;
			}
 
			static bool IsValueOfXDataTypeOrTargetType(ElementNode node, INode parentNode, out XmlName propertyName)
				=> node.TryGetPropertyName(parentNode, out propertyName)
					&& (IsXDataType(propertyName) || IsTargetTypePropertyOfMauiType(parentNode, propertyName));
 
			static bool IsTargetTypePropertyOfMauiType(INode parentNode, XmlName propertyName)
				=> propertyName == new XmlName("", "TargetType")
					&& parentNode is ElementNode { XmlType: var parentType }
					&& (IsStyle(parentType)
						|| IsTrigger(parentType)
						|| IsDataTrigger(parentType)
						|| IsMultiTrigger(parentType));
 
			static bool IsXDataType(XmlName name) => name == XmlName.xDataType;
			static bool IsStyle(XmlType type) => type.Name == nameof(Style) && type.NamespaceUri == XamlParser.MauiUri;
			static bool IsTrigger(XmlType type) => type.Name == nameof(Trigger) && type.NamespaceUri == XamlParser.MauiUri;
			static bool IsDataTrigger(XmlType type) => type.Name == nameof(DataTrigger) && type.NamespaceUri == XamlParser.MauiUri;
			static bool IsMultiTrigger(XmlType type) => type.Name == nameof(MultiTrigger) && type.NamespaceUri == XamlParser.MauiUri;
 
			static bool IsTypeExtension(ElementNode node, out ValueNode typeNameValueNode)
			{
				if (node.XmlType.Name == nameof(TypeExtension) && node.XmlType.NamespaceUri == XamlParser.X2009Uri)
				{
					XmlName typeNameXmlName = new("", "TypeName");
					if (node.Properties.ContainsKey(typeNameXmlName)
						&& node.Properties[typeNameXmlName] is ValueNode { Value: string } propertyValueNode)
					{
						typeNameValueNode = propertyValueNode;
						return true;
					}
 
					if (node.CollectionItems.Count == 1
						&& node.CollectionItems[0] is ValueNode { Value: string } collectionValueNode)
					{
						typeNameValueNode = collectionValueNode;
						return true;
					}
				}
 
				typeNameValueNode = null;
				return false;
			}
 
		}
 
		public void Visit(RootNode node, INode parentNode)
		{
		}
 
		public void Visit(ListNode node, INode parentNode)
		{
		}
	}
}