Browse Source

Improve type caching in the XAML compiler (#21408)

* Update XamlX

* XAML compiler: cache AvaloniaXamlIlWellKnownTypes per compilation

* XAML compiler: use more well known types

* XAML compiler: replace IXamlType.FullName usages
pull/21419/head
Julien Lebosquain 4 months ago
committed by GitHub
parent
commit
46137bd4a5
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      external/XamlX
  2. 4
      src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
  3. 2
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompilerConfiguration.cs
  4. 29
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs
  5. 11
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs
  6. 2
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AddNameScopeRegistration.cs
  7. 4
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs
  8. 2
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs
  9. 2
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlOptionMarkupExtensionTransformer.cs
  10. 25
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlQueryTransformer.cs
  11. 2
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs
  12. 2
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlResourceTransformer.cs
  13. 16
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSelectorTransformer.cs
  14. 2
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs
  15. 1
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlTransformRoutedEvent.cs
  16. 257
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
  17. 33
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs
  18. 12
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs
  19. 7
      src/tools/Avalonia.Generators/Compiler/NoopTypeSystem.cs
  20. 4
      src/tools/Avalonia.Generators/Compiler/RoslynTypeSystem.cs
  21. 1
      tests/Avalonia.Generators.Tests/MiniCompilerTests.cs
  22. 1
      tests/Avalonia.Generators.Tests/Views/View.cs

2
external/XamlX

@ -1 +1 @@
Subproject commit 009d4815470cf4bf71d1adbb633a5d81dcb2bb52 Subproject commit 86f5a26fadb745e95169c3c805ebd9fd7c9b44d2

4
src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs

@ -458,8 +458,8 @@ namespace Avalonia.Build.Tasks
.Methods.First(m => m.Name == document.TypeBuilderProvider.PopulateMethod.Name); .Methods.First(m => m.Name == document.TypeBuilderProvider.PopulateMethod.Name);
var designLoaderFieldType = typeSystem var designLoaderFieldType = typeSystem
.GetType("System.Action`1") .WellKnownTypes.GetActionOfT(1)
.MakeGenericType(typeSystem.GetType("System.Object")); .MakeGenericType(typeSystem.WellKnownTypes.Object);
var designLoaderFieldTypeReference = (GenericInstanceType)typeSystem.GetTypeReference(designLoaderFieldType); var designLoaderFieldTypeReference = (GenericInstanceType)typeSystem.GetTypeReference(designLoaderFieldType);
designLoaderFieldTypeReference.GenericArguments[0] = designLoaderFieldTypeReference.GenericArguments[0] =

2
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompilerConfiguration.cs

@ -1,3 +1,4 @@
using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers;
using XamlX.Transform; using XamlX.Transform;
using XamlX.TypeSystem; using XamlX.TypeSystem;
@ -28,6 +29,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
AddExtra(ClrPropertyEmitter); AddExtra(ClrPropertyEmitter);
AddExtra(AccessorFactoryEmitter); AddExtra(AccessorFactoryEmitter);
AddExtra(TrampolineBuilder); AddExtra(TrampolineBuilder);
AddExtra(new AvaloniaXamlIlWellKnownTypes(TypeSystem));
} }
} }
} }

29
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs

@ -70,13 +70,16 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
}; };
rv.CustomAttributeResolver = new AttributeResolver(typeSystem, rv); rv.CustomAttributeResolver = new AttributeResolver(typeSystem, rv);
var nameScopeType = typeSystem.GetType("Avalonia.Controls.INameScope");
var eagerParentStackProviderInterfaceType = typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.IAvaloniaXamlIlEagerParentStackProvider");
var emit = new XamlLanguageEmitMappings<IXamlILEmitter, XamlILNodeEmitResult> var emit = new XamlLanguageEmitMappings<IXamlILEmitter, XamlILNodeEmitResult>
{ {
ProvideValueTargetPropertyEmitter = XamlIlAvaloniaPropertyHelper.EmitProvideValueTarget, ProvideValueTargetPropertyEmitter = XamlIlAvaloniaPropertyHelper.EmitProvideValueTarget,
ContextTypeBuilderCallback = definition => ContextTypeBuilderCallback = definition =>
{ {
EmitNameScopeField(rv, typeSystem, definition); EmitNameScopeField(rv, typeSystem, definition, nameScopeType);
EmitEagerParentStackProvider(rv, typeSystem, definition, runtimeHelpers); EmitEagerParentStackProvider(rv, typeSystem, definition, runtimeHelpers, eagerParentStackProviderInterfaceType);
} }
}; };
return (rv, emit); return (rv, emit);
@ -88,9 +91,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
private static void EmitNameScopeField( private static void EmitNameScopeField(
XamlLanguageTypeMappings mappings, XamlLanguageTypeMappings mappings,
IXamlTypeSystem typeSystem, IXamlTypeSystem typeSystem,
IXamlILContextDefinition<IXamlILEmitter> definition) IXamlILContextDefinition<IXamlILEmitter> definition,
IXamlType nameScopeType)
{ {
var nameScopeType = typeSystem.GetType("Avalonia.Controls.INameScope");
var field = definition.TypeBuilder.DefineField(nameScopeType, var field = definition.TypeBuilder.DefineField(nameScopeType,
ContextNameScopeFieldName, XamlVisibility.Public, false); ContextNameScopeFieldName, XamlVisibility.Public, false);
definition.ConstructorBuilder.Generator definition.ConstructorBuilder.Generator
@ -98,7 +101,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
.Ldarg(1) .Ldarg(1)
.Ldtype(nameScopeType) .Ldtype(nameScopeType)
.EmitCall(mappings.ServiceProvider.GetMethod(new FindMethodMethodSignature("GetService", .EmitCall(mappings.ServiceProvider.GetMethod(new FindMethodMethodSignature("GetService",
typeSystem.GetType("System.Object"), typeSystem.GetType("System.Type")))) typeSystem.WellKnownTypes.Object, typeSystem.WellKnownTypes.Type)))
.Stfld(field); .Stfld(field);
} }
@ -107,10 +110,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
XamlLanguageTypeMappings mappings, XamlLanguageTypeMappings mappings,
IXamlTypeSystem typeSystem, IXamlTypeSystem typeSystem,
IXamlILContextDefinition<IXamlILEmitter> definition, IXamlILContextDefinition<IXamlILEmitter> definition,
IXamlType runtimeHelpers) IXamlType runtimeHelpers,
IXamlType interfaceType)
{ {
var interfaceType = typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.IAvaloniaXamlIlEagerParentStackProvider");
definition.TypeBuilder.AddInterfaceImplementation(interfaceType); definition.TypeBuilder.AddInterfaceImplementation(interfaceType);
// IReadOnlyList<object> DirectParentsStack => (IReadOnlyList<object>)ParentsStack; // IReadOnlyList<object> DirectParentsStack => (IReadOnlyList<object>)ParentsStack;
@ -122,8 +124,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
var serviceProviderGetServiceMethod = mappings.ServiceProvider.GetMethod(new FindMethodMethodSignature( var serviceProviderGetServiceMethod = mappings.ServiceProvider.GetMethod(new FindMethodMethodSignature(
"GetService", "GetService",
typeSystem.GetType("System.Object"), typeSystem.WellKnownTypes.Object,
typeSystem.GetType("System.Type"))); typeSystem.WellKnownTypes.Type));
var asEagerParentStackProviderMethod = runtimeHelpers.GetMethod(new FindMethodMethodSignature( var asEagerParentStackProviderMethod = runtimeHelpers.GetMethod(new FindMethodMethodSignature(
"AsEagerParentStackProvider", "AsEagerParentStackProvider",
@ -184,12 +186,11 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
AddType(typeSystem.GetType("Avalonia.Media.IImage"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.BitmapTypeConverter")); AddType(typeSystem.GetType("Avalonia.Media.IImage"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.BitmapTypeConverter"));
AddType(typeSystem.GetType("Avalonia.Media.Imaging.Bitmap"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.BitmapTypeConverter")); AddType(typeSystem.GetType("Avalonia.Media.Imaging.Bitmap"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.BitmapTypeConverter"));
AddType(typeSystem.GetType("Avalonia.Media.IImageBrushSource"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.BitmapTypeConverter")); AddType(typeSystem.GetType("Avalonia.Media.IImageBrushSource"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.BitmapTypeConverter"));
var ilist = typeSystem.GetType("System.Collections.Generic.IList`1"); AddType(typeSystem.WellKnownTypes.IListOfT.MakeGenericType(typeSystem.GetType("Avalonia.Point")),
AddType(ilist.MakeGenericType(typeSystem.GetType("Avalonia.Point")),
typeSystem.GetType("Avalonia.Markup.Xaml.Converters.PointsListTypeConverter")); typeSystem.GetType("Avalonia.Markup.Xaml.Converters.PointsListTypeConverter"));
AddType(typeSystem.GetType("Avalonia.Controls.WindowIcon"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.IconTypeConverter")); AddType(typeSystem.GetType("Avalonia.Controls.WindowIcon"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.IconTypeConverter"));
AddType(typeSystem.GetType("System.Globalization.CultureInfo"), typeSystem.GetType( "System.ComponentModel.CultureInfoConverter")); AddType(typeSystem.GetType("System.Globalization.CultureInfo"), typeSystem.GetType( "System.ComponentModel.CultureInfoConverter"));
AddType(typeSystem.GetType("System.Uri"), typeSystem.GetType( "Avalonia.Markup.Xaml.Converters.AvaloniaUriTypeConverter")); AddType(typeSystem.WellKnownTypes.Uri, typeSystem.GetType( "Avalonia.Markup.Xaml.Converters.AvaloniaUriTypeConverter"));
AddType(typeSystem.GetType("System.TimeSpan"), typeSystem.GetType( "Avalonia.Markup.Xaml.Converters.TimeSpanTypeConverter")); AddType(typeSystem.GetType("System.TimeSpan"), typeSystem.GetType( "Avalonia.Markup.Xaml.Converters.TimeSpanTypeConverter"));
AddType(typeSystem.GetType("Avalonia.Media.FontFamily"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.FontFamilyTypeConverter")); AddType(typeSystem.GetType("Avalonia.Media.FontFamily"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.FontFamilyTypeConverter"));
_avaloniaList = typeSystem.GetType("Avalonia.Collections.AvaloniaList`1"); _avaloniaList = typeSystem.GetType("Avalonia.Collections.AvaloniaList`1");
@ -270,7 +271,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
return true; return true;
} }
if (type.FullName == "Avalonia.AvaloniaProperty") if (type.Is("Avalonia", "AvaloniaProperty"))
{ {
var attrType = context.GetAvaloniaTypes().InheritDataTypeFromAttribute; var attrType = context.GetAvaloniaTypes().InheritDataTypeFromAttribute;
var scopeKind = customAttributes? var scopeKind = customAttributes?

11
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs

@ -39,7 +39,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
return false; return false;
} }
if (type.FullName == "System.TimeSpan") if (type.Is("System", "TimeSpan"))
{ {
var tsText = text.Trim(); var tsText = text.Trim();
@ -348,7 +348,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
} }
// Keep it in the end, so more specific parsers can be applied. // Keep it in the end, so more specific parsers can be applied.
var elementType = GetElementType(type, context.Configuration.WellKnownTypes); var elementType = GetElementType(type);
if (elementType is not null) if (elementType is not null)
{ {
string[] items; string[] items;
@ -445,15 +445,16 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
return false; return false;
} }
private static IXamlType? GetElementType(IXamlType type, XamlTypeWellKnownTypes types) private static IXamlType? GetElementType(IXamlType type)
{ {
if (type.IsArray) if (type.IsArray)
{ {
return type.ArrayElementType; return type.ArrayElementType;
} }
return type.GetAllInterfaces().FirstOrDefault(i => return type.GetAllInterfaces().FirstOrDefault(static i =>
i.FullName.StartsWith(types.IEnumerableT.FullName))? i.Name.StartsWith("IEnumerable`1", StringComparison.Ordinal) &&
i.Namespace == "System.Collections.Generic")?
.GenericArguments[0]; .GenericArguments[0];
} }
} }

2
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AddNameScopeRegistration.cs

@ -16,7 +16,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
if (node is XamlPropertyAssignmentNode pa) if (node is XamlPropertyAssignmentNode pa)
{ {
if (pa.Property.Name == "Name" if (pa.Property.Name == "Name"
&& pa.Property.DeclaringType.Interfaces.Any(t => t.FullName == "Avalonia.INamed")) && pa.Property.DeclaringType.Interfaces.Any(t => t.Is("Avalonia", "INamed")))
{ {
if (context.ParentNodes().FirstOrDefault() is XamlManipulationGroupNode mg if (context.ParentNodes().FirstOrDefault() is XamlManipulationGroupNode mg
&& mg.Children.OfType<AvaloniaNameScopeRegistrationXamlIlNode>().Any()) && mg.Children.OfType<AvaloniaNameScopeRegistrationXamlIlNode>().Any())

4
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs

@ -30,7 +30,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
startType = extension.Type.GetClrType(); startType = extension.Type.GetClrType();
//let's try to infer StaticResource type from parent resources in xaml //let's try to infer StaticResource type from parent resources in xaml
if (extension.Value.Type.GetClrType().FullName == "Avalonia.Markup.Xaml.MarkupExtensions.StaticResourceExtension" && if (extension.Value.Type.GetClrType().Is("Avalonia.Markup.Xaml.MarkupExtensions", "StaticResourceExtension") &&
extension.Value is XamlAstConstructableObjectNode cn && extension.Value is XamlAstConstructableObjectNode cn &&
cn.Arguments.Count == 1 && cn.Arguments[0] is XamlAstTextNode keyNode) cn.Arguments.Count == 1 && cn.Arguments[0] is XamlAstTextNode keyNode)
{ {
@ -56,7 +56,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
{ {
if (propertyNode.Values.Count == 1 && if (propertyNode.Values.Count == 1 &&
propertyNode.Values[0] is XamlAstConstructableObjectNode obj && propertyNode.Values[0] is XamlAstConstructableObjectNode obj &&
obj.Type.GetClrType().FullName == "Avalonia.Controls.ResourceDictionary") obj.Type.GetClrType().Is("Avalonia.Controls", "ResourceDictionary"))
{ {
foreach (var r in obj.Children.SelectMany(c => getResourceValues(c))) foreach (var r in obj.Children.SelectMany(c => getResourceValues(c)))
{ {

2
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs

@ -163,7 +163,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
{ {
foreach (var i in GetAllInterfacesIncludingSelf(itemsCollectionType)) foreach (var i in GetAllInterfacesIncludingSelf(itemsCollectionType))
{ {
if (i.GenericTypeDefinition?.Equals(context.Configuration.WellKnownTypes.IEnumerableT) == true) if (i.GenericTypeDefinition?.Equals(context.Configuration.WellKnownTypes.IEnumerableOfT) == true)
{ {
return new AvaloniaXamlIlDataContextTypeMetadataNode(on, i.GenericArguments[0]); return new AvaloniaXamlIlDataContextTypeMetadataNode(on, i.GenericArguments[0]);
} }

2
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlOptionMarkupExtensionTransformer.cs

@ -136,7 +136,7 @@ internal class AvaloniaXamlIlOptionMarkupExtensionTransformer : IXamlAstTransfor
try try
{ {
var targetType = method.Parameters.Last(); var targetType = method.Parameters.Last();
if (targetType.FullName == "System.Type") if (targetType.Is("System", "Type"))
{ {
if (option is IXamlType typeOption) if (option is IXamlType typeOption)
{ {

25
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlQueryTransformer.cs

@ -138,7 +138,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
[UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)] [UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)]
protected void EmitCall(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen, Func<IXamlMethod, bool> method) protected void EmitCall(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen, Func<IXamlMethod, bool> method)
{ {
var queries = context.Configuration.TypeSystem.GetType("Avalonia.Styling.StyleQueries"); var queries = context.GetAvaloniaTypes().StyleQueries;
var found = queries.FindMethod(m => m.IsStatic && m.Parameters.Count > 0 && method(m)); var found = queries.FindMethod(m => m.IsStatic && m.Parameters.Count > 0 && method(m));
if(found == null) if(found == null)
throw new XamlTypeSystemException( throw new XamlTypeSystemException(
@ -174,7 +174,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
var name = Concrete ? "OfType" : "Is"; var name = Concrete ? "OfType" : "Is";
codeGen.Ldtype(TargetType); codeGen.Ldtype(TargetType);
EmitCall(context, codeGen, EmitCall(context, codeGen,
m => m.Name == name && m.Parameters.Count == 2 && m.Parameters[1].FullName == "System.Type"); m => m.Name == name && m.Parameters.Count == 2 && m.Parameters[1].Equals(context.Configuration.WellKnownTypes.Type));
} }
} }
@ -201,7 +201,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
codeGen.Ldstr(String); codeGen.Ldstr(String);
var name = _type.ToString(); var name = _type.ToString();
EmitCall(context, codeGen, EmitCall(context, codeGen,
m => m.Name == name && m.Parameters.Count == 2 && m.Parameters[1].FullName == "System.String"); m => m.Name == name && m.Parameters.Count == 2 && m.Parameters[1].Equals(context.Configuration.WellKnownTypes.String));
} }
} }
@ -320,11 +320,10 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
return; return;
} }
if (context.Configuration.TypeSystem.FindType("System.Collections.Generic.List`1") is not { } type)
return;
IXamlType listType = type.MakeGenericType(base.Type.GetClrType()); var typeArgument = Type.GetClrType();
var add = listType.FindMethod("Add", context.Configuration.WellKnownTypes.Void, false, Type.GetClrType()); var listType = context.Configuration.WellKnownTypes.ListOfT.MakeGenericType(typeArgument);
var add = listType.FindMethod("Add", context.Configuration.WellKnownTypes.Void, false, typeArgument);
if (add == null) if (add == null)
return; return;
@ -338,7 +337,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
foreach (var s in _queries) foreach (var s in _queries)
{ {
codeGen.Dup(); codeGen.Dup();
context.Emit(s, codeGen, Type.GetClrType()); context.Emit(s, codeGen, typeArgument);
codeGen.EmitCall(add, true); codeGen.EmitCall(add, true);
} }
@ -399,11 +398,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
return; return;
} }
if (context.Configuration.TypeSystem.FindType("System.Collections.Generic.List`1") is not { } type) var typeArgument = Type.GetClrType();
return; var listType = context.Configuration.WellKnownTypes.ListOfT.MakeGenericType(typeArgument);
var add = listType.FindMethod("Add", context.Configuration.WellKnownTypes.Void, false, typeArgument);
IXamlType listType = type.MakeGenericType(base.Type.GetClrType());
var add = listType.FindMethod("Add", context.Configuration.WellKnownTypes.Void, false, Type.GetClrType());
if (add == null) if (add == null)
return; return;
@ -417,7 +414,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
foreach (var s in _queries) foreach (var s in _queries)
{ {
codeGen.Dup(); codeGen.Dup();
context.Emit(s, codeGen, Type.GetClrType()); context.Emit(s, codeGen, typeArgument);
codeGen.EmitCall(add, true); codeGen.EmitCall(add, true);
} }

2
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs

@ -24,7 +24,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
attributes = attributes.Concat(referenceNode.Getter.CustomAttributes); attributes = attributes.Concat(referenceNode.Getter.CustomAttributes);
} }
if (attributes.All(attribute => attribute.Type.FullName != "Avalonia.Controls.ResolveByNameAttribute")) if (attributes.All(attribute => !attribute.Type.Is("Avalonia.Controls", "ResolveByNameAttribute")))
return node; return node;
if (propertyValueNode.Values.Count != 1 || !(propertyValueNode.Values.First() is XamlAstTextNode)) if (propertyValueNode.Values.Count != 1 || !(propertyValueNode.Values.First() is XamlAstTextNode))

2
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlResourceTransformer.cs

@ -118,7 +118,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
} }
// Never defer strings. // Never defer strings.
if (clrType.FullName == "System.String") if (clrType.Is("System", "String"))
{ {
return false; return false;
} }

16
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSelectorTransformer.cs

@ -313,7 +313,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
[UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)] [UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)]
protected void EmitCall(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen, Func<IXamlMethod, bool> method) protected void EmitCall(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen, Func<IXamlMethod, bool> method)
{ {
var selectors = context.Configuration.TypeSystem.GetType("Avalonia.Styling.Selectors"); var selectors = context.GetAvaloniaTypes().Selectors;
var found = selectors.GetMethod(m => m.IsStatic && m.Parameters.Count > 0 && method(m)); var found = selectors.GetMethod(m => m.IsStatic && m.Parameters.Count > 0 && method(m));
codeGen.EmitCall(found); codeGen.EmitCall(found);
} }
@ -346,7 +346,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
var name = Concrete ? "OfType" : "Is"; var name = Concrete ? "OfType" : "Is";
codeGen.Ldtype(TargetType); codeGen.Ldtype(TargetType);
EmitCall(context, codeGen, EmitCall(context, codeGen,
m => m.Name == name && m.Parameters.Count == 2 && m.Parameters[1].FullName == "System.Type"); m => m.Name == name && m.Parameters.Count == 2 && m.Parameters[1].Is("System", "Type"));
} }
} }
@ -375,7 +375,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
codeGen.Ldstr(String); codeGen.Ldstr(String);
var name = _type.ToString(); var name = _type.ToString();
EmitCall(context, codeGen, EmitCall(context, codeGen,
m => m.Name == name && m.Parameters.Count == 2 && m.Parameters[1].FullName == "System.String"); m => m.Name == name && m.Parameters.Count == 2 && m.Parameters[1].Is("System", "String"));
} }
} }
@ -479,8 +479,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
EmitCall(context, codeGen, EmitCall(context, codeGen,
m => m.Name == "PropertyEquals" m => m.Name == "PropertyEquals"
&& m.Parameters.Count == 3 && m.Parameters.Count == 3
&& m.Parameters[1].FullName == "Avalonia.AvaloniaProperty" && m.Parameters[1].Is("Avalonia", "AvaloniaProperty")
&& m.Parameters[2].Equals(context.Configuration.WellKnownTypes.Object)); && m.Parameters[2].Is("System", "Object"));
} }
} }
@ -508,8 +508,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
EmitCall(context, codeGen, EmitCall(context, codeGen,
m => m.Name == "PropertyEquals" m => m.Name == "PropertyEquals"
&& m.Parameters.Count == 3 && m.Parameters.Count == 3
&& m.Parameters[1].FullName == "Avalonia.AvaloniaProperty" && m.Parameters[1].Is("Avalonia", "AvaloniaProperty")
&& m.Parameters[2].Equals(context.Configuration.WellKnownTypes.Object)); && m.Parameters[2].Is("System", "Object"));
} }
} }
@ -564,7 +564,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
_selectors[0].Emit(context, codeGen); _selectors[0].Emit(context, codeGen);
return; return;
} }
var listType = context.Configuration.TypeSystem.GetType("System.Collections.Generic.List`1") var listType = context.Configuration.WellKnownTypes.ListOfT
.MakeGenericType(base.Type.GetClrType()); .MakeGenericType(base.Type.GetClrType());
var add = listType.GetMethod("Add", context.Configuration.WellKnownTypes.Void, false, Type.GetClrType()); var add = listType.GetMethod("Add", context.Configuration.WellKnownTypes.Void, false, Type.GetClrType());
codeGen codeGen

2
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs

@ -23,7 +23,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
{ {
if (!(node is XamlAstObjectNode on if (!(node is XamlAstObjectNode on
&& on.Type.GetClrType().FullName == "Avalonia.Styling.Setter")) && on.Type.GetClrType().Is("Avalonia.Styling", "Setter")))
return node; return node;
IXamlType? targetType = null; IXamlType? targetType = null;

1
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlTransformRoutedEvent.cs

@ -19,7 +19,6 @@ internal class AvaloniaXamlIlTransformRoutedEvent : IXamlAstTransformer
var xkt = context.GetAvaloniaTypes(); var xkt = context.GetAvaloniaTypes();
var interactiveType = xkt.Interactivity.Interactive; var interactiveType = xkt.Interactivity.Interactive;
var routedEventType = xkt.Interactivity.RoutedEvent; var routedEventType = xkt.Interactivity.RoutedEvent;
var AddHandlerT = xkt.Interactivity.AddHandlerT;
if (interactiveType.IsAssignableFrom(targetRef.Type)) if (interactiveType.IsAssignableFrom(targetRef.Type))
{ {

257
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs

@ -72,7 +72,10 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public IXamlType Int { get; } public IXamlType Int { get; }
public IXamlType Long { get; } public IXamlType Long { get; }
public IXamlType Uri { get; } public IXamlType Uri { get; }
public IXamlType TaskOfT { get; }
public IXamlType IDictionaryT { get; } public IXamlType IDictionaryT { get; }
public IXamlType WeakReferenceOfT { get; }
public IXamlType IObservableOfT { get; }
public IXamlType FontFamily { get; } public IXamlType FontFamily { get; }
public IXamlConstructor FontFamilyConstructorUriName { get; } public IXamlConstructor FontFamilyConstructorUriName { get; }
public IXamlType Thickness { get; } public IXamlType Thickness { get; }
@ -129,6 +132,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public IXamlType Style { get; } public IXamlType Style { get; }
public IXamlType Container { get; } public IXamlType Container { get; }
public IXamlType Styles { get; } public IXamlType Styles { get; }
public IXamlType StyleQueries { get; }
public IXamlType Selectors { get; }
public IXamlType ControlTheme { get; } public IXamlType ControlTheme { get; }
public IXamlType WindowTransparencyLevel { get; } public IXamlType WindowTransparencyLevel { get; }
public IXamlType IReadOnlyListOfT { get; } public IXamlType IReadOnlyListOfT { get; }
@ -149,22 +154,21 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public IXamlMethod AddHandlerT { get; } public IXamlMethod AddHandlerT { get; }
[UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)] [UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)]
internal InteractivityWellKnownTypes(TransformerConfiguration cfg) internal InteractivityWellKnownTypes(IXamlTypeSystem typeSystem, XamlTypeWellKnownTypes wellKnownTypes)
{ {
var ts = cfg.TypeSystem; Interactive = typeSystem.GetType("Avalonia.Interactivity.Interactive");
Interactive = ts.GetType("Avalonia.Interactivity.Interactive"); RoutedEvent = typeSystem.GetType("Avalonia.Interactivity.RoutedEvent");
RoutedEvent = ts.GetType("Avalonia.Interactivity.RoutedEvent"); RoutedEventArgs = typeSystem.GetType("Avalonia.Interactivity.RoutedEventArgs");
RoutedEventArgs = ts.GetType("Avalonia.Interactivity.RoutedEventArgs"); var eventHanlderT = typeSystem.GetType("System.EventHandler`1");
var eventHanlderT = ts.GetType("System.EventHandler`1");
RoutedEventHandler = eventHanlderT.MakeGenericType(RoutedEventArgs); RoutedEventHandler = eventHanlderT.MakeGenericType(RoutedEventArgs);
AddHandler = Interactive.GetMethod(m => m.IsPublic AddHandler = Interactive.GetMethod(m => m.IsPublic
&& !m.IsStatic && !m.IsStatic
&& m.Name == "AddHandler" && m.Name == "AddHandler"
&& m.Parameters.Count == 4 && m.Parameters.Count == 4
&& m.Parameters[0].Equals(RoutedEvent) && m.Parameters[0].Equals(RoutedEvent)
&& m.Parameters[1].Equals(cfg.WellKnownTypes.Delegate) && m.Parameters[1].Equals(wellKnownTypes.Delegate)
&& m.Parameters[2].IsEnum && m.Parameters[2].IsEnum
&& m.Parameters[3].Equals(cfg.WellKnownTypes.Boolean) && m.Parameters[3].Equals(wellKnownTypes.Boolean)
); );
AddHandlerT = Interactive.GetMethod(m => m.IsPublic AddHandlerT = Interactive.GetMethod(m => m.IsPublic
&& !m.IsStatic && !m.IsStatic
@ -172,9 +176,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
&& m.Parameters.Count == 4 && m.Parameters.Count == 4
&& RoutedEvent.IsAssignableFrom(m.Parameters[0]) && RoutedEvent.IsAssignableFrom(m.Parameters[0])
&& m.Parameters[0].GenericArguments.Count == 1 // This is specific this case workaround to check is generic method && m.Parameters[0].GenericArguments.Count == 1 // This is specific this case workaround to check is generic method
&& (cfg.WellKnownTypes.Delegate).IsAssignableFrom(m.Parameters[1]) && wellKnownTypes.Delegate.IsAssignableFrom(m.Parameters[1])
&& m.Parameters[2].IsEnum && m.Parameters[2].IsEnum
&& m.Parameters[3].Equals(cfg.WellKnownTypes.Boolean) && m.Parameters[3].Equals(wellKnownTypes.Boolean)
); );
} }
@ -183,44 +187,44 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public InteractivityWellKnownTypes Interactivity { get; } public InteractivityWellKnownTypes Interactivity { get; }
[UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)] [UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)]
public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg) public AvaloniaXamlIlWellKnownTypes(IXamlTypeSystem typeSystem)
{ {
RuntimeHelpers = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.XamlIlRuntimeHelpers"); RuntimeHelpers = typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.XamlIlRuntimeHelpers");
XamlIlTypes = cfg.WellKnownTypes; XamlIlTypes = typeSystem.WellKnownTypes;
AvaloniaObject = cfg.TypeSystem.GetType("Avalonia.AvaloniaObject"); AvaloniaObject = typeSystem.GetType("Avalonia.AvaloniaObject");
AvaloniaObjectExtensions = cfg.TypeSystem.GetType("Avalonia.AvaloniaObjectExtensions"); AvaloniaObjectExtensions = typeSystem.GetType("Avalonia.AvaloniaObjectExtensions");
AvaloniaProperty = cfg.TypeSystem.GetType("Avalonia.AvaloniaProperty"); AvaloniaProperty = typeSystem.GetType("Avalonia.AvaloniaProperty");
AvaloniaPropertyT = cfg.TypeSystem.GetType("Avalonia.AvaloniaProperty`1"); AvaloniaPropertyT = typeSystem.GetType("Avalonia.AvaloniaProperty`1");
StyledPropertyT = cfg.TypeSystem.GetType("Avalonia.StyledProperty`1"); StyledPropertyT = typeSystem.GetType("Avalonia.StyledProperty`1");
AvaloniaAttachedPropertyT = cfg.TypeSystem.GetType("Avalonia.AttachedProperty`1"); AvaloniaAttachedPropertyT = typeSystem.GetType("Avalonia.AttachedProperty`1");
BindingPriority = cfg.TypeSystem.GetType("Avalonia.Data.BindingPriority"); BindingPriority = typeSystem.GetType("Avalonia.Data.BindingPriority");
AvaloniaObjectSetStyledPropertyValue = AvaloniaObject AvaloniaObjectSetStyledPropertyValue = AvaloniaObject
.GetMethod(m => m.IsPublic && !m.IsStatic && m.Name == "SetValue" .GetMethod(m => m.IsPublic && !m.IsStatic && m.Name == "SetValue"
&& m.Parameters.Count == 3 && m.Parameters.Count == 3
&& m.Parameters[0].Name == "StyledProperty`1" && m.Parameters[0].Name == "StyledProperty`1"
&& m.Parameters[2].Equals(BindingPriority)); && m.Parameters[2].Equals(BindingPriority));
BindingBase = cfg.TypeSystem.GetType("Avalonia.Data.BindingBase"); BindingBase = typeSystem.GetType("Avalonia.Data.BindingBase");
BindingExpressionBase = cfg.TypeSystem.GetType("Avalonia.Data.BindingExpressionBase"); BindingExpressionBase = typeSystem.GetType("Avalonia.Data.BindingExpressionBase");
MultiBinding = cfg.TypeSystem.GetType("Avalonia.Data.MultiBinding"); MultiBinding = typeSystem.GetType("Avalonia.Data.MultiBinding");
IDisposable = cfg.TypeSystem.GetType("System.IDisposable"); IDisposable = typeSystem.GetType("System.IDisposable");
ICommand = cfg.TypeSystem.GetType("System.Windows.Input.ICommand"); ICommand = typeSystem.GetType("System.Windows.Input.ICommand");
Transitions = cfg.TypeSystem.GetType("Avalonia.Animation.Transitions"); Transitions = typeSystem.GetType("Avalonia.Animation.Transitions");
AssignBindingAttribute = cfg.TypeSystem.GetType("Avalonia.Data.AssignBindingAttribute"); AssignBindingAttribute = typeSystem.GetType("Avalonia.Data.AssignBindingAttribute");
DependsOnAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.DependsOnAttribute"); DependsOnAttribute = typeSystem.GetType("Avalonia.Metadata.DependsOnAttribute");
DataTypeAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.DataTypeAttribute"); DataTypeAttribute = typeSystem.GetType("Avalonia.Metadata.DataTypeAttribute");
InheritDataTypeFromItemsAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.InheritDataTypeFromItemsAttribute"); InheritDataTypeFromItemsAttribute = typeSystem.GetType("Avalonia.Metadata.InheritDataTypeFromItemsAttribute");
InheritDataTypeFromAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.InheritDataTypeFromAttribute"); InheritDataTypeFromAttribute = typeSystem.GetType("Avalonia.Metadata.InheritDataTypeFromAttribute");
MarkupExtensionOptionAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.MarkupExtensionOptionAttribute"); MarkupExtensionOptionAttribute = typeSystem.GetType("Avalonia.Metadata.MarkupExtensionOptionAttribute");
MarkupExtensionDefaultOptionAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.MarkupExtensionDefaultOptionAttribute"); MarkupExtensionDefaultOptionAttribute = typeSystem.GetType("Avalonia.Metadata.MarkupExtensionDefaultOptionAttribute");
ControlTemplateScopeAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.ControlTemplateScopeAttribute"); ControlTemplateScopeAttribute = typeSystem.GetType("Avalonia.Metadata.ControlTemplateScopeAttribute");
AvaloniaListAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.AvaloniaListAttribute"); AvaloniaListAttribute = typeSystem.GetType("Avalonia.Metadata.AvaloniaListAttribute");
AvaloniaList = cfg.TypeSystem.GetType("Avalonia.Collections.AvaloniaList`1"); AvaloniaList = typeSystem.GetType("Avalonia.Collections.AvaloniaList`1");
OnExtensionType = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.On"); OnExtensionType = typeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.On");
AvaloniaObjectBindMethod = AvaloniaObject.GetMethod("Bind", BindingExpressionBase, false, AvaloniaProperty, BindingBase); AvaloniaObjectBindMethod = AvaloniaObject.GetMethod("Bind", BindingExpressionBase, false, AvaloniaProperty, BindingBase);
UnsetValueType = cfg.TypeSystem.GetType("Avalonia.UnsetValueType"); UnsetValueType = typeSystem.GetType("Avalonia.UnsetValueType");
StyledElement = cfg.TypeSystem.GetType("Avalonia.StyledElement"); StyledElement = typeSystem.GetType("Avalonia.StyledElement");
INameScope = cfg.TypeSystem.GetType("Avalonia.Controls.INameScope"); INameScope = typeSystem.GetType("Avalonia.Controls.INameScope");
INameScopeRegister = INameScope.GetMethod( INameScopeRegister = INameScope.GetMethod(
new FindMethodMethodSignature("Register", XamlIlTypes.Void, new FindMethodMethodSignature("Register", XamlIlTypes.Void,
XamlIlTypes.String, XamlIlTypes.Object) XamlIlTypes.String, XamlIlTypes.Object)
@ -236,42 +240,45 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
DeclaringOnly = true, DeclaringOnly = true,
IsExactMatch = true IsExactMatch = true
}); });
NameScope = cfg.TypeSystem.GetType("Avalonia.Controls.NameScope"); NameScope = typeSystem.GetType("Avalonia.Controls.NameScope");
NameScopeSetNameScope = NameScope.GetMethod(new FindMethodMethodSignature("SetNameScope", NameScopeSetNameScope = NameScope.GetMethod(new FindMethodMethodSignature("SetNameScope",
XamlIlTypes.Void, StyledElement, INameScope) XamlIlTypes.Void, StyledElement, INameScope)
{ IsStatic = true }); { IsStatic = true });
AvaloniaObjectSetValueMethod = AvaloniaObject.GetMethod("SetValue", IDisposable, AvaloniaObjectSetValueMethod = AvaloniaObject.GetMethod("SetValue", IDisposable,
false, AvaloniaProperty, XamlIlTypes.Object, BindingPriority); false, AvaloniaProperty, XamlIlTypes.Object, BindingPriority);
IPropertyInfo = cfg.TypeSystem.GetType("Avalonia.Data.Core.IPropertyInfo"); IPropertyInfo = typeSystem.GetType("Avalonia.Data.Core.IPropertyInfo");
ClrPropertyInfo = cfg.TypeSystem.GetType("Avalonia.Data.Core.ClrPropertyInfo"); ClrPropertyInfo = typeSystem.GetType("Avalonia.Data.Core.ClrPropertyInfo");
IPropertyAccessor = cfg.TypeSystem.GetType("Avalonia.Data.Core.Plugins.IPropertyAccessor"); IPropertyAccessor = typeSystem.GetType("Avalonia.Data.Core.Plugins.IPropertyAccessor");
PropertyInfoAccessorFactory = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.PropertyInfoAccessorFactory"); PropertyInfoAccessorFactory = typeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.PropertyInfoAccessorFactory");
CompiledBinding = cfg.TypeSystem.GetType("Avalonia.Data.CompiledBinding"); CompiledBinding = typeSystem.GetType("Avalonia.Data.CompiledBinding");
CompiledBindingPathBuilder = cfg.TypeSystem.GetType("Avalonia.Data.CompiledBindingPathBuilder"); CompiledBindingPathBuilder = typeSystem.GetType("Avalonia.Data.CompiledBindingPathBuilder");
CompiledBindingPath = cfg.TypeSystem.GetType("Avalonia.Data.CompiledBindingPath"); CompiledBindingPath = typeSystem.GetType("Avalonia.Data.CompiledBindingPath");
CompiledBindingExtension = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindingExtension"); CompiledBindingExtension = typeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindingExtension");
ResolveByNameExtension = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.ResolveByNameExtension"); ResolveByNameExtension = typeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.ResolveByNameExtension");
DataTemplate = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.Templates.DataTemplate"); DataTemplate = typeSystem.GetType("Avalonia.Markup.Xaml.Templates.DataTemplate");
IDataTemplate = cfg.TypeSystem.GetType("Avalonia.Controls.Templates.IDataTemplate"); IDataTemplate = typeSystem.GetType("Avalonia.Controls.Templates.IDataTemplate");
Control = cfg.TypeSystem.GetType("Avalonia.Controls.Control"); Control = typeSystem.GetType("Avalonia.Controls.Control");
ContentControl = cfg.TypeSystem.GetType("Avalonia.Controls.ContentControl"); ContentControl = typeSystem.GetType("Avalonia.Controls.ContentControl");
ITemplateOfControl = cfg.TypeSystem.GetType("Avalonia.Controls.ITemplate`1").MakeGenericType(Control); ITemplateOfControl = typeSystem.GetType("Avalonia.Controls.ITemplate`1").MakeGenericType(Control);
ItemsControl = cfg.TypeSystem.GetType("Avalonia.Controls.ItemsControl"); ItemsControl = typeSystem.GetType("Avalonia.Controls.ItemsControl");
ReflectionBindingExtension = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.ReflectionBindingExtension"); ReflectionBindingExtension = typeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.ReflectionBindingExtension");
RelativeSource = cfg.TypeSystem.GetType("Avalonia.Data.RelativeSource"); RelativeSource = typeSystem.GetType("Avalonia.Data.RelativeSource");
UInt = cfg.TypeSystem.GetType("System.UInt32"); UInt = typeSystem.GetType("System.UInt32");
Int = cfg.TypeSystem.GetType("System.Int32"); Int = typeSystem.GetType("System.Int32");
Long = cfg.TypeSystem.GetType("System.Int64"); Long = typeSystem.GetType("System.Int64");
Uri = cfg.TypeSystem.GetType("System.Uri"); Uri = typeSystem.GetType("System.Uri");
IDictionaryT = cfg.TypeSystem.GetType("System.Collections.Generic.IDictionary`2"); TaskOfT = typeSystem.GetType("System.Threading.Tasks.Task`1");
FontFamily = cfg.TypeSystem.GetType("Avalonia.Media.FontFamily"); IDictionaryT = typeSystem.GetType("System.Collections.Generic.IDictionary`2");
WeakReferenceOfT = typeSystem.GetType("System.WeakReference`1");
IObservableOfT = typeSystem.GetType("System.IObservable`1");
FontFamily = typeSystem.GetType("Avalonia.Media.FontFamily");
FontFamilyConstructorUriName = FontFamily.GetConstructor(new List<IXamlType> { Uri, XamlIlTypes.String }); FontFamilyConstructorUriName = FontFamily.GetConstructor(new List<IXamlType> { Uri, XamlIlTypes.String });
ThemeVariant = cfg.TypeSystem.GetType("Avalonia.Styling.ThemeVariant"); ThemeVariant = typeSystem.GetType("Avalonia.Styling.ThemeVariant");
WindowTransparencyLevel = cfg.TypeSystem.GetType("Avalonia.Controls.WindowTransparencyLevel"); WindowTransparencyLevel = typeSystem.GetType("Avalonia.Controls.WindowTransparencyLevel");
(IXamlType, IXamlConstructor) GetNumericTypeInfo([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] string name, IXamlType componentType, int componentCount) (IXamlType, IXamlConstructor) GetNumericTypeInfo([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] string name, IXamlType componentType, int componentCount)
{ {
var type = cfg.TypeSystem.GetType(name); var type = typeSystem.GetType(name);
var ctor = type.GetConstructor(Enumerable.Range(0, componentCount).Select(_ => componentType).ToList()); var ctor = type.GetConstructor(Enumerable.Range(0, componentCount).Select(_ => componentType).ToList());
return (type, ctor); return (type, ctor);
@ -284,70 +291,72 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
(Matrix, MatrixFullConstructor) = GetNumericTypeInfo("Avalonia.Matrix", XamlIlTypes.Double, 6); (Matrix, MatrixFullConstructor) = GetNumericTypeInfo("Avalonia.Matrix", XamlIlTypes.Double, 6);
(CornerRadius, CornerRadiusFullConstructor) = GetNumericTypeInfo("Avalonia.CornerRadius", XamlIlTypes.Double, 4); (CornerRadius, CornerRadiusFullConstructor) = GetNumericTypeInfo("Avalonia.CornerRadius", XamlIlTypes.Double, 4);
RelativeUnit = cfg.TypeSystem.GetType("Avalonia.RelativeUnit"); RelativeUnit = typeSystem.GetType("Avalonia.RelativeUnit");
RelativePoint = cfg.TypeSystem.GetType("Avalonia.RelativePoint"); RelativePoint = typeSystem.GetType("Avalonia.RelativePoint");
RelativePointFullConstructor = RelativePoint.GetConstructor(new List<IXamlType> { XamlIlTypes.Double, XamlIlTypes.Double, RelativeUnit }); RelativePointFullConstructor = RelativePoint.GetConstructor(new List<IXamlType> { XamlIlTypes.Double, XamlIlTypes.Double, RelativeUnit });
GridLength = cfg.TypeSystem.GetType("Avalonia.Controls.GridLength"); GridLength = typeSystem.GetType("Avalonia.Controls.GridLength");
GridLengthConstructorValueType = GridLength.GetConstructor(new List<IXamlType> { XamlIlTypes.Double, cfg.TypeSystem.GetType("Avalonia.Controls.GridUnitType") }); GridLengthConstructorValueType = GridLength.GetConstructor(new List<IXamlType> { XamlIlTypes.Double, typeSystem.GetType("Avalonia.Controls.GridUnitType") });
Color = cfg.TypeSystem.GetType("Avalonia.Media.Color"); Color = typeSystem.GetType("Avalonia.Media.Color");
StandardCursorType = cfg.TypeSystem.GetType("Avalonia.Input.StandardCursorType"); StandardCursorType = typeSystem.GetType("Avalonia.Input.StandardCursorType");
Cursor = cfg.TypeSystem.GetType("Avalonia.Input.Cursor"); Cursor = typeSystem.GetType("Avalonia.Input.Cursor");
CursorTypeConstructor = Cursor.GetConstructor(new List<IXamlType> { StandardCursorType }); CursorTypeConstructor = Cursor.GetConstructor(new List<IXamlType> { StandardCursorType });
ColumnDefinition = cfg.TypeSystem.GetType("Avalonia.Controls.ColumnDefinition"); ColumnDefinition = typeSystem.GetType("Avalonia.Controls.ColumnDefinition");
ColumnDefinitions = cfg.TypeSystem.GetType("Avalonia.Controls.ColumnDefinitions"); ColumnDefinitions = typeSystem.GetType("Avalonia.Controls.ColumnDefinitions");
RowDefinition = cfg.TypeSystem.GetType("Avalonia.Controls.RowDefinition"); RowDefinition = typeSystem.GetType("Avalonia.Controls.RowDefinition");
RowDefinitions = cfg.TypeSystem.GetType("Avalonia.Controls.RowDefinitions"); RowDefinitions = typeSystem.GetType("Avalonia.Controls.RowDefinitions");
Classes = cfg.TypeSystem.GetType("Avalonia.Controls.Classes"); Classes = typeSystem.GetType("Avalonia.Controls.Classes");
StyledElementClassesProperty = StyledElementClassesProperty =
StyledElement.Properties.First(x => x.Name == "Classes" && x.PropertyType.Equals(Classes)); StyledElement.Properties.First(x => x.Name == "Classes" && x.PropertyType.Equals(Classes));
ClassesBindMethod = cfg.TypeSystem.GetType("Avalonia.StyledElementExtensions") ClassesBindMethod = typeSystem.GetType("Avalonia.StyledElementExtensions")
.GetMethod("BindClass", IDisposable, false, StyledElement, .GetMethod("BindClass", IDisposable, false, StyledElement,
cfg.WellKnownTypes.String, typeSystem.WellKnownTypes.String,
BindingBase, cfg.WellKnownTypes.Object); BindingBase, typeSystem.WellKnownTypes.Object);
IBrush = cfg.TypeSystem.GetType("Avalonia.Media.IBrush"); IBrush = typeSystem.GetType("Avalonia.Media.IBrush");
ImmutableSolidColorBrush = cfg.TypeSystem.GetType("Avalonia.Media.Immutable.ImmutableSolidColorBrush"); ImmutableSolidColorBrush = typeSystem.GetType("Avalonia.Media.Immutable.ImmutableSolidColorBrush");
ImmutableSolidColorBrushConstructorColor = ImmutableSolidColorBrush.GetConstructor(new List<IXamlType> { UInt }); ImmutableSolidColorBrushConstructorColor = ImmutableSolidColorBrush.GetConstructor(new List<IXamlType> { UInt });
TypeUtilities = cfg.TypeSystem.GetType("Avalonia.Utilities.TypeUtilities"); TypeUtilities = typeSystem.GetType("Avalonia.Utilities.TypeUtilities");
TextDecorationCollection = cfg.TypeSystem.GetType("Avalonia.Media.TextDecorationCollection"); TextDecorationCollection = typeSystem.GetType("Avalonia.Media.TextDecorationCollection");
TextDecorations = cfg.TypeSystem.GetType("Avalonia.Media.TextDecorations"); TextDecorations = typeSystem.GetType("Avalonia.Media.TextDecorations");
TextTrimming = cfg.TypeSystem.GetType("Avalonia.Media.TextTrimming"); TextTrimming = typeSystem.GetType("Avalonia.Media.TextTrimming");
SetterBase = cfg.TypeSystem.GetType("Avalonia.Styling.SetterBase"); SetterBase = typeSystem.GetType("Avalonia.Styling.SetterBase");
Setter = cfg.TypeSystem.GetType("Avalonia.Styling.Setter"); Setter = typeSystem.GetType("Avalonia.Styling.Setter");
IStyle = cfg.TypeSystem.GetType("Avalonia.Styling.IStyle"); IStyle = typeSystem.GetType("Avalonia.Styling.IStyle");
StyleInclude = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.Styling.StyleInclude"); StyleInclude = typeSystem.GetType("Avalonia.Markup.Xaml.Styling.StyleInclude");
ResourceInclude = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.Styling.ResourceInclude"); ResourceInclude = typeSystem.GetType("Avalonia.Markup.Xaml.Styling.ResourceInclude");
MergeResourceInclude = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.Styling.MergeResourceInclude"); MergeResourceInclude = typeSystem.GetType("Avalonia.Markup.Xaml.Styling.MergeResourceInclude");
IResourceDictionary = cfg.TypeSystem.GetType("Avalonia.Controls.IResourceDictionary"); IResourceDictionary = typeSystem.GetType("Avalonia.Controls.IResourceDictionary");
ResourceDictionary = cfg.TypeSystem.GetType("Avalonia.Controls.ResourceDictionary"); ResourceDictionary = typeSystem.GetType("Avalonia.Controls.ResourceDictionary");
ResourceDictionaryDeferredAdd = ResourceDictionary.GetMethod("AddDeferred", XamlIlTypes.Void, true, XamlIlTypes.Object, ResourceDictionaryDeferredAdd = ResourceDictionary.GetMethod("AddDeferred", XamlIlTypes.Void, true, XamlIlTypes.Object,
cfg.TypeSystem.GetType("Avalonia.Controls.IDeferredContent")); typeSystem.GetType("Avalonia.Controls.IDeferredContent"));
ResourceDictionaryNotSharedDeferredAdd = ResourceDictionary.GetMethod("AddNotSharedDeferred", XamlIlTypes.Void, true, XamlIlTypes.Object, ResourceDictionaryNotSharedDeferredAdd = ResourceDictionary.GetMethod("AddNotSharedDeferred", XamlIlTypes.Void, true, XamlIlTypes.Object,
cfg.TypeSystem.GetType("Avalonia.Controls.IDeferredContent")); typeSystem.GetType("Avalonia.Controls.IDeferredContent"));
ResourceDictionaryEnsureCapacity = ResourceDictionary.GetMethod("EnsureCapacity", XamlIlTypes.Void, true, XamlIlTypes.Int32); ResourceDictionaryEnsureCapacity = ResourceDictionary.GetMethod("EnsureCapacity", XamlIlTypes.Void, true, XamlIlTypes.Int32);
ResourceDictionaryGetCount = ResourceDictionary.GetMethod("get_Count", XamlIlTypes.Int32, true); ResourceDictionaryGetCount = ResourceDictionary.GetMethod("get_Count", XamlIlTypes.Int32, true);
IThemeVariantProvider = cfg.TypeSystem.GetType("Avalonia.Controls.IThemeVariantProvider"); IThemeVariantProvider = typeSystem.GetType("Avalonia.Controls.IThemeVariantProvider");
UriKind = cfg.TypeSystem.GetType("System.UriKind"); UriKind = typeSystem.GetType("System.UriKind");
UriConstructor = Uri.GetConstructor(new List<IXamlType>() { cfg.WellKnownTypes.String, UriKind }); UriConstructor = Uri.GetConstructor(new List<IXamlType>() { typeSystem.WellKnownTypes.String, UriKind });
Style = cfg.TypeSystem.GetType("Avalonia.Styling.Style"); Style = typeSystem.GetType("Avalonia.Styling.Style");
Container = cfg.TypeSystem.GetType("Avalonia.Styling.ContainerQuery"); Container = typeSystem.GetType("Avalonia.Styling.ContainerQuery");
Styles = cfg.TypeSystem.GetType("Avalonia.Styling.Styles"); Styles = typeSystem.GetType("Avalonia.Styling.Styles");
ControlTheme = cfg.TypeSystem.GetType("Avalonia.Styling.ControlTheme"); StyleQueries = typeSystem.GetType("Avalonia.Styling.StyleQueries");
ControlTemplate = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.Templates.ControlTemplate"); Selectors = typeSystem.GetType("Avalonia.Styling.Selectors");
IReadOnlyListOfT = cfg.TypeSystem.GetType("System.Collections.Generic.IReadOnlyList`1"); ControlTheme = typeSystem.GetType("Avalonia.Styling.ControlTheme");
EventHandlerT = cfg.TypeSystem.GetType("System.EventHandler`1"); ControlTemplate = typeSystem.GetType("Avalonia.Markup.Xaml.Templates.ControlTemplate");
Interactivity = new InteractivityWellKnownTypes(cfg); IReadOnlyListOfT = typeSystem.GetType("System.Collections.Generic.IReadOnlyList`1");
EventHandlerT = typeSystem.GetType("System.EventHandler`1");
Interactivity = new InteractivityWellKnownTypes(typeSystem, typeSystem.WellKnownTypes);
GetClassProperty = cfg.TypeSystem.GetType("Avalonia.StyledElementExtensions") GetClassProperty = typeSystem.GetType("Avalonia.StyledElementExtensions")
.GetMethod(name: "GetClassProperty", .GetMethod(name: "GetClassProperty",
returnType: AvaloniaProperty, returnType: AvaloniaProperty,
allowDowncast:false, allowDowncast:false,
cfg.WellKnownTypes.String typeSystem.WellKnownTypes.String
); );
var xamlSourceInfo = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.Diagnostics.XamlSourceInfo"); var xamlSourceInfo = typeSystem.GetType("Avalonia.Markup.Xaml.Diagnostics.XamlSourceInfo");
XamlSourceInfoConstructor = xamlSourceInfo.GetConstructor([ XamlSourceInfoConstructor = xamlSourceInfo.GetConstructor([
XamlIlTypes.Int32, XamlIlTypes.Int32, XamlIlTypes.String XamlIlTypes.Int32, XamlIlTypes.Int32, XamlIlTypes.String
]); ]);
@ -360,28 +369,16 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
static class AvaloniaXamlIlWellKnownTypesExtensions static class AvaloniaXamlIlWellKnownTypesExtensions
{ {
public static AvaloniaXamlIlWellKnownTypes GetAvaloniaTypes(this TransformerConfiguration cfg)
=> cfg.GetExtra<AvaloniaXamlIlWellKnownTypes>();
public static AvaloniaXamlIlWellKnownTypes GetAvaloniaTypes(this AstTransformationContext ctx) public static AvaloniaXamlIlWellKnownTypes GetAvaloniaTypes(this AstTransformationContext ctx)
{ => ctx.Configuration.GetAvaloniaTypes();
if (ctx.TryGetItem<AvaloniaXamlIlWellKnownTypes>(out var rv))
return rv;
ctx.SetItem(rv = new AvaloniaXamlIlWellKnownTypes(ctx.Configuration));
return rv;
}
public static AvaloniaXamlIlWellKnownTypes GetAvaloniaTypes(this XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> ctx) public static AvaloniaXamlIlWellKnownTypes GetAvaloniaTypes(this XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> ctx)
{ => ctx.Configuration.GetAvaloniaTypes();
if (ctx.TryGetItem<AvaloniaXamlIlWellKnownTypes>(out var rv))
return rv;
ctx.SetItem(rv = new AvaloniaXamlIlWellKnownTypes(ctx.Configuration));
return rv;
}
public static AvaloniaXamlIlWellKnownTypes GetAvaloniaTypes(this AstGroupTransformationContext ctx) public static AvaloniaXamlIlWellKnownTypes GetAvaloniaTypes(this AstGroupTransformationContext ctx)
{ => ctx.Configuration.GetAvaloniaTypes();
if (ctx.TryGetItem<AvaloniaXamlIlWellKnownTypes>(out var rv))
return rv;
ctx.SetItem(rv = new AvaloniaXamlIlWellKnownTypes(ctx.Configuration));
return rv;
}
} }
} }

33
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs

@ -155,13 +155,14 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
{ {
IXamlType targetType = targetTypeResolver(); IXamlType targetType = targetTypeResolver();
IXamlType? observableType; IXamlType? observableType;
if (targetType.GenericTypeDefinition?.Equals(context.Configuration.TypeSystem.FindType("System.IObservable`1")) == true) var observableOfT = context.GetAvaloniaTypes().IObservableOfT;
if (targetType.GenericTypeDefinition?.Equals(observableOfT) == true)
{ {
observableType = targetType; observableType = targetType;
} }
else else
{ {
observableType = targetType.GetAllInterfaces().FirstOrDefault(i => i.GenericTypeDefinition?.Equals(context.Configuration.TypeSystem.FindType("System.IObservable`1")) ?? false); observableType = targetType.GetAllInterfaces().FirstOrDefault(i => i.GenericTypeDefinition?.Equals(observableOfT) ?? false);
} }
if (observableType != null) if (observableType != null)
@ -171,7 +172,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
} }
bool foundTask = false; bool foundTask = false;
var taskType = context.Configuration.TypeSystem.GetType("System.Threading.Tasks.Task`1"); var taskType = context.GetAvaloniaTypes().TaskOfT;
for (var currentType = targetType; currentType != null; currentType = currentType.BaseType) for (var currentType = targetType; currentType != null; currentType = currentType.BaseType)
{ {
@ -260,7 +261,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
currentParamIndex++; currentParamIndex++;
} }
bool isNotifyingCollection = targetType.GetAllInterfaces().Any(i => i.FullName == "System.Collections.Specialized.INotifyCollectionChanged"); bool isNotifyingCollection = targetType.GetAllInterfaces().Any(i => i.Is("System.Collections.Specialized", "INotifyCollectionChanged"));
nodes.Add(new XamlIlClrIndexerPathElementNode(property, values, string.Join(",", indexer.Arguments), isNotifyingCollection)); nodes.Add(new XamlIlClrIndexerPathElementNode(property, values, string.Join(",", indexer.Arguments), isNotifyingCollection));
break; break;
@ -752,13 +753,12 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
IXamlType specificDelegateType; IXamlType specificDelegateType;
if (Method.ReturnType == context.Configuration.WellKnownTypes.Void && Method.Parameters.Count == 0) if (Method.ReturnType == context.Configuration.WellKnownTypes.Void && Method.Parameters.Count == 0)
{ {
specificDelegateType = context.Configuration.TypeSystem specificDelegateType = context.Configuration.WellKnownTypes.Action;
.GetType("System.Action");
} }
else if (Method.ReturnType == context.Configuration.WellKnownTypes.Void && Method.Parameters.Count <= 16) else if (Method.ReturnType == context.Configuration.WellKnownTypes.Void && Method.Parameters.Count <= 16)
{ {
specificDelegateType = context.Configuration.TypeSystem specificDelegateType = context.Configuration.WellKnownTypes
.GetType($"System.Action`{Method.Parameters.Count}") .GetActionOfT(Method.Parameters.Count)
.MakeGenericType(Method.Parameters); .MakeGenericType(Method.Parameters);
} }
else if (Method.Parameters.Count <= 16) else if (Method.Parameters.Count <= 16)
@ -766,8 +766,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
List<IXamlType> genericParameters = new(); List<IXamlType> genericParameters = new();
genericParameters.AddRange(Method.Parameters); genericParameters.AddRange(Method.Parameters);
genericParameters.Add(Method.ReturnType); genericParameters.Add(Method.ReturnType);
specificDelegateType = context.Configuration.TypeSystem specificDelegateType = context.Configuration.WellKnownTypes
.GetType($"System.Func`{Method.Parameters.Count + 1}") .GetFuncOfT(Method.Parameters.Count + 1)
.MakeGenericType(genericParameters); .MakeGenericType(genericParameters);
} }
else else
@ -836,9 +836,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
.Ldstr(_executeMethod.Name) .Ldstr(_executeMethod.Name)
.Ldnull() .Ldnull()
.Ldftn(trampolineBuilder.EmitCommandExecuteTrampoline(context, _executeMethod)) .Ldftn(trampolineBuilder.EmitCommandExecuteTrampoline(context, _executeMethod))
.Newobj(context.Configuration.TypeSystem.GetType("System.Action`2") .Newobj(context.Configuration.WellKnownTypes.GetActionOfT(2)
.MakeGenericType(objectType, objectType) .MakeGenericType(objectType, objectType)
.GetConstructor(new() { objectType, context.Configuration.TypeSystem.GetType("System.IntPtr") })); .GetConstructor(new() { objectType, context.Configuration.WellKnownTypes.IntPtr }));
if (_canExecuteMethod is null) if (_canExecuteMethod is null)
{ {
@ -849,9 +849,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
codeGen codeGen
.Ldnull() .Ldnull()
.Ldftn(trampolineBuilder.EmitCommandCanExecuteTrampoline(context, _canExecuteMethod)) .Ldftn(trampolineBuilder.EmitCommandCanExecuteTrampoline(context, _canExecuteMethod))
.Newobj(context.Configuration.TypeSystem.GetType("System.Func`3") .Newobj(context.Configuration.TypeSystem.WellKnownTypes.GetFuncOfT(3)
.MakeGenericType(objectType, objectType, context.Configuration.WellKnownTypes.Boolean) .MakeGenericType(objectType, objectType, context.Configuration.WellKnownTypes.Boolean)
.GetConstructor(new() { objectType, context.Configuration.TypeSystem.GetType("System.IntPtr") })); .GetConstructor(new() { objectType, context.Configuration.WellKnownTypes.IntPtr }));
} }
if (_dependsOnProperties is { Count:> 0 }) if (_dependsOnProperties is { Count:> 0 })
@ -901,7 +901,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
[UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)] [UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)]
public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen)
{ {
var intType = context.Configuration.TypeSystem.GetType("System.Int32"); var intType = context.Configuration.TypeSystem.WellKnownTypes.Int32;
context.Configuration.GetExtra<XamlIlClrPropertyInfoEmitter>() context.Configuration.GetExtra<XamlIlClrPropertyInfoEmitter>()
.Emit(context, codeGen, _property, _values, _indexerKey); .Emit(context, codeGen, _property, _values, _indexerKey);
@ -948,7 +948,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
[UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)] [UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)]
public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen)
{ {
var intType = context.Configuration.TypeSystem.GetType("System.Int32"); var intType = context.Configuration.TypeSystem.WellKnownTypes.Int32;
var indices = codeGen.DefineLocal(intType.MakeArrayType(1)); var indices = codeGen.DefineLocal(intType.MakeArrayType(1));
codeGen.Ldc_I4(_values.Count) codeGen.Ldc_I4(_values.Count)
.Newarr(intType) .Newarr(intType)
@ -1011,7 +1011,6 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
[UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)] [UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)]
public XamlILNodeEmitResult Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) public XamlILNodeEmitResult Emit(XamlIlEmitContext context, IXamlILEmitter codeGen)
{ {
var intType = context.Configuration.TypeSystem.GetType("System.Int32");
var types = context.GetAvaloniaTypes(); var types = context.GetAvaloniaTypes();
codeGen.Newobj(types.CompiledBindingPathBuilder.GetConstructor()); codeGen.Newobj(types.CompiledBindingPathBuilder.GetConstructor());

12
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs

@ -42,7 +42,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
private void EmitLoadPropertyAccessorFactory(XamlIlEmitContext context, IXamlILEmitter codeGen, IXamlType type, string accessorFactoryName, bool isStatic = true) private void EmitLoadPropertyAccessorFactory(XamlIlEmitContext context, IXamlILEmitter codeGen, IXamlType type, string accessorFactoryName, bool isStatic = true)
{ {
var types = context.GetAvaloniaTypes(); var types = context.GetAvaloniaTypes();
var weakReferenceType = context.Configuration.TypeSystem.GetType("System.WeakReference`1").MakeGenericType(context.Configuration.WellKnownTypes.Object); var weakReferenceType = types.WeakReferenceOfT.MakeGenericType(context.Configuration.WellKnownTypes.Object);
FindMethodMethodSignature accessorFactorySignature = new FindMethodMethodSignature(accessorFactoryName, types.IPropertyAccessor, weakReferenceType, types.IPropertyInfo) FindMethodMethodSignature accessorFactorySignature = new FindMethodMethodSignature(accessorFactoryName, types.IPropertyAccessor, weakReferenceType, types.IPropertyInfo)
{ {
IsStatic = isStatic IsStatic = isStatic
@ -53,7 +53,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
[UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)] [UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)]
public IXamlType EmitLoadIndexerAccessorFactory(XamlIlEmitContext context, IXamlILEmitter codeGen, IXamlAstValueNode value) public IXamlType EmitLoadIndexerAccessorFactory(XamlIlEmitContext context, IXamlILEmitter codeGen, IXamlAstValueNode value)
{ {
var intType = context.Configuration.TypeSystem.GetType("System.Int32"); var intType = context.Configuration.TypeSystem.WellKnownTypes.Int32;
if (_indexerClosureType is null) if (_indexerClosureType is null)
{ {
_indexerClosureType = InitializeClosureType(context); _indexerClosureType = InitializeClosureType(context);
@ -69,8 +69,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
private IXamlType InitializeClosureType(XamlIlEmitContext context) private IXamlType InitializeClosureType(XamlIlEmitContext context)
{ {
var types = context.GetAvaloniaTypes(); var types = context.GetAvaloniaTypes();
var intType = context.Configuration.TypeSystem.GetType("System.Int32"); var intType = context.Configuration.WellKnownTypes.Int32;
var weakReferenceType = context.Configuration.TypeSystem.GetType("System.WeakReference`1").MakeGenericType(context.Configuration.WellKnownTypes.Object); var weakReferenceType = types.WeakReferenceOfT.MakeGenericType(context.Configuration.WellKnownTypes.Object);
var indexAccessorFactoryMethod = context.GetAvaloniaTypes().PropertyInfoAccessorFactory.GetMethod( var indexAccessorFactoryMethod = context.GetAvaloniaTypes().PropertyInfoAccessorFactory.GetMethod(
new FindMethodMethodSignature( new FindMethodMethodSignature(
"CreateIndexerPropertyAccessor", "CreateIndexerPropertyAccessor",
@ -109,8 +109,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
private IXamlType EmitCreateAccessorFactoryDelegate(XamlIlEmitContext context, IXamlILEmitter codeGen) private IXamlType EmitCreateAccessorFactoryDelegate(XamlIlEmitContext context, IXamlILEmitter codeGen)
{ {
var types = context.GetAvaloniaTypes(); var types = context.GetAvaloniaTypes();
var weakReferenceType = context.Configuration.TypeSystem.GetType("System.WeakReference`1").MakeGenericType(context.Configuration.WellKnownTypes.Object); var weakReferenceType = types.WeakReferenceOfT.MakeGenericType(context.Configuration.WellKnownTypes.Object);
var funcType = context.Configuration.TypeSystem.GetType("System.Func`3").MakeGenericType( var funcType = context.Configuration.WellKnownTypes.GetFuncOfT(3).MakeGenericType(
weakReferenceType, weakReferenceType,
types.IPropertyInfo, types.IPropertyInfo,
types.IPropertyAccessor); types.IPropertyAccessor);

7
src/tools/Avalonia.Generators/Compiler/NoopTypeSystem.cs

@ -5,7 +5,11 @@ namespace Avalonia.Generators.Compiler;
internal class NoopTypeSystem : IXamlTypeSystem internal class NoopTypeSystem : IXamlTypeSystem
{ {
public NoopTypeSystem()
=> WellKnownTypes = new XamlTypeWellKnownTypes(this);
public IEnumerable<IXamlAssembly> Assemblies => [NoopAssembly.Instance]; public IEnumerable<IXamlAssembly> Assemblies => [NoopAssembly.Instance];
public XamlTypeWellKnownTypes WellKnownTypes { get; }
public IXamlAssembly? FindAssembly(string substring) => null; public IXamlAssembly? FindAssembly(string substring) => null;
public IXamlType? FindType(string name) => XamlPseudoType.Unresolved(name); public IXamlType? FindType(string name) => XamlPseudoType.Unresolved(name);
public IXamlType? FindType(string name, string assembly) => XamlPseudoType.Unresolved(name); public IXamlType? FindType(string name, string assembly) => XamlPseudoType.Unresolved(name);
@ -14,9 +18,8 @@ internal class NoopTypeSystem : IXamlTypeSystem
{ {
public static NoopAssembly Instance { get; } = new(); public static NoopAssembly Instance { get; } = new();
public bool Equals(IXamlAssembly other) => ReferenceEquals(this, other); public bool Equals(IXamlAssembly other) => ReferenceEquals(this, other);
public string Name { get; } = "Noop"; public string Name => "Noop";
public IReadOnlyList<IXamlCustomAttribute> CustomAttributes { get; } = []; public IReadOnlyList<IXamlCustomAttribute> CustomAttributes { get; } = [];
public IXamlType? FindType(string fullName) => XamlPseudoType.Unresolved(fullName); public IXamlType? FindType(string fullName) => XamlPseudoType.Unresolved(fullName);
} }
} }

4
src/tools/Avalonia.Generators/Compiler/RoslynTypeSystem.cs

@ -26,10 +26,14 @@ internal class RoslynTypeSystem : IXamlTypeSystem
.ToList(); .ToList();
_assemblies.AddRange(assemblySymbols); _assemblies.AddRange(assemblySymbols);
WellKnownTypes = new XamlTypeWellKnownTypes(this);
} }
public IEnumerable<IXamlAssembly> Assemblies => _assemblies; public IEnumerable<IXamlAssembly> Assemblies => _assemblies;
public XamlTypeWellKnownTypes WellKnownTypes { get; }
public IXamlAssembly? FindAssembly(string name) => public IXamlAssembly? FindAssembly(string name) =>
Assemblies Assemblies
.FirstOrDefault(a => string.Equals(a.Name, name, StringComparison.OrdinalIgnoreCase)); .FirstOrDefault(a => string.Equals(a.Name, name, StringComparison.OrdinalIgnoreCase));

1
tests/Avalonia.Generators.Tests/MiniCompilerTests.cs

@ -40,6 +40,7 @@ public class MiniCompilerTests
CSharpCompilation CSharpCompilation
.Create("BasicLib", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) .Create("BasicLib", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.AddReferences(MetadataReference.CreateFromFile(typeof(string).Assembly.Location)) .AddReferences(MetadataReference.CreateFromFile(typeof(string).Assembly.Location))
.AddReferences(MetadataReference.CreateFromFile(typeof(Uri).Assembly.Location))
.AddReferences(MetadataReference.CreateFromFile(typeof(IServiceProvider).Assembly.Location)) .AddReferences(MetadataReference.CreateFromFile(typeof(IServiceProvider).Assembly.Location))
.AddReferences(MetadataReference.CreateFromFile(typeof(ITypeDescriptorContext).Assembly.Location)) .AddReferences(MetadataReference.CreateFromFile(typeof(ITypeDescriptorContext).Assembly.Location))
.AddReferences(MetadataReference.CreateFromFile(typeof(ISupportInitialize).Assembly.Location)) .AddReferences(MetadataReference.CreateFromFile(typeof(ISupportInitialize).Assembly.Location))

1
tests/Avalonia.Generators.Tests/Views/View.cs

@ -41,6 +41,7 @@ public static class View
var compilation = CSharpCompilation var compilation = CSharpCompilation
.Create("AvaloniaLib", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) .Create("AvaloniaLib", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.AddReferences(MetadataReference.CreateFromFile(typeof(string).Assembly.Location)) .AddReferences(MetadataReference.CreateFromFile(typeof(string).Assembly.Location))
.AddReferences(MetadataReference.CreateFromFile(typeof(Uri).Assembly.Location))
.AddReferences(MetadataReference.CreateFromFile(typeof(IServiceProvider).Assembly.Location)) .AddReferences(MetadataReference.CreateFromFile(typeof(IServiceProvider).Assembly.Location))
.AddReferences(MetadataReference.CreateFromFile(typeof(ITypeDescriptorContext).Assembly.Location)) .AddReferences(MetadataReference.CreateFromFile(typeof(ITypeDescriptorContext).Assembly.Location))
.AddReferences(MetadataReference.CreateFromFile(typeof(ISupportInitialize).Assembly.Location)) .AddReferences(MetadataReference.CreateFromFile(typeof(ISupportInitialize).Assembly.Location))

Loading…
Cancel
Save