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);
var designLoaderFieldType = typeSystem
.GetType("System.Action`1")
.MakeGenericType(typeSystem.GetType("System.Object"));
.WellKnownTypes.GetActionOfT(1)
.MakeGenericType(typeSystem.WellKnownTypes.Object);
var designLoaderFieldTypeReference = (GenericInstanceType)typeSystem.GetTypeReference(designLoaderFieldType);
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.TypeSystem;
@ -28,6 +29,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
AddExtra(ClrPropertyEmitter);
AddExtra(AccessorFactoryEmitter);
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);
var nameScopeType = typeSystem.GetType("Avalonia.Controls.INameScope");
var eagerParentStackProviderInterfaceType = typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.IAvaloniaXamlIlEagerParentStackProvider");
var emit = new XamlLanguageEmitMappings<IXamlILEmitter, XamlILNodeEmitResult>
{
ProvideValueTargetPropertyEmitter = XamlIlAvaloniaPropertyHelper.EmitProvideValueTarget,
ContextTypeBuilderCallback = definition =>
{
EmitNameScopeField(rv, typeSystem, definition);
EmitEagerParentStackProvider(rv, typeSystem, definition, runtimeHelpers);
EmitNameScopeField(rv, typeSystem, definition, nameScopeType);
EmitEagerParentStackProvider(rv, typeSystem, definition, runtimeHelpers, eagerParentStackProviderInterfaceType);
}
};
return (rv, emit);
@ -88,9 +91,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
private static void EmitNameScopeField(
XamlLanguageTypeMappings mappings,
IXamlTypeSystem typeSystem,
IXamlILContextDefinition<IXamlILEmitter> definition)
IXamlILContextDefinition<IXamlILEmitter> definition,
IXamlType nameScopeType)
{
var nameScopeType = typeSystem.GetType("Avalonia.Controls.INameScope");
var field = definition.TypeBuilder.DefineField(nameScopeType,
ContextNameScopeFieldName, XamlVisibility.Public, false);
definition.ConstructorBuilder.Generator
@ -98,7 +101,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
.Ldarg(1)
.Ldtype(nameScopeType)
.EmitCall(mappings.ServiceProvider.GetMethod(new FindMethodMethodSignature("GetService",
typeSystem.GetType("System.Object"), typeSystem.GetType("System.Type"))))
typeSystem.WellKnownTypes.Object, typeSystem.WellKnownTypes.Type)))
.Stfld(field);
}
@ -107,10 +110,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
XamlLanguageTypeMappings mappings,
IXamlTypeSystem typeSystem,
IXamlILContextDefinition<IXamlILEmitter> definition,
IXamlType runtimeHelpers)
IXamlType runtimeHelpers,
IXamlType interfaceType)
{
var interfaceType = typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.IAvaloniaXamlIlEagerParentStackProvider");
definition.TypeBuilder.AddInterfaceImplementation(interfaceType);
// IReadOnlyList<object> DirectParentsStack => (IReadOnlyList<object>)ParentsStack;
@ -122,8 +124,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
var serviceProviderGetServiceMethod = mappings.ServiceProvider.GetMethod(new FindMethodMethodSignature(
"GetService",
typeSystem.GetType("System.Object"),
typeSystem.GetType("System.Type")));
typeSystem.WellKnownTypes.Object,
typeSystem.WellKnownTypes.Type));
var asEagerParentStackProviderMethod = runtimeHelpers.GetMethod(new FindMethodMethodSignature(
"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.Imaging.Bitmap"), 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(ilist.MakeGenericType(typeSystem.GetType("Avalonia.Point")),
AddType(typeSystem.WellKnownTypes.IListOfT.MakeGenericType(typeSystem.GetType("Avalonia.Point")),
typeSystem.GetType("Avalonia.Markup.Xaml.Converters.PointsListTypeConverter"));
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.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("Avalonia.Media.FontFamily"), typeSystem.GetType("Avalonia.Markup.Xaml.Converters.FontFamilyTypeConverter"));
_avaloniaList = typeSystem.GetType("Avalonia.Collections.AvaloniaList`1");
@ -270,7 +271,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
return true;
}
if (type.FullName == "Avalonia.AvaloniaProperty")
if (type.Is("Avalonia", "AvaloniaProperty"))
{
var attrType = context.GetAvaloniaTypes().InheritDataTypeFromAttribute;
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;
}
if (type.FullName == "System.TimeSpan")
if (type.Is("System", "TimeSpan"))
{
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.
var elementType = GetElementType(type, context.Configuration.WellKnownTypes);
var elementType = GetElementType(type);
if (elementType is not null)
{
string[] items;
@ -445,15 +445,16 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
return false;
}
private static IXamlType? GetElementType(IXamlType type, XamlTypeWellKnownTypes types)
private static IXamlType? GetElementType(IXamlType type)
{
if (type.IsArray)
{
return type.ArrayElementType;
}
return type.GetAllInterfaces().FirstOrDefault(i =>
i.FullName.StartsWith(types.IEnumerableT.FullName))?
return type.GetAllInterfaces().FirstOrDefault(static i =>
i.Name.StartsWith("IEnumerable`1", StringComparison.Ordinal) &&
i.Namespace == "System.Collections.Generic")?
.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 (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
&& 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();
//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 &&
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 &&
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)))
{

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))
{
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]);
}

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

@ -136,7 +136,7 @@ internal class AvaloniaXamlIlOptionMarkupExtensionTransformer : IXamlAstTransfor
try
{
var targetType = method.Parameters.Last();
if (targetType.FullName == "System.Type")
if (targetType.Is("System", "Type"))
{
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)]
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));
if(found == null)
throw new XamlTypeSystemException(
@ -174,7 +174,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
var name = Concrete ? "OfType" : "Is";
codeGen.Ldtype(TargetType);
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);
var name = _type.ToString();
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;
}
if (context.Configuration.TypeSystem.FindType("System.Collections.Generic.List`1") is not { } type)
return;
IXamlType listType = type.MakeGenericType(base.Type.GetClrType());
var add = listType.FindMethod("Add", context.Configuration.WellKnownTypes.Void, false, Type.GetClrType());
var typeArgument = Type.GetClrType();
var listType = context.Configuration.WellKnownTypes.ListOfT.MakeGenericType(typeArgument);
var add = listType.FindMethod("Add", context.Configuration.WellKnownTypes.Void, false, typeArgument);
if (add == null)
return;
@ -338,7 +337,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
foreach (var s in _queries)
{
codeGen.Dup();
context.Emit(s, codeGen, Type.GetClrType());
context.Emit(s, codeGen, typeArgument);
codeGen.EmitCall(add, true);
}
@ -399,11 +398,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
return;
}
if (context.Configuration.TypeSystem.FindType("System.Collections.Generic.List`1") is not { } type)
return;
IXamlType listType = type.MakeGenericType(base.Type.GetClrType());
var add = listType.FindMethod("Add", context.Configuration.WellKnownTypes.Void, false, Type.GetClrType());
var typeArgument = Type.GetClrType();
var listType = context.Configuration.WellKnownTypes.ListOfT.MakeGenericType(typeArgument);
var add = listType.FindMethod("Add", context.Configuration.WellKnownTypes.Void, false, typeArgument);
if (add == null)
return;
@ -417,7 +414,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
foreach (var s in _queries)
{
codeGen.Dup();
context.Emit(s, codeGen, Type.GetClrType());
context.Emit(s, codeGen, typeArgument);
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);
}
if (attributes.All(attribute => attribute.Type.FullName != "Avalonia.Controls.ResolveByNameAttribute"))
if (attributes.All(attribute => !attribute.Type.Is("Avalonia.Controls", "ResolveByNameAttribute")))
return node;
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.
if (clrType.FullName == "System.String")
if (clrType.Is("System", "String"))
{
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)]
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));
codeGen.EmitCall(found);
}
@ -346,7 +346,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
var name = Concrete ? "OfType" : "Is";
codeGen.Ldtype(TargetType);
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);
var name = _type.ToString();
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,
m => m.Name == "PropertyEquals"
&& m.Parameters.Count == 3
&& m.Parameters[1].FullName == "Avalonia.AvaloniaProperty"
&& m.Parameters[2].Equals(context.Configuration.WellKnownTypes.Object));
&& m.Parameters[1].Is("Avalonia", "AvaloniaProperty")
&& m.Parameters[2].Is("System", "Object"));
}
}
@ -508,8 +508,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
EmitCall(context, codeGen,
m => m.Name == "PropertyEquals"
&& m.Parameters.Count == 3
&& m.Parameters[1].FullName == "Avalonia.AvaloniaProperty"
&& m.Parameters[2].Equals(context.Configuration.WellKnownTypes.Object));
&& m.Parameters[1].Is("Avalonia", "AvaloniaProperty")
&& m.Parameters[2].Is("System", "Object"));
}
}
@ -564,7 +564,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
_selectors[0].Emit(context, codeGen);
return;
}
var listType = context.Configuration.TypeSystem.GetType("System.Collections.Generic.List`1")
var listType = context.Configuration.WellKnownTypes.ListOfT
.MakeGenericType(base.Type.GetClrType());
var add = listType.GetMethod("Add", context.Configuration.WellKnownTypes.Void, false, Type.GetClrType());
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)
{
if (!(node is XamlAstObjectNode on
&& on.Type.GetClrType().FullName == "Avalonia.Styling.Setter"))
&& on.Type.GetClrType().Is("Avalonia.Styling", "Setter")))
return node;
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 interactiveType = xkt.Interactivity.Interactive;
var routedEventType = xkt.Interactivity.RoutedEvent;
var AddHandlerT = xkt.Interactivity.AddHandlerT;
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 Long { get; }
public IXamlType Uri { get; }
public IXamlType TaskOfT { get; }
public IXamlType IDictionaryT { get; }
public IXamlType WeakReferenceOfT { get; }
public IXamlType IObservableOfT { get; }
public IXamlType FontFamily { get; }
public IXamlConstructor FontFamilyConstructorUriName { get; }
public IXamlType Thickness { get; }
@ -129,6 +132,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public IXamlType Style { get; }
public IXamlType Container { get; }
public IXamlType Styles { get; }
public IXamlType StyleQueries { get; }
public IXamlType Selectors { get; }
public IXamlType ControlTheme { get; }
public IXamlType WindowTransparencyLevel { get; }
public IXamlType IReadOnlyListOfT { get; }
@ -149,22 +154,21 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public IXamlMethod AddHandlerT { get; }
[UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)]
internal InteractivityWellKnownTypes(TransformerConfiguration cfg)
internal InteractivityWellKnownTypes(IXamlTypeSystem typeSystem, XamlTypeWellKnownTypes wellKnownTypes)
{
var ts = cfg.TypeSystem;
Interactive = ts.GetType("Avalonia.Interactivity.Interactive");
RoutedEvent = ts.GetType("Avalonia.Interactivity.RoutedEvent");
RoutedEventArgs = ts.GetType("Avalonia.Interactivity.RoutedEventArgs");
var eventHanlderT = ts.GetType("System.EventHandler`1");
Interactive = typeSystem.GetType("Avalonia.Interactivity.Interactive");
RoutedEvent = typeSystem.GetType("Avalonia.Interactivity.RoutedEvent");
RoutedEventArgs = typeSystem.GetType("Avalonia.Interactivity.RoutedEventArgs");
var eventHanlderT = typeSystem.GetType("System.EventHandler`1");
RoutedEventHandler = eventHanlderT.MakeGenericType(RoutedEventArgs);
AddHandler = Interactive.GetMethod(m => m.IsPublic
&& !m.IsStatic
&& m.Name == "AddHandler"
&& m.Parameters.Count == 4
&& m.Parameters[0].Equals(RoutedEvent)
&& m.Parameters[1].Equals(cfg.WellKnownTypes.Delegate)
&& m.Parameters[1].Equals(wellKnownTypes.Delegate)
&& m.Parameters[2].IsEnum
&& m.Parameters[3].Equals(cfg.WellKnownTypes.Boolean)
&& m.Parameters[3].Equals(wellKnownTypes.Boolean)
);
AddHandlerT = Interactive.GetMethod(m => m.IsPublic
&& !m.IsStatic
@ -172,9 +176,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
&& m.Parameters.Count == 4
&& RoutedEvent.IsAssignableFrom(m.Parameters[0])
&& 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[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; }
[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;
AvaloniaObject = cfg.TypeSystem.GetType("Avalonia.AvaloniaObject");
AvaloniaObjectExtensions = cfg.TypeSystem.GetType("Avalonia.AvaloniaObjectExtensions");
AvaloniaProperty = cfg.TypeSystem.GetType("Avalonia.AvaloniaProperty");
AvaloniaPropertyT = cfg.TypeSystem.GetType("Avalonia.AvaloniaProperty`1");
StyledPropertyT = cfg.TypeSystem.GetType("Avalonia.StyledProperty`1");
AvaloniaAttachedPropertyT = cfg.TypeSystem.GetType("Avalonia.AttachedProperty`1");
BindingPriority = cfg.TypeSystem.GetType("Avalonia.Data.BindingPriority");
XamlIlTypes = typeSystem.WellKnownTypes;
AvaloniaObject = typeSystem.GetType("Avalonia.AvaloniaObject");
AvaloniaObjectExtensions = typeSystem.GetType("Avalonia.AvaloniaObjectExtensions");
AvaloniaProperty = typeSystem.GetType("Avalonia.AvaloniaProperty");
AvaloniaPropertyT = typeSystem.GetType("Avalonia.AvaloniaProperty`1");
StyledPropertyT = typeSystem.GetType("Avalonia.StyledProperty`1");
AvaloniaAttachedPropertyT = typeSystem.GetType("Avalonia.AttachedProperty`1");
BindingPriority = typeSystem.GetType("Avalonia.Data.BindingPriority");
AvaloniaObjectSetStyledPropertyValue = AvaloniaObject
.GetMethod(m => m.IsPublic && !m.IsStatic && m.Name == "SetValue"
&& m.Parameters.Count == 3
&& m.Parameters[0].Name == "StyledProperty`1"
&& m.Parameters[2].Equals(BindingPriority));
BindingBase = cfg.TypeSystem.GetType("Avalonia.Data.BindingBase");
BindingExpressionBase = cfg.TypeSystem.GetType("Avalonia.Data.BindingExpressionBase");
MultiBinding = cfg.TypeSystem.GetType("Avalonia.Data.MultiBinding");
IDisposable = cfg.TypeSystem.GetType("System.IDisposable");
ICommand = cfg.TypeSystem.GetType("System.Windows.Input.ICommand");
Transitions = cfg.TypeSystem.GetType("Avalonia.Animation.Transitions");
AssignBindingAttribute = cfg.TypeSystem.GetType("Avalonia.Data.AssignBindingAttribute");
DependsOnAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.DependsOnAttribute");
DataTypeAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.DataTypeAttribute");
InheritDataTypeFromItemsAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.InheritDataTypeFromItemsAttribute");
InheritDataTypeFromAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.InheritDataTypeFromAttribute");
MarkupExtensionOptionAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.MarkupExtensionOptionAttribute");
MarkupExtensionDefaultOptionAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.MarkupExtensionDefaultOptionAttribute");
ControlTemplateScopeAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.ControlTemplateScopeAttribute");
AvaloniaListAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.AvaloniaListAttribute");
AvaloniaList = cfg.TypeSystem.GetType("Avalonia.Collections.AvaloniaList`1");
OnExtensionType = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.On");
BindingBase = typeSystem.GetType("Avalonia.Data.BindingBase");
BindingExpressionBase = typeSystem.GetType("Avalonia.Data.BindingExpressionBase");
MultiBinding = typeSystem.GetType("Avalonia.Data.MultiBinding");
IDisposable = typeSystem.GetType("System.IDisposable");
ICommand = typeSystem.GetType("System.Windows.Input.ICommand");
Transitions = typeSystem.GetType("Avalonia.Animation.Transitions");
AssignBindingAttribute = typeSystem.GetType("Avalonia.Data.AssignBindingAttribute");
DependsOnAttribute = typeSystem.GetType("Avalonia.Metadata.DependsOnAttribute");
DataTypeAttribute = typeSystem.GetType("Avalonia.Metadata.DataTypeAttribute");
InheritDataTypeFromItemsAttribute = typeSystem.GetType("Avalonia.Metadata.InheritDataTypeFromItemsAttribute");
InheritDataTypeFromAttribute = typeSystem.GetType("Avalonia.Metadata.InheritDataTypeFromAttribute");
MarkupExtensionOptionAttribute = typeSystem.GetType("Avalonia.Metadata.MarkupExtensionOptionAttribute");
MarkupExtensionDefaultOptionAttribute = typeSystem.GetType("Avalonia.Metadata.MarkupExtensionDefaultOptionAttribute");
ControlTemplateScopeAttribute = typeSystem.GetType("Avalonia.Metadata.ControlTemplateScopeAttribute");
AvaloniaListAttribute = typeSystem.GetType("Avalonia.Metadata.AvaloniaListAttribute");
AvaloniaList = typeSystem.GetType("Avalonia.Collections.AvaloniaList`1");
OnExtensionType = typeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.On");
AvaloniaObjectBindMethod = AvaloniaObject.GetMethod("Bind", BindingExpressionBase, false, AvaloniaProperty, BindingBase);
UnsetValueType = cfg.TypeSystem.GetType("Avalonia.UnsetValueType");
StyledElement = cfg.TypeSystem.GetType("Avalonia.StyledElement");
INameScope = cfg.TypeSystem.GetType("Avalonia.Controls.INameScope");
UnsetValueType = typeSystem.GetType("Avalonia.UnsetValueType");
StyledElement = typeSystem.GetType("Avalonia.StyledElement");
INameScope = typeSystem.GetType("Avalonia.Controls.INameScope");
INameScopeRegister = INameScope.GetMethod(
new FindMethodMethodSignature("Register", XamlIlTypes.Void,
XamlIlTypes.String, XamlIlTypes.Object)
@ -236,42 +240,45 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
DeclaringOnly = true,
IsExactMatch = true
});
NameScope = cfg.TypeSystem.GetType("Avalonia.Controls.NameScope");
NameScope = typeSystem.GetType("Avalonia.Controls.NameScope");
NameScopeSetNameScope = NameScope.GetMethod(new FindMethodMethodSignature("SetNameScope",
XamlIlTypes.Void, StyledElement, INameScope)
{ IsStatic = true });
AvaloniaObjectSetValueMethod = AvaloniaObject.GetMethod("SetValue", IDisposable,
false, AvaloniaProperty, XamlIlTypes.Object, BindingPriority);
IPropertyInfo = cfg.TypeSystem.GetType("Avalonia.Data.Core.IPropertyInfo");
ClrPropertyInfo = cfg.TypeSystem.GetType("Avalonia.Data.Core.ClrPropertyInfo");
IPropertyAccessor = cfg.TypeSystem.GetType("Avalonia.Data.Core.Plugins.IPropertyAccessor");
PropertyInfoAccessorFactory = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.PropertyInfoAccessorFactory");
CompiledBinding = cfg.TypeSystem.GetType("Avalonia.Data.CompiledBinding");
CompiledBindingPathBuilder = cfg.TypeSystem.GetType("Avalonia.Data.CompiledBindingPathBuilder");
CompiledBindingPath = cfg.TypeSystem.GetType("Avalonia.Data.CompiledBindingPath");
CompiledBindingExtension = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindingExtension");
ResolveByNameExtension = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.ResolveByNameExtension");
DataTemplate = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.Templates.DataTemplate");
IDataTemplate = cfg.TypeSystem.GetType("Avalonia.Controls.Templates.IDataTemplate");
Control = cfg.TypeSystem.GetType("Avalonia.Controls.Control");
ContentControl = cfg.TypeSystem.GetType("Avalonia.Controls.ContentControl");
ITemplateOfControl = cfg.TypeSystem.GetType("Avalonia.Controls.ITemplate`1").MakeGenericType(Control);
ItemsControl = cfg.TypeSystem.GetType("Avalonia.Controls.ItemsControl");
ReflectionBindingExtension = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.ReflectionBindingExtension");
RelativeSource = cfg.TypeSystem.GetType("Avalonia.Data.RelativeSource");
UInt = cfg.TypeSystem.GetType("System.UInt32");
Int = cfg.TypeSystem.GetType("System.Int32");
Long = cfg.TypeSystem.GetType("System.Int64");
Uri = cfg.TypeSystem.GetType("System.Uri");
IDictionaryT = cfg.TypeSystem.GetType("System.Collections.Generic.IDictionary`2");
FontFamily = cfg.TypeSystem.GetType("Avalonia.Media.FontFamily");
IPropertyInfo = typeSystem.GetType("Avalonia.Data.Core.IPropertyInfo");
ClrPropertyInfo = typeSystem.GetType("Avalonia.Data.Core.ClrPropertyInfo");
IPropertyAccessor = typeSystem.GetType("Avalonia.Data.Core.Plugins.IPropertyAccessor");
PropertyInfoAccessorFactory = typeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.PropertyInfoAccessorFactory");
CompiledBinding = typeSystem.GetType("Avalonia.Data.CompiledBinding");
CompiledBindingPathBuilder = typeSystem.GetType("Avalonia.Data.CompiledBindingPathBuilder");
CompiledBindingPath = typeSystem.GetType("Avalonia.Data.CompiledBindingPath");
CompiledBindingExtension = typeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindingExtension");
ResolveByNameExtension = typeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.ResolveByNameExtension");
DataTemplate = typeSystem.GetType("Avalonia.Markup.Xaml.Templates.DataTemplate");
IDataTemplate = typeSystem.GetType("Avalonia.Controls.Templates.IDataTemplate");
Control = typeSystem.GetType("Avalonia.Controls.Control");
ContentControl = typeSystem.GetType("Avalonia.Controls.ContentControl");
ITemplateOfControl = typeSystem.GetType("Avalonia.Controls.ITemplate`1").MakeGenericType(Control);
ItemsControl = typeSystem.GetType("Avalonia.Controls.ItemsControl");
ReflectionBindingExtension = typeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.ReflectionBindingExtension");
RelativeSource = typeSystem.GetType("Avalonia.Data.RelativeSource");
UInt = typeSystem.GetType("System.UInt32");
Int = typeSystem.GetType("System.Int32");
Long = typeSystem.GetType("System.Int64");
Uri = typeSystem.GetType("System.Uri");
TaskOfT = typeSystem.GetType("System.Threading.Tasks.Task`1");
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 });
ThemeVariant = cfg.TypeSystem.GetType("Avalonia.Styling.ThemeVariant");
WindowTransparencyLevel = cfg.TypeSystem.GetType("Avalonia.Controls.WindowTransparencyLevel");
ThemeVariant = typeSystem.GetType("Avalonia.Styling.ThemeVariant");
WindowTransparencyLevel = typeSystem.GetType("Avalonia.Controls.WindowTransparencyLevel");
(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());
return (type, ctor);
@ -284,70 +291,72 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
(Matrix, MatrixFullConstructor) = GetNumericTypeInfo("Avalonia.Matrix", XamlIlTypes.Double, 6);
(CornerRadius, CornerRadiusFullConstructor) = GetNumericTypeInfo("Avalonia.CornerRadius", XamlIlTypes.Double, 4);
RelativeUnit = cfg.TypeSystem.GetType("Avalonia.RelativeUnit");
RelativePoint = cfg.TypeSystem.GetType("Avalonia.RelativePoint");
RelativeUnit = typeSystem.GetType("Avalonia.RelativeUnit");
RelativePoint = typeSystem.GetType("Avalonia.RelativePoint");
RelativePointFullConstructor = RelativePoint.GetConstructor(new List<IXamlType> { XamlIlTypes.Double, XamlIlTypes.Double, RelativeUnit });
GridLength = cfg.TypeSystem.GetType("Avalonia.Controls.GridLength");
GridLengthConstructorValueType = GridLength.GetConstructor(new List<IXamlType> { XamlIlTypes.Double, cfg.TypeSystem.GetType("Avalonia.Controls.GridUnitType") });
Color = cfg.TypeSystem.GetType("Avalonia.Media.Color");
StandardCursorType = cfg.TypeSystem.GetType("Avalonia.Input.StandardCursorType");
Cursor = cfg.TypeSystem.GetType("Avalonia.Input.Cursor");
GridLength = typeSystem.GetType("Avalonia.Controls.GridLength");
GridLengthConstructorValueType = GridLength.GetConstructor(new List<IXamlType> { XamlIlTypes.Double, typeSystem.GetType("Avalonia.Controls.GridUnitType") });
Color = typeSystem.GetType("Avalonia.Media.Color");
StandardCursorType = typeSystem.GetType("Avalonia.Input.StandardCursorType");
Cursor = typeSystem.GetType("Avalonia.Input.Cursor");
CursorTypeConstructor = Cursor.GetConstructor(new List<IXamlType> { StandardCursorType });
ColumnDefinition = cfg.TypeSystem.GetType("Avalonia.Controls.ColumnDefinition");
ColumnDefinitions = cfg.TypeSystem.GetType("Avalonia.Controls.ColumnDefinitions");
RowDefinition = cfg.TypeSystem.GetType("Avalonia.Controls.RowDefinition");
RowDefinitions = cfg.TypeSystem.GetType("Avalonia.Controls.RowDefinitions");
Classes = cfg.TypeSystem.GetType("Avalonia.Controls.Classes");
ColumnDefinition = typeSystem.GetType("Avalonia.Controls.ColumnDefinition");
ColumnDefinitions = typeSystem.GetType("Avalonia.Controls.ColumnDefinitions");
RowDefinition = typeSystem.GetType("Avalonia.Controls.RowDefinition");
RowDefinitions = typeSystem.GetType("Avalonia.Controls.RowDefinitions");
Classes = typeSystem.GetType("Avalonia.Controls.Classes");
StyledElementClassesProperty =
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,
cfg.WellKnownTypes.String,
BindingBase, cfg.WellKnownTypes.Object);
typeSystem.WellKnownTypes.String,
BindingBase, typeSystem.WellKnownTypes.Object);
IBrush = cfg.TypeSystem.GetType("Avalonia.Media.IBrush");
ImmutableSolidColorBrush = cfg.TypeSystem.GetType("Avalonia.Media.Immutable.ImmutableSolidColorBrush");
IBrush = typeSystem.GetType("Avalonia.Media.IBrush");
ImmutableSolidColorBrush = typeSystem.GetType("Avalonia.Media.Immutable.ImmutableSolidColorBrush");
ImmutableSolidColorBrushConstructorColor = ImmutableSolidColorBrush.GetConstructor(new List<IXamlType> { UInt });
TypeUtilities = cfg.TypeSystem.GetType("Avalonia.Utilities.TypeUtilities");
TextDecorationCollection = cfg.TypeSystem.GetType("Avalonia.Media.TextDecorationCollection");
TextDecorations = cfg.TypeSystem.GetType("Avalonia.Media.TextDecorations");
TextTrimming = cfg.TypeSystem.GetType("Avalonia.Media.TextTrimming");
SetterBase = cfg.TypeSystem.GetType("Avalonia.Styling.SetterBase");
Setter = cfg.TypeSystem.GetType("Avalonia.Styling.Setter");
IStyle = cfg.TypeSystem.GetType("Avalonia.Styling.IStyle");
StyleInclude = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.Styling.StyleInclude");
ResourceInclude = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.Styling.ResourceInclude");
MergeResourceInclude = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.Styling.MergeResourceInclude");
IResourceDictionary = cfg.TypeSystem.GetType("Avalonia.Controls.IResourceDictionary");
ResourceDictionary = cfg.TypeSystem.GetType("Avalonia.Controls.ResourceDictionary");
TypeUtilities = typeSystem.GetType("Avalonia.Utilities.TypeUtilities");
TextDecorationCollection = typeSystem.GetType("Avalonia.Media.TextDecorationCollection");
TextDecorations = typeSystem.GetType("Avalonia.Media.TextDecorations");
TextTrimming = typeSystem.GetType("Avalonia.Media.TextTrimming");
SetterBase = typeSystem.GetType("Avalonia.Styling.SetterBase");
Setter = typeSystem.GetType("Avalonia.Styling.Setter");
IStyle = typeSystem.GetType("Avalonia.Styling.IStyle");
StyleInclude = typeSystem.GetType("Avalonia.Markup.Xaml.Styling.StyleInclude");
ResourceInclude = typeSystem.GetType("Avalonia.Markup.Xaml.Styling.ResourceInclude");
MergeResourceInclude = typeSystem.GetType("Avalonia.Markup.Xaml.Styling.MergeResourceInclude");
IResourceDictionary = typeSystem.GetType("Avalonia.Controls.IResourceDictionary");
ResourceDictionary = typeSystem.GetType("Avalonia.Controls.ResourceDictionary");
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,
cfg.TypeSystem.GetType("Avalonia.Controls.IDeferredContent"));
typeSystem.GetType("Avalonia.Controls.IDeferredContent"));
ResourceDictionaryEnsureCapacity = ResourceDictionary.GetMethod("EnsureCapacity", XamlIlTypes.Void, true, XamlIlTypes.Int32);
ResourceDictionaryGetCount = ResourceDictionary.GetMethod("get_Count", XamlIlTypes.Int32, true);
IThemeVariantProvider = cfg.TypeSystem.GetType("Avalonia.Controls.IThemeVariantProvider");
UriKind = cfg.TypeSystem.GetType("System.UriKind");
UriConstructor = Uri.GetConstructor(new List<IXamlType>() { cfg.WellKnownTypes.String, UriKind });
Style = cfg.TypeSystem.GetType("Avalonia.Styling.Style");
Container = cfg.TypeSystem.GetType("Avalonia.Styling.ContainerQuery");
Styles = cfg.TypeSystem.GetType("Avalonia.Styling.Styles");
ControlTheme = cfg.TypeSystem.GetType("Avalonia.Styling.ControlTheme");
ControlTemplate = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.Templates.ControlTemplate");
IReadOnlyListOfT = cfg.TypeSystem.GetType("System.Collections.Generic.IReadOnlyList`1");
EventHandlerT = cfg.TypeSystem.GetType("System.EventHandler`1");
Interactivity = new InteractivityWellKnownTypes(cfg);
IThemeVariantProvider = typeSystem.GetType("Avalonia.Controls.IThemeVariantProvider");
UriKind = typeSystem.GetType("System.UriKind");
UriConstructor = Uri.GetConstructor(new List<IXamlType>() { typeSystem.WellKnownTypes.String, UriKind });
Style = typeSystem.GetType("Avalonia.Styling.Style");
Container = typeSystem.GetType("Avalonia.Styling.ContainerQuery");
Styles = typeSystem.GetType("Avalonia.Styling.Styles");
StyleQueries = typeSystem.GetType("Avalonia.Styling.StyleQueries");
Selectors = typeSystem.GetType("Avalonia.Styling.Selectors");
ControlTheme = typeSystem.GetType("Avalonia.Styling.ControlTheme");
ControlTemplate = typeSystem.GetType("Avalonia.Markup.Xaml.Templates.ControlTemplate");
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",
returnType: AvaloniaProperty,
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([
XamlIlTypes.Int32, XamlIlTypes.Int32, XamlIlTypes.String
]);
@ -360,28 +369,16 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
static class AvaloniaXamlIlWellKnownTypesExtensions
{
public static AvaloniaXamlIlWellKnownTypes GetAvaloniaTypes(this TransformerConfiguration cfg)
=> cfg.GetExtra<AvaloniaXamlIlWellKnownTypes>();
public static AvaloniaXamlIlWellKnownTypes GetAvaloniaTypes(this AstTransformationContext ctx)
{
if (ctx.TryGetItem<AvaloniaXamlIlWellKnownTypes>(out var rv))
return rv;
ctx.SetItem(rv = new AvaloniaXamlIlWellKnownTypes(ctx.Configuration));
return rv;
}
=> ctx.Configuration.GetAvaloniaTypes();
public static AvaloniaXamlIlWellKnownTypes GetAvaloniaTypes(this XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> ctx)
{
if (ctx.TryGetItem<AvaloniaXamlIlWellKnownTypes>(out var rv))
return rv;
ctx.SetItem(rv = new AvaloniaXamlIlWellKnownTypes(ctx.Configuration));
return rv;
}
=> ctx.Configuration.GetAvaloniaTypes();
public static AvaloniaXamlIlWellKnownTypes GetAvaloniaTypes(this AstGroupTransformationContext ctx)
{
if (ctx.TryGetItem<AvaloniaXamlIlWellKnownTypes>(out var rv))
return rv;
ctx.SetItem(rv = new AvaloniaXamlIlWellKnownTypes(ctx.Configuration));
return rv;
}
=> ctx.Configuration.GetAvaloniaTypes();
}
}

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

@ -155,13 +155,14 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
{
IXamlType targetType = targetTypeResolver();
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;
}
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)
@ -171,7 +172,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
}
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)
{
@ -260,7 +261,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
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));
break;
@ -752,13 +753,12 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
IXamlType specificDelegateType;
if (Method.ReturnType == context.Configuration.WellKnownTypes.Void && Method.Parameters.Count == 0)
{
specificDelegateType = context.Configuration.TypeSystem
.GetType("System.Action");
specificDelegateType = context.Configuration.WellKnownTypes.Action;
}
else if (Method.ReturnType == context.Configuration.WellKnownTypes.Void && Method.Parameters.Count <= 16)
{
specificDelegateType = context.Configuration.TypeSystem
.GetType($"System.Action`{Method.Parameters.Count}")
specificDelegateType = context.Configuration.WellKnownTypes
.GetActionOfT(Method.Parameters.Count)
.MakeGenericType(Method.Parameters);
}
else if (Method.Parameters.Count <= 16)
@ -766,8 +766,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
List<IXamlType> genericParameters = new();
genericParameters.AddRange(Method.Parameters);
genericParameters.Add(Method.ReturnType);
specificDelegateType = context.Configuration.TypeSystem
.GetType($"System.Func`{Method.Parameters.Count + 1}")
specificDelegateType = context.Configuration.WellKnownTypes
.GetFuncOfT(Method.Parameters.Count + 1)
.MakeGenericType(genericParameters);
}
else
@ -836,9 +836,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
.Ldstr(_executeMethod.Name)
.Ldnull()
.Ldftn(trampolineBuilder.EmitCommandExecuteTrampoline(context, _executeMethod))
.Newobj(context.Configuration.TypeSystem.GetType("System.Action`2")
.Newobj(context.Configuration.WellKnownTypes.GetActionOfT(2)
.MakeGenericType(objectType, objectType)
.GetConstructor(new() { objectType, context.Configuration.TypeSystem.GetType("System.IntPtr") }));
.GetConstructor(new() { objectType, context.Configuration.WellKnownTypes.IntPtr }));
if (_canExecuteMethod is null)
{
@ -849,9 +849,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
codeGen
.Ldnull()
.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)
.GetConstructor(new() { objectType, context.Configuration.TypeSystem.GetType("System.IntPtr") }));
.GetConstructor(new() { objectType, context.Configuration.WellKnownTypes.IntPtr }));
}
if (_dependsOnProperties is { Count:> 0 })
@ -901,7 +901,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
[UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)]
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>()
.Emit(context, codeGen, _property, _values, _indexerKey);
@ -948,7 +948,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
[UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)]
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));
codeGen.Ldc_I4(_values.Count)
.Newarr(intType)
@ -1011,7 +1011,6 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
[UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)]
public XamlILNodeEmitResult Emit(XamlIlEmitContext context, IXamlILEmitter codeGen)
{
var intType = context.Configuration.TypeSystem.GetType("System.Int32");
var types = context.GetAvaloniaTypes();
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)
{
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)
{
IsStatic = isStatic
@ -53,7 +53,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
[UnconditionalSuppressMessage("Trimming", "IL2122", Justification = TrimmingMessages.TypesInCoreOrAvaloniaAssembly)]
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)
{
_indexerClosureType = InitializeClosureType(context);
@ -69,8 +69,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
private IXamlType InitializeClosureType(XamlIlEmitContext context)
{
var types = context.GetAvaloniaTypes();
var intType = context.Configuration.TypeSystem.GetType("System.Int32");
var weakReferenceType = context.Configuration.TypeSystem.GetType("System.WeakReference`1").MakeGenericType(context.Configuration.WellKnownTypes.Object);
var intType = context.Configuration.WellKnownTypes.Int32;
var weakReferenceType = types.WeakReferenceOfT.MakeGenericType(context.Configuration.WellKnownTypes.Object);
var indexAccessorFactoryMethod = context.GetAvaloniaTypes().PropertyInfoAccessorFactory.GetMethod(
new FindMethodMethodSignature(
"CreateIndexerPropertyAccessor",
@ -109,8 +109,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
private IXamlType EmitCreateAccessorFactoryDelegate(XamlIlEmitContext context, IXamlILEmitter codeGen)
{
var types = context.GetAvaloniaTypes();
var weakReferenceType = context.Configuration.TypeSystem.GetType("System.WeakReference`1").MakeGenericType(context.Configuration.WellKnownTypes.Object);
var funcType = context.Configuration.TypeSystem.GetType("System.Func`3").MakeGenericType(
var weakReferenceType = types.WeakReferenceOfT.MakeGenericType(context.Configuration.WellKnownTypes.Object);
var funcType = context.Configuration.WellKnownTypes.GetFuncOfT(3).MakeGenericType(
weakReferenceType,
types.IPropertyInfo,
types.IPropertyAccessor);

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

@ -5,7 +5,11 @@ namespace Avalonia.Generators.Compiler;
internal class NoopTypeSystem : IXamlTypeSystem
{
public NoopTypeSystem()
=> WellKnownTypes = new XamlTypeWellKnownTypes(this);
public IEnumerable<IXamlAssembly> Assemblies => [NoopAssembly.Instance];
public XamlTypeWellKnownTypes WellKnownTypes { get; }
public IXamlAssembly? FindAssembly(string substring) => null;
public IXamlType? FindType(string name) => 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 bool Equals(IXamlAssembly other) => ReferenceEquals(this, other);
public string Name { get; } = "Noop";
public string Name => "Noop";
public IReadOnlyList<IXamlCustomAttribute> CustomAttributes { get; } = [];
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();
_assemblies.AddRange(assemblySymbols);
WellKnownTypes = new XamlTypeWellKnownTypes(this);
}
public IEnumerable<IXamlAssembly> Assemblies => _assemblies;
public XamlTypeWellKnownTypes WellKnownTypes { get; }
public IXamlAssembly? FindAssembly(string name) =>
Assemblies
.FirstOrDefault(a => string.Equals(a.Name, name, StringComparison.OrdinalIgnoreCase));

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

@ -40,6 +40,7 @@ public class MiniCompilerTests
CSharpCompilation
.Create("BasicLib", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.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(ITypeDescriptorContext).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
.Create("AvaloniaLib", options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.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(ITypeDescriptorContext).Assembly.Location))
.AddReferences(MetadataReference.CreateFromFile(typeof(ISupportInitialize).Assembly.Location))

Loading…
Cancel
Save