Repository: AvaloniaUI/Avalonia
File: src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/XDataTypeTransformer.cs (C#)

Code before:
        /// Converts x:DataType directives to regular DataType assignments if property with Avalonia.Metadata.DataTypeAttribute exists.
        /// </summary>
        /// <returns></returns>
        public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
        {
            if (node is XamlAstObjectNode on)
            {
                for (var c = 0; c < on.Children.Count; c++)
                {
                    var ch = on.Children[c];
                    if (ch is XamlAstXmlDirective { Namespace: XamlNamespaces.Xaml2006, Name: DataTypePropertyName } d)
                    {
                        if (on.Children.OfType<XamlAstXamlPropertyValueNode>()
                            .Any(p => ((XamlAstNamePropertyReference)p.Property)?.Name == DataTypePropertyName))
                        {
                            // Break iteration if any DataType property was already set by user code.
                            break;
                        }
                        
                        var templateDataTypeAttribute = context.GetAvaloniaTypes().DataTypeAttribute;

                        var clrType = on.Type switch
                        {
                            XamlAstClrTypeReference clrRef => clrRef.Type,
                            XamlAstXmlTypeReference xmlRef => TypeReferenceResolver.ResolveType(context, xmlRef.Name,
                                on.Type.IsMarkupExtension, on, strict: false).Type,
                            _ => null
                        };
                        if (clrType is null)
                        {
                            break;
                        }

                        // Technically it's possible to map "x:DataType" to a property with [DataType] attribute regardless of its name,
                        // but we go explicitly strict here and check the name as well.
                        var (declaringType, dataTypeProperty) = GetAllProperties(clrType)
                            .FirstOrDefault(t => t.property.Name == DataTypePropertyName && t.property.CustomAttributes
                                .Any(a => a.Type == templateDataTypeAttribute));
                       
                        if (dataTypeProperty is not null)
                        {
                            on.Children[c] = new XamlAstXamlPropertyValueNode(d,
                                new XamlAstNamePropertyReference(d,
                                    new XamlAstClrTypeReference(ch, declaringType, false), dataTypeProperty.Name,
                                    on.Type),
                                d.Values);
                        }
                    }
                }
            }


Review comment (refactor):
@kekekeks I am not sure if it's a good idea to resolve type on this step. 
I tried to move this transformer to a later step, when we operate with previously resolved CLR types, but Xml directives are nonexistent on that step.

Code after:
        /// Converts x:DataType directives to regular DataType assignments if property with Avalonia.Metadata.DataTypeAttribute exists.
        /// </summary>
        /// <returns></returns>
        public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
        {
            if (node is XamlAstObjectNode on)
            {
                for (var c = 0; c < on.Children.Count; c++)
                {
                    var ch = on.Children[c];
                    if (ch is XamlAstXmlDirective { Namespace: XamlNamespaces.Xaml2006, Name: DataTypePropertyName } d)
                    {
                        if (on.Children.OfType<XamlAstXamlPropertyValueNode>()
                            .Any(p => ((XamlAstNamePropertyReference)p.Property)?.Name == DataTypePropertyName))
                        {
                            // Break iteration if any DataType property was already set by user code.
                            break;
                        }
                        
                        var templateDataTypeAttribute = context.GetAvaloniaTypes().DataTypeAttribute;

                        var clrType = (on.Type as XamlAstClrTypeReference)?.Type;
                        if (clrType is null)
                        {
                            break;
                        }

                        // Technically it's possible to map "x:DataType" to a property with [DataType] attribute regardless of its name,
                        // but we go explicitly strict here and check the name as well.
                        var (declaringType, dataTypeProperty) = GetAllProperties(clrType)
                            .FirstOrDefault(t => t.property.Name == DataTypePropertyName && t.property.CustomAttributes
                                .Any(a => a.Type == templateDataTypeAttribute));
                       
                        if (dataTypeProperty is not null)
                        {
                            on.Children[c] = new XamlAstXamlPropertyValueNode(d,
                                new XamlAstNamePropertyReference(d,
                                    new XamlAstClrTypeReference(ch, declaringType, false), dataTypeProperty.Name,
                                    on.Type),
                                d.Values);
                        }
                    }
                }
            }

            return node;
        }
        
        private static IEnumerable<(IXamlType declaringType, IXamlProperty property)> GetAllProperties(IXamlType t)
        {
            foreach (var p in t.Properties)