From 1cf15339c4e71d493fd93dd79434ce0033dd474c Mon Sep 17 00:00:00 2001 From: Julien Lebosquain Date: Thu, 16 May 2024 03:12:19 +0200 Subject: [PATCH 1/5] Nullable annotations for projects using XamlX --- .../NullableAttributes.cs | 162 +++++------------- .../Avalonia.Build.Tasks.csproj | 13 +- .../Avalonia.Controls.ColorPicker.csproj | 2 +- .../Avalonia.Markup.Xaml.Loader.csproj | 1 + .../AvaloniaXamlIlRuntimeCompiler.cs | 58 ++++--- .../AvaloniaXamlIlFontFamilyAstNode.cs | 4 +- .../AvaloniaXamlIlCompiler.cs | 8 +- .../AvaloniaXamlIlCompilerConfiguration.cs | 13 +- .../AvaloniaXamlIlLanguage.cs | 50 +++--- .../AvaloniaXamlIlLanguageParseIntrinsics.cs | 29 ++-- .../IXamlAstGroupTransformer.cs | 7 +- .../XamlIncludeGroupTransformer.cs | 4 +- .../XamlMergeResourceGroupTransformer.cs | 3 +- .../Transformers/AddNameScopeRegistration.cs | 10 +- .../AvaloniaBindingExtensionTransformer.cs | 5 +- .../AvaloniaXamlIlBindingPathParser.cs | 32 ++-- .../AvaloniaXamlIlBindingPathTransformer.cs | 12 +- .../AvaloniaXamlIlClassesPropertyResolver.cs | 2 +- ...valoniaXamlIlDataContextTypeTransformer.cs | 24 ++- ...aloniaXamlIlDeferredResourceTransformer.cs | 6 +- ...reResourceDictionaryCapacityTransformer.cs | 4 +- ...aXamlIlOptionMarkupExtensionTransformer.cs | 33 ++-- .../AvaloniaXamlIlPropertyPathTransformer.cs | 35 ++-- ...mlIlReorderClassesPropertiesTransformer.cs | 4 +- ...valoniaXamlIlRootObjectScopeTransformer.cs | 4 +- .../AvaloniaXamlIlSelectorTransformer.cs | 72 ++++---- .../AvaloniaXamlIlSetterTransformer.cs | 25 ++- ...iaXamlIlThemeVariantProviderTransformer.cs | 3 +- ...mlIlTransformInstanceAttachedProperties.cs | 14 +- .../AvaloniaXamlIlWellKnownTypes.cs | 31 ++-- .../Visitors/NameScopeRegistrationVisitor.cs | 2 +- .../XamlIlAvaloniaPropertyHelper.cs | 43 +++-- .../XamlIlBindingPathHelper.cs | 101 ++++++----- .../XamlIlClrPropertyInfoHelper.cs | 23 ++- ...amlIlPropertyInfoAccessorFactoryEmitter.cs | 4 +- .../XamlIlTrampolineBuilder.cs | 4 +- .../Avalonia.Markup.Xaml.Loader/xamlil.github | 2 +- .../XamlIl/Runtime/XamlIlRuntimeHelpers.cs | 2 +- .../Avalonia.Designer.HostApp.csproj | 3 +- .../DesignXamlLoader.cs | 6 +- .../Avalonia.Generators.csproj | 12 +- .../Common/Domain/IViewResolver.cs | 2 +- .../Common/XamlXViewResolver.cs | 16 +- .../Compiler/RoslynTypeSystem.cs | 63 ++++--- .../GeneratorContextExtensions.cs | 2 +- .../AvaloniaNameSourceGenerator.cs | 2 +- .../InitializeComponentTests.cs | 3 +- .../OnlyProperties/OnlyPropertiesTests.cs | 3 +- .../XamlXClassResolverTests.cs | 1 + .../XamlXNameResolverTests.cs | 1 + 50 files changed, 475 insertions(+), 490 deletions(-) rename src/Avalonia.Base/{Metadata => Compatibility}/NullableAttributes.cs (62%) diff --git a/src/Avalonia.Base/Metadata/NullableAttributes.cs b/src/Avalonia.Base/Compatibility/NullableAttributes.cs similarity index 62% rename from src/Avalonia.Base/Metadata/NullableAttributes.cs rename to src/Avalonia.Base/Compatibility/NullableAttributes.cs index b6f0f3a47c5..39e0f39e593 100644 --- a/src/Avalonia.Base/Metadata/NullableAttributes.cs +++ b/src/Avalonia.Base/Compatibility/NullableAttributes.cs @@ -1,63 +1,30 @@ -#pragma warning disable MA0048 // File name must match type name -#define INTERNAL_NULLABLE_ATTRIBUTES - -// https://github.com/dotnet/corefx/blob/48363ac826ccf66fbe31a5dcb1dc2aab9a7dd768/src/Common/src/CoreLib/System/Diagnostics/CodeAnalysis/NullableAttributes.cs +// https://raw.githubusercontent.com/dotnet/runtime/753648476b64946b8f5f4d25e1294adbabd3165b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. namespace System.Diagnostics.CodeAnalysis { -#if NETSTANDARD2_0 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NET45 || NET451 || NET452 || NET6 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48 +#if !NET6_0_OR_GREATER /// Specifies that null is allowed as an input even if the corresponding type disallows it. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class AllowNullAttribute : Attribute - { } + internal sealed class AllowNullAttribute : Attribute { } /// Specifies that null is disallowed as an input even if the corresponding type allows it. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class DisallowNullAttribute : Attribute - { } + internal sealed class DisallowNullAttribute : Attribute { } /// Specifies that an output may be null even if the corresponding type disallows it. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class MaybeNullAttribute : Attribute - { } + internal sealed class MaybeNullAttribute : Attribute { } - /// Specifies that an output will not be null even if the corresponding type allows it. + /// Specifies that an output will not be null even if the corresponding type allows it. Specifies that an input argument was not null when the call returns. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class NotNullAttribute : Attribute - { } + internal sealed class NotNullAttribute : Attribute { } /// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class MaybeNullWhenAttribute : Attribute + internal sealed class MaybeNullWhenAttribute : Attribute { /// Initializes the attribute with the specified return value condition. /// @@ -71,12 +38,7 @@ sealed class MaybeNullWhenAttribute : Attribute /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class NotNullWhenAttribute : Attribute + internal sealed class NotNullWhenAttribute : Attribute { /// Initializes the attribute with the specified return value condition. /// @@ -90,12 +52,7 @@ sealed class NotNullWhenAttribute : Attribute /// Specifies that the output will be non-null if the named parameter is non-null. [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class NotNullIfNotNullAttribute : Attribute + internal sealed class NotNullIfNotNullAttribute : Attribute { /// Initializes the attribute with the associated parameter name. /// @@ -109,22 +66,11 @@ sealed class NotNullIfNotNullAttribute : Attribute /// Applied to a method that will never return under any circumstance. [AttributeUsage(AttributeTargets.Method, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class DoesNotReturnAttribute : Attribute - { } + internal sealed class DoesNotReturnAttribute : Attribute { } /// Specifies that the method will not return if the associated Boolean parameter is passed the specified value. [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class DoesNotReturnIfAttribute : Attribute + internal sealed class DoesNotReturnIfAttribute : Attribute { /// Initializes the attribute with the specified parameter value. /// @@ -136,82 +82,62 @@ sealed class DoesNotReturnIfAttribute : Attribute /// Gets the condition parameter value. public bool ParameterValue { get; } } -#endif // NETSTANDARD2_0 attributes -#if NETSTANDARD2_1 || NETSTANDARD2_0 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NETCOREAPP3_1 || NET45 || NET451 || NET452 || NET6 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48 - /// - /// Specifies that the method or property will ensure that the listed field and property members have - /// not- values. - /// + /// Specifies that the method or property will ensure that the listed field and property members have not-null values. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class MemberNotNullAttribute : Attribute + internal sealed class MemberNotNullAttribute : Attribute { - /// Gets field or property member names. - public string[] Members { get; } - /// Initializes the attribute with a field or property member. - /// The field or property member that is promised to be not-null. - public MemberNotNullAttribute(string member) - { - Members = new[] { member }; - } + /// + /// The field or property member that is promised to be not-null. + /// + public MemberNotNullAttribute(string member) => Members = [member]; /// Initializes the attribute with the list of field and property members. - /// The list of field and property members that are promised to be not-null. - public MemberNotNullAttribute(params string[] members) - { - Members = members; - } - } - - /// - /// Specifies that the method or property will ensure that the listed field and property members have - /// non- values when returning with the specified return value condition. - /// - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] -#if INTERNAL_NULLABLE_ATTRIBUTES - internal -#else - public -#endif - sealed class MemberNotNullWhenAttribute : Attribute - { - /// Gets the return value condition. - public bool ReturnValue { get; } + /// + /// The list of field and property members that are promised to be not-null. + /// + public MemberNotNullAttribute(params string[] members) => Members = members; /// Gets field or property member names. public string[] Members { get; } + } + /// Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition. + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] + internal sealed class MemberNotNullWhenAttribute : Attribute + { /// Initializes the attribute with the specified return value condition and a field or property member. /// - /// The return value condition. If the method returns this value, - /// the associated parameter will not be . + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + /// + /// The field or property member that is promised to be not-null. /// - /// The field or property member that is promised to be not-. public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; - Members = new[] { member }; + Members = [member]; } - /// Initializes the attribute with the specified return value condition and list of field and property members. - /// + /// Initializes the attribute with the specified return value condition and list of field and property members. /// - /// The return value condition. If the method returns this value, - /// the associated parameter will not be . + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + /// + /// The list of field and property members that are promised to be not-null. /// - /// The list of field and property members that are promised to be not-null. public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } + + /// Gets the return value condition. + public bool ReturnValue { get; } + + /// Gets field or property member names. + public string[] Members { get; } } -#endif // NETSTANDARD2_1 attributes +#endif } - diff --git a/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj b/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj index 49b9e7cddc2..61069630a5e 100644 --- a/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj +++ b/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj @@ -114,16 +114,17 @@ Markup/%(RecursiveDir)%(FileName)%(Extension) - - - - - + + + + + - + + diff --git a/src/Avalonia.Controls.ColorPicker/Avalonia.Controls.ColorPicker.csproj b/src/Avalonia.Controls.ColorPicker/Avalonia.Controls.ColorPicker.csproj index ed080e30650..db7bc33232b 100644 --- a/src/Avalonia.Controls.ColorPicker/Avalonia.Controls.ColorPicker.csproj +++ b/src/Avalonia.Controls.ColorPicker/Avalonia.Controls.ColorPicker.csproj @@ -4,7 +4,7 @@ true - + diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj b/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj index cc4844ad150..20403d00bfd 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj @@ -14,4 +14,5 @@ + diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs index 5ed8a2b8835..b66e006ad6f 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs @@ -33,14 +33,14 @@ namespace Avalonia.Markup.Xaml.XamlIl internal static class AvaloniaXamlIlRuntimeCompiler { #if !RUNTIME_XAML_CECIL - private static SreTypeSystem _sreTypeSystem; - private static Type _ignoresAccessChecksFromAttribute; - private static ModuleBuilder _sreBuilder; - private static IXamlType _sreContextType; - private static XamlLanguageTypeMappings _sreMappings; - private static XamlLanguageEmitMappings _sreEmitMappings; - private static XamlXmlnsMappings _sreXmlns; - private static AssemblyBuilder _sreAsm; + private static SreTypeSystem? _sreTypeSystem; + private static Type? _ignoresAccessChecksFromAttribute; + private static ModuleBuilder? _sreBuilder; + private static IXamlType? _sreContextType; + private static XamlLanguageTypeMappings? _sreMappings; + private static XamlLanguageEmitMappings? _sreEmitMappings; + private static XamlXmlnsMappings? _sreXmlns; + private static AssemblyBuilder? _sreAsm; private static bool _sreCanSave; [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = XamlX.TrimmingMessages.CanBeSafelyTrimmed)] @@ -48,7 +48,7 @@ public static void DumpRuntimeCompilationResults() { if (_sreBuilder == null) return; - var saveMethod = _sreAsm.GetType().GetMethods() + var saveMethod = _sreAsm!.GetType().GetMethods() .FirstOrDefault(m => m.Name == "Save" && m.GetParameters().Length == 1); if (saveMethod == null) return; @@ -65,6 +65,13 @@ public static void DumpRuntimeCompilationResults() [CompilerDynamicDependencies] [UnconditionalSuppressMessage("Trimming", "IL2072", Justification = XamlX.TrimmingMessages.GeneratedTypes)] + [MemberNotNull(nameof(_sreTypeSystem))] + [MemberNotNull(nameof(_sreBuilder))] + [MemberNotNull(nameof(_sreMappings))] + [MemberNotNull(nameof(_sreEmitMappings))] + [MemberNotNull(nameof(_sreXmlns))] + [MemberNotNull(nameof(_sreContextType))] + [MemberNotNull(nameof(_ignoresAccessChecksFromAttribute))] static void InitializeSre() { if (_sreTypeSystem == null) @@ -81,8 +88,8 @@ static void InitializeSre() { name, (AssemblyBuilderAccess)3, Path.GetDirectoryName(typeof(AvaloniaXamlIlRuntimeCompiler).Assembly.GetModules()[0] - .FullyQualifiedName) - }); + .FullyQualifiedName)! + })!; else _sreCanSave = false; } @@ -94,7 +101,7 @@ static void InitializeSre() _sreBuilder = _sreAsm.DefineDynamicModule("XamlIlLoader.ildump"); } - if (_sreMappings == null) + if (_sreMappings is null || _sreEmitMappings is null) (_sreMappings, _sreEmitMappings) = AvaloniaXamlIlLanguage.Configure(_sreTypeSystem); if (_sreXmlns == null) _sreXmlns = XamlXmlnsMappings.Resolve(_sreTypeSystem, _sreMappings); @@ -108,7 +115,7 @@ static void InitializeSre() } [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = XamlX.TrimmingMessages.CanBeSafelyTrimmed)] - static MethodInfo GetDefineDynamicAssembly() => AppDomain.CurrentDomain.GetType().GetMethods() + static MethodInfo? GetDefineDynamicAssembly() => AppDomain.CurrentDomain.GetType().GetMethods() .FirstOrDefault(m => m.Name == "DefineDynamicAssembly" && m.GetParameters().Length == 3 && m.GetParameters()[2].ParameterType == typeof(string)); @@ -142,12 +149,12 @@ static Type EmitIgnoresAccessCheckAttributeDefinition(ModuleBuilder builder) ctorIl.Emit(OpCodes.Ret); tb.SetCustomAttribute(new CustomAttributeBuilder( - typeof(AttributeUsageAttribute).GetConstructor(new[] { typeof(AttributeTargets) }), + typeof(AttributeUsageAttribute).GetConstructor(new[] { typeof(AttributeTargets) })!, new object[] { AttributeTargets.Assembly }, - new[] { typeof(AttributeUsageAttribute).GetProperty("AllowMultiple") }, + new[] { typeof(AttributeUsageAttribute).GetProperty(nameof(AttributeUsageAttribute.AllowMultiple))! }, new object[] { true })); - return tb.CreateTypeInfo(); + return tb.CreateTypeInfo()!; } [UnconditionalSuppressMessage("Trimming", "IL2080", Justification = XamlX.TrimmingMessages.GeneratedTypes)] @@ -159,8 +166,8 @@ static void EmitIgnoresAccessCheckToAttribute(AssemblyName assemblyName) var key = assemblyName.GetPublicKey(); if (key != null && key.Length != 0) name += ", PublicKey=" + BitConverter.ToString(key).Replace("-", "").ToUpperInvariant(); - _sreAsm.SetCustomAttribute(new CustomAttributeBuilder( - _ignoresAccessChecksFromAttribute.GetConstructors()[0], + _sreAsm!.SetCustomAttribute(new CustomAttributeBuilder( + _ignoresAccessChecksFromAttribute!.GetConstructors()[0], new object[] { name })); } @@ -267,7 +274,7 @@ static IReadOnlyList LoadGroupSreCore(IReadOnlyCollection>( Expression.Call(populate, isp, Expression.Convert(epar, populate.GetParameters()[1].ParameterType)), @@ -353,7 +363,7 @@ static object LoadOrPopulate([DynamicallyAccessedMembers(DynamicallyAccessedMemb target => { populateCb(serviceProvider, target); })); try { - return Activator.CreateInstance(targetType); + return Activator.CreateInstance(targetType)!; } finally { @@ -363,7 +373,7 @@ static object LoadOrPopulate([DynamicallyAccessedMembers(DynamicallyAccessedMemb var createCb = Expression.Lambda>( Expression.Convert(Expression.Call( - created.GetMethod(AvaloniaXamlIlCompiler.BuildName), isp), typeof(object)), isp).Compile(); + created.GetMethod(AvaloniaXamlIlCompiler.BuildName)!, isp), typeof(object)), isp).Compile(); return createCb(serviceProvider); } else @@ -394,7 +404,7 @@ public static IReadOnlyList LoadGroup(IReadOnlyCollection documents) #if !XAMLX_CECIL_INTERNAL [RequiresUnreferencedCode(XamlX.TrimmingMessages.DynamicXamlReference)] #endif - public XamlDocument Parse(string xaml, IXamlType overrideRootType) + public XamlDocument Parse(string xaml, IXamlType? overrideRootType) { var parsed = XDocumentXamlParser.Parse(xaml, new Dictionary { @@ -192,7 +192,7 @@ public XamlDocument Parse(string xaml, IXamlType overrideRootType) return parsed; } - public void Compile(XamlDocument document, XamlDocumentTypeBuilderProvider typeBuilderProvider, string baseUri, IFileSource fileSource) + public void Compile(XamlDocument document, XamlDocumentTypeBuilderProvider typeBuilderProvider, string? baseUri, IFileSource? fileSource) { Compile( document, @@ -211,7 +211,7 @@ public void Compile(XamlDocument document, XamlDocumentTypeBuilderProvider typeB #if !XAMLX_CECIL_INTERNAL [RequiresUnreferencedCode(XamlX.TrimmingMessages.DynamicXamlReference)] #endif - public void ParseAndCompile(string xaml, string baseUri, IFileSource fileSource, IXamlTypeBuilder tb, IXamlType overrideRootType) + public void ParseAndCompile(string xaml, string? baseUri, IFileSource fileSource, IXamlTypeBuilder tb, IXamlType overrideRootType) { var parsed = Parse(xaml, overrideRootType); diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompilerConfiguration.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompilerConfiguration.cs index d5b760aa848..e8da6714416 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompilerConfiguration.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompilerConfiguration.cs @@ -9,16 +9,17 @@ class AvaloniaXamlIlCompilerConfiguration : TransformerConfiguration public XamlIlPropertyInfoAccessorFactoryEmitter AccessorFactoryEmitter { get; } public XamlIlTrampolineBuilder TrampolineBuilder { get; } - public AvaloniaXamlIlCompilerConfiguration(IXamlTypeSystem typeSystem, - IXamlAssembly defaultAssembly, + public AvaloniaXamlIlCompilerConfiguration( + IXamlTypeSystem typeSystem, + IXamlAssembly? defaultAssembly, XamlLanguageTypeMappings typeMappings, - XamlXmlnsMappings xmlnsMappings, - XamlValueConverter customValueConverter, + XamlXmlnsMappings? xmlnsMappings, + XamlValueConverter? customValueConverter, XamlIlClrPropertyInfoEmitter clrPropertyEmitter, XamlIlPropertyInfoAccessorFactoryEmitter accessorFactoryEmitter, XamlIlTrampolineBuilder trampolineBuilder, - IXamlIdentifierGenerator identifierGenerator, - XamlDiagnosticsHandler diagnosticsHandler) + IXamlIdentifierGenerator? identifierGenerator, + XamlDiagnosticsHandler? diagnosticsHandler) : base(typeSystem, defaultAssembly, typeMappings, xmlnsMappings, customValueConverter, identifierGenerator, diagnosticsHandler) { ClrPropertyEmitter = clrPropertyEmitter; diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs index 53fa0a2a4da..4f4e407690c 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers; using XamlX.Ast; @@ -21,8 +22,6 @@ class AvaloniaXamlIlLanguage public static (XamlLanguageTypeMappings language, XamlLanguageEmitMappings emit) Configure(IXamlTypeSystem typeSystem) { var runtimeHelpers = typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.XamlIlRuntimeHelpers"); - var assignBindingAttribute = typeSystem.GetType("Avalonia.Data.AssignBindingAttribute"); - var bindingType = typeSystem.GetType("Avalonia.Data.IBinding"); var rv = new XamlLanguageTypeMappings(typeSystem) { SupportInitialize = typeSystem.GetType("System.ComponentModel.ISupportInitialize"), @@ -89,7 +88,7 @@ private static void EmitNameScopeField( IXamlTypeSystem typeSystem, IXamlILContextDefinition definition) { - var nameScopeType = typeSystem.FindType("Avalonia.Controls.INameScope"); + var nameScopeType = typeSystem.GetType("Avalonia.Controls.INameScope"); var field = definition.TypeBuilder.DefineField(nameScopeType, ContextNameScopeFieldName, XamlVisibility.Public, false); definition.ConstructorBuilder.Generator @@ -97,7 +96,7 @@ private static void EmitNameScopeField( .Ldarg(1) .Ldtype(nameScopeType) .EmitCall(mappings.ServiceProvider.GetMethod(new FindMethodMethodSignature("GetService", - typeSystem.FindType("System.Object"), typeSystem.FindType("System.Type")))) + typeSystem.GetType("System.Object"), typeSystem.GetType("System.Type")))) .Stfld(field); } @@ -107,26 +106,26 @@ private static void EmitEagerParentStackProvider( IXamlILContextDefinition definition, IXamlType runtimeHelpers) { - var interfaceType = typeSystem.FindType("Avalonia.Markup.Xaml.XamlIl.Runtime.IAvaloniaXamlIlEagerParentStackProvider"); + var interfaceType = typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.IAvaloniaXamlIlEagerParentStackProvider"); definition.TypeBuilder.AddInterfaceImplementation(interfaceType); // IReadOnlyList DirectParentsStack => (IReadOnlyList)ParentsStack; var directParentsGetter = ImplementInterfacePropertyGetter("DirectParentsStack"); directParentsGetter.Generator - .LdThisFld(definition.ParentListField) + .LdThisFld(definition.ParentListField!) .Castclass(directParentsGetter.ReturnType) .Ret(); var serviceProviderGetServiceMethod = mappings.ServiceProvider.GetMethod(new FindMethodMethodSignature( "GetService", - typeSystem.FindType("System.Object"), - typeSystem.FindType("System.Type"))); + typeSystem.GetType("System.Object"), + typeSystem.GetType("System.Type"))); var asEagerParentStackProviderMethod = runtimeHelpers.GetMethod(new FindMethodMethodSignature( "AsEagerParentStackProvider", interfaceType, - mappings.ParentStackProvider) + mappings.ParentStackProvider!) { IsStatic = true }); @@ -136,14 +135,14 @@ private static void EmitEagerParentStackProvider( var parentProviderGetter = ImplementInterfacePropertyGetter("ParentProvider"); parentProviderGetter.Generator .LdThisFld(definition.ParentServiceProviderField) - .Ldtype(mappings.ParentStackProvider) + .Ldtype(mappings.ParentStackProvider!) .EmitCall(serviceProviderGetServiceMethod) .EmitCall(asEagerParentStackProviderMethod) .Ret(); IXamlMethodBuilder ImplementInterfacePropertyGetter(string propertyName) { - var interfaceGetter = interfaceType.FindMethod(m => m.Name == "get_" + propertyName); + var interfaceGetter = interfaceType.GetMethod(m => m.Name == "get_" + propertyName); var getter = definition.TypeBuilder.DefineMethod( interfaceGetter.ReturnType, @@ -193,7 +192,7 @@ void AddType(IXamlType type, IXamlType conv) _avaloniaListConverter = typeSystem.GetType("Avalonia.Collections.AvaloniaListConverter`1"); } - IXamlType LookupConverter(IXamlType type) + IXamlType? LookupConverter(IXamlType type) { foreach(var p in _converters) if (p.Key.Equals(type)) @@ -205,41 +204,44 @@ IXamlType LookupConverter(IXamlType type) class ConstructedAttribute : IXamlCustomAttribute { - public bool Equals(IXamlCustomAttribute other) => false; + public bool Equals(IXamlCustomAttribute? other) => false; public IXamlType Type { get; } - public List Parameters { get; } - public Dictionary Properties { get; } + public List Parameters { get; } + public Dictionary Properties { get; } - public ConstructedAttribute(IXamlType type, List parameters, Dictionary properties) + public ConstructedAttribute(IXamlType type, List? parameters, Dictionary? properties) { Type = type; - Parameters = parameters ?? new List(); - Properties = properties ?? new Dictionary(); + Parameters = parameters ?? new List(); + Properties = properties ?? new Dictionary(); } } - public IXamlCustomAttribute GetCustomAttribute(IXamlType type, IXamlType attributeType) + public IXamlCustomAttribute? GetCustomAttribute(IXamlType type, IXamlType attributeType) { if (attributeType.Equals(_typeConverterAttribute)) { var conv = LookupConverter(type); if (conv != null) - return new ConstructedAttribute(_typeConverterAttribute, new List() {conv}, null); + return new ConstructedAttribute(_typeConverterAttribute, [conv], null); } return null; } - public IXamlCustomAttribute GetCustomAttribute(IXamlProperty property, IXamlType attributeType) + public IXamlCustomAttribute? GetCustomAttribute(IXamlProperty property, IXamlType attributeType) { return null; } } - public static bool CustomValueConverter(AstTransformationContext context, - IXamlAstValueNode node, IReadOnlyList customAttributes, IXamlType type, - out IXamlAstValueNode result) + public static bool CustomValueConverter( + AstTransformationContext context, + IXamlAstValueNode node, + IReadOnlyList? customAttributes, + IXamlType type, + [NotNullWhen(true)] out IXamlAstValueNode? result) { if (node is AvaloniaXamlIlOptionMarkupExtensionTransformer.OptionsMarkupExtensionNode optionsNode) { diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs index b11086e74d8..ce8937027e2 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using Avalonia.Controls; @@ -15,9 +16,15 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions { class AvaloniaXamlIlLanguageParseIntrinsics { - public static bool TryConvert(AstTransformationContext context, IXamlAstValueNode node, string text, IXamlType type, AvaloniaXamlIlWellKnownTypes types, out IXamlAstValueNode result) + public static bool TryConvert( + AstTransformationContext context, + IXamlAstValueNode node, + string text, + IXamlType type, + AvaloniaXamlIlWellKnownTypes types, + [NotNullWhen(true)] out IXamlAstValueNode? result) { - bool ReturnOnParseError(string title, out IXamlAstValueNode result) + bool ReturnOnParseError(string title, out IXamlAstValueNode? result) { context.ReportDiagnostic(new XamlDiagnostic( AvaloniaXamlDiagnosticCodes.AvaloniaIntrinsicsError, @@ -50,7 +57,7 @@ bool ReturnOnParseError(string title, out IXamlAstValueNode result) } result = new XamlStaticOrTargetedReturnMethodCallNode(node, - type.FindMethod("FromTicks", type, false, types.Long), + type.GetMethod("FromTicks", type, false, types.Long), new[] { new XamlConstantNode(node, types.Long, timeSpan.Ticks) }); return true; } @@ -272,7 +279,7 @@ bool ReturnOnParseError(string title, out IXamlAstValueNode result) { if (property.PropertyType == types.TextTrimming && property.Name.Equals(text, StringComparison.OrdinalIgnoreCase)) { - result = new XamlStaticOrTargetedReturnMethodCallNode(node, property.Getter, Enumerable.Empty()); + result = new XamlStaticOrTargetedReturnMethodCallNode(node, property.Getter!, Enumerable.Empty()); return true; } @@ -285,7 +292,7 @@ bool ReturnOnParseError(string title, out IXamlAstValueNode result) { if (property.PropertyType == types.TextDecorationCollection && property.Name.Equals(text, StringComparison.OrdinalIgnoreCase)) { - result = new XamlStaticOrTargetedReturnMethodCallNode(node, property.Getter, Enumerable.Empty()); + result = new XamlStaticOrTargetedReturnMethodCallNode(node, property.Getter!, Enumerable.Empty()); return true; } @@ -298,7 +305,7 @@ bool ReturnOnParseError(string title, out IXamlAstValueNode result) { if (property.PropertyType == types.WindowTransparencyLevel && property.Name.Equals(text, StringComparison.OrdinalIgnoreCase)) { - result = new XamlStaticOrTargetedReturnMethodCallNode(node, property.Getter, Enumerable.Empty()); + result = new XamlStaticOrTargetedReturnMethodCallNode(node, property.Getter!, Enumerable.Empty()); return true; } @@ -309,7 +316,7 @@ bool ReturnOnParseError(string title, out IXamlAstValueNode result) { var uriText = text.Trim(); - var kind = ((!uriText?.StartsWith("/") == true) ? UriKind.RelativeOrAbsolute : UriKind.Relative); + var kind = !uriText.StartsWith("/") ? UriKind.RelativeOrAbsolute : UriKind.Relative; if (string.IsNullOrWhiteSpace(uriText) || !Uri.TryCreate(uriText, kind, out var _)) { @@ -373,12 +380,12 @@ bool ReturnOnParseError(string title, out IXamlAstValueNode result) { if (attribute.Properties.TryGetValue("Separators", out var separatorsArray)) { - separators = ((Array)separatorsArray)?.OfType().ToArray(); + separators = ((Array?)separatorsArray)?.OfType().ToArray(); } if (attribute.Properties.TryGetValue("SplitOptions", out var splitOptionsObj)) { - splitOptions = (StringSplitOptions)splitOptionsObj; + splitOptions = (StringSplitOptions)splitOptionsObj!; } } @@ -403,7 +410,7 @@ bool ReturnOnParseError(string title, out IXamlAstValueNode result) return false; } - nodes[index] = itemNode; + nodes[index] = itemNode!; } foreach (var element in nodes) @@ -440,7 +447,7 @@ bool ReturnOnParseError(string title, out IXamlAstValueNode result) return false; } - private static IXamlType GetElementType(IXamlType type, XamlTypeWellKnownTypes types) + private static IXamlType? GetElementType(IXamlType type, XamlTypeWellKnownTypes types) { if (type.IsArray) { diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/IXamlAstGroupTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/IXamlAstGroupTransformer.cs index 37b1952c498..5ed01caa7df 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/IXamlAstGroupTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/IXamlAstGroupTransformer.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Xml; -using XamlX; +using System.Collections.Generic; using XamlX.Ast; using XamlX.Transform; @@ -18,7 +15,7 @@ public AstGroupTransformationContext( } public override string Document => CurrentDocument?.FileSource?.FilePath ?? "{unknown document}"; - public IXamlDocumentResource CurrentDocument { get; set; } + public IXamlDocumentResource? CurrentDocument { get; set; } public IReadOnlyCollection Documents { get; } diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/XamlIncludeGroupTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/XamlIncludeGroupTransformer.cs index 7c345c060f6..766c6d9e02c 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/XamlIncludeGroupTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/XamlIncludeGroupTransformer.cs @@ -192,7 +192,7 @@ void OnInvalidSource(IXamlAstNode? node) => var uriPath = new Uri(originalAssetPath, (UriKind)uriKind); if (!uriPath.IsAbsoluteUri) { - var baseUrl = context.CurrentDocument.Uri ?? throw new InvalidOperationException("CurrentDocument URI is null."); + var baseUrl = context.CurrentDocument?.Uri ?? throw new InvalidOperationException("CurrentDocument URI is null."); uriPath = new Uri(new Uri(baseUrl, UriKind.Absolute), uriPath); } else if (!uriPath.Scheme.Equals("avares", StringComparison.CurrentCultureIgnoreCase)) @@ -218,7 +218,7 @@ public XamlILNodeEmitResult Emit(XamlEmitContext m.Name == "CreateRootServiceProviderV3"); + .GetMethod(m => m.Name == "CreateRootServiceProviderV3"); codeGen.EmitCall(method); return XamlILNodeEmitResult.Type(0, Type.GetClrType()); diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/XamlMergeResourceGroupTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/XamlMergeResourceGroupTransformer.cs index 20123f2e322..25e52c40f05 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/XamlMergeResourceGroupTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/XamlMergeResourceGroupTransformer.cs @@ -7,7 +7,6 @@ using XamlX.TypeSystem; namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.GroupTransformers; -#nullable enable internal class XamlMergeResourceGroupTransformer : IXamlAstGroupTransformer { @@ -94,7 +93,7 @@ void ProcessXamlPropertyAssignmentNode(XamlManipulationGroupNode parent, XamlPro $"Node MergeResourceInclude is unable to resolve \"{originalAssetPath}\" path.", propertyNode, node); } - var singleRootObject = ((XamlManipulationGroupNode)targetDocumentRoot.Manipulation) + var singleRootObject = ((XamlManipulationGroupNode)targetDocumentRoot.Manipulation!) .Children.OfType().Single(); if (singleRootObject.Type != resourceDictionaryType) { diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AddNameScopeRegistration.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AddNameScopeRegistration.cs index 4cf84b90a08..948ca5207c8 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AddNameScopeRegistration.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AddNameScopeRegistration.cs @@ -22,7 +22,7 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod && mg.Children.OfType().Any()) return node; - IXamlAstValueNode value = null; + IXamlAstValueNode? value = null; for (var c = 0; c < pa.Values.Count; c++) if (pa.Values[c].Type.GetClrType().Equals(context.Configuration.WellKnownTypes.String)) { @@ -73,9 +73,9 @@ public NestedScopeMetadataNode(IXamlAstValueNode value) : base(value, value) class AvaloniaNameScopeRegistrationXamlIlNode : XamlAstNode, IXamlAstManipulationNode { public IXamlAstValueNode Name { get; set; } - public IXamlType TargetType { get; } + public IXamlType? TargetType { get; } - public AvaloniaNameScopeRegistrationXamlIlNode(IXamlAstValueNode name, IXamlType targetType) : base(name) + public AvaloniaNameScopeRegistrationXamlIlNode(IXamlAstValueNode name, IXamlType? targetType) : base(name) { TargetType = targetType; Name = name; @@ -87,7 +87,7 @@ public override void VisitChildren(IXamlAstVisitor visitor) class AvaloniaNameScopeRegistrationXamlIlNodeEmitter : IXamlAstLocalsNodeEmitter { - public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContextWithLocals context, IXamlILEmitter codeGen) + public XamlILNodeEmitResult? Emit(IXamlAstNode node, XamlEmitContextWithLocals context, IXamlILEmitter codeGen) { if (node is AvaloniaNameScopeRegistrationXamlIlNode registration) { @@ -114,7 +114,7 @@ public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContextWithLocals() .Where(v => v.Property is AvaloniaSyntheticCompiledBindingProperty) @@ -195,17 +193,15 @@ v.Property is XamlAstClrProperty prop if (treeType == "Visual") { - convertedNode = new VisualAncestorBindingExpressionNode + convertedNode = new VisualAncestorBindingExpressionNode(ancestorType!) { - Type = ancestorType, Level = ancestorLevel }; } else if (treeType == "Logical") { - convertedNode = new LogicalAncestorBindingExpressionNode + convertedNode = new LogicalAncestorBindingExpressionNode(ancestorType!) { - Type = ancestorType, Level = ancestorLevel }; } @@ -238,7 +234,7 @@ v.Property is XamlAstClrProperty prop throw new XamlBindingsTransformException("TargetType has to be set on ControlTemplate or it should be defined inside of a Style.", binding); } - convertedNode = new TemplatedParentBindingExpressionNode { Type = parentType }; + convertedNode = new TemplatedParentBindingExpressionNode(parentType); } else { @@ -260,8 +256,8 @@ v.Property is XamlAstClrProperty prop private static bool GetRelativeSourceObjectFromAssignment( AstTransformationContext context, - XamlAstXamlPropertyValueNode relativeSourceProperty, - out XamlAstObjectNode relativeSourceObject) + XamlAstXamlPropertyValueNode? relativeSourceProperty, + [NotNullWhen(true)] out XamlAstObjectNode? relativeSourceObject) { relativeSourceObject = null; if (relativeSourceProperty is null) @@ -320,21 +316,21 @@ public override void VisitChildren(IXamlAstVisitor visitor) } } - class VisualAncestorBindingExpressionNode : BindingExpressionGrammar.INode + class VisualAncestorBindingExpressionNode(IXamlType type) : BindingExpressionGrammar.INode { - public IXamlType Type { get; set; } + public IXamlType Type { get; set; } = type; public int Level { get; set; } } - class LogicalAncestorBindingExpressionNode : BindingExpressionGrammar.INode + class LogicalAncestorBindingExpressionNode(IXamlType type) : BindingExpressionGrammar.INode { - public IXamlType Type { get; set; } + public IXamlType Type { get; set; } = type; public int Level { get; set; } } - class TemplatedParentBindingExpressionNode : BindingExpressionGrammar.INode + class TemplatedParentBindingExpressionNode(IXamlType type) : BindingExpressionGrammar.INode { - public IXamlType Type { get; set; } + public IXamlType Type { get; set; } = type; } class RawSourceBindingExpressionNode : XamlAstNode, BindingExpressionGrammar.INode diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs index cba82a94080..5ca29581a53 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs @@ -14,7 +14,7 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod { if (node is XamlAstConstructableObjectNode binding && binding.Type.GetClrType().Equals(context.GetAvaloniaTypes().CompiledBindingExtension)) { - IXamlType startType = null; + IXamlType? startType = null; var sourceProperty = binding.Children.OfType().FirstOrDefault(c => c.Property.Name == "Source"); var dataTypeProperty = binding.Children.OfType().FirstOrDefault(c => c.Property.Name == "DataType"); if (sourceProperty?.Values.Count is 1) @@ -23,11 +23,11 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod switch (sourceValue) { case XamlAstTextNode textNode: - startType = textNode.Type?.GetClrType(); + startType = textNode.Type.GetClrType(); break; case XamlMarkupExtensionNode extension: - startType = extension.Type?.GetClrType(); + 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" && @@ -47,7 +47,7 @@ m.Children[0] is XamlPropertyAssignmentNode pm && string getResourceValue_xKey(XamlPropertyAssignmentNode node) => node.Values.Count == 2 && node.Values[0] is XamlAstTextNode t ? t.Text : ""; - IXamlType getResourceValue_Type(XamlPropertyAssignmentNode node, IXamlType xamlType) + IXamlType? getResourceValue_Type(XamlPropertyAssignmentNode node, IXamlType? xamlType) => node.Values.Count == 2 ? node.Values[1].Type.GetClrType() : xamlType; IEnumerable getResourceValues(IXamlAstNode node) @@ -85,7 +85,7 @@ propertyNode.Values[0] is XamlAstConstructableObjectNode obj && .Where(o => styledElement.IsAssignableFrom(o.Type.GetClrType())) .Select(o => o.Children.FirstOrDefault(p => matchProperty(p, styledElement, "Resources"))) .Where(r => r != null) - .SelectMany(r => getResourceValues(r)) + .SelectMany(r => getResourceValues(r!)) .FirstOrDefault(r => getResourceValue_xKey(r) == key); if (resource != null) @@ -96,7 +96,7 @@ propertyNode.Values[0] is XamlAstConstructableObjectNode obj && break; case XamlStaticExtensionNode staticExtension: - startType = staticExtension.Type?.GetClrType(); + startType = staticExtension.Type.GetClrType(); break; } } diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlClassesPropertyResolver.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlClassesPropertyResolver.cs index 6f188d87378..eccd3d9e091 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlClassesPropertyResolver.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlClassesPropertyResolver.cs @@ -49,7 +49,7 @@ public void Emit(IXamlILEmitter emitter) { emitter .Stloc(value.Local) - .EmitCall(_types.StyledElementClassesProperty.Getter) + .EmitCall(_types.StyledElementClassesProperty.Getter!) .Ldstr(_className) .Ldloc(value.Local) .EmitCall(_types.Classes.GetMethod(new FindMethodMethodSignature("Set", diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs index 488fcef46c6..ce31c89b6f3 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDataContextTypeTransformer.cs @@ -12,7 +12,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers { class XamlDataContextException : XamlTransformException { - public XamlDataContextException(string message, IXamlLineInfo lineInfo, Exception innerException = null) + public XamlDataContextException(string message, IXamlLineInfo lineInfo, Exception? innerException = null) : base(message, lineInfo, innerException) { } @@ -30,8 +30,8 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod if (node is XamlAstConstructableObjectNode on) { - AvaloniaXamlIlDataContextTypeMetadataNode inferredDataContextTypeNode = null; - AvaloniaXamlIlDataContextTypeMetadataNode directiveDataContextTypeNode = null; + AvaloniaXamlIlDataContextTypeMetadataNode? inferredDataContextTypeNode = null; + AvaloniaXamlIlDataContextTypeMetadataNode? directiveDataContextTypeNode = null; for (int i = 0; i < on.Children.Count; ++i) { @@ -81,13 +81,13 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod // Infer data type from collection binding on a control that displays items. var property = context.ParentNodes().OfType().FirstOrDefault(); var attributeType = context.GetAvaloniaTypes().InheritDataTypeFromItemsAttribute; - var attribute = property?.Property?.GetClrProperty().CustomAttributes + var attribute = property?.Property.GetClrProperty().CustomAttributes .FirstOrDefault(a => a.Type == attributeType); if (attribute is not null) { - var propertyName = (string)attribute.Parameters.First(); - XamlAstConstructableObjectNode parentObject; + var propertyName = (string?)attribute.Parameters.First(); + XamlAstConstructableObjectNode? parentObject; if (attribute.Properties.TryGetValue("AncestorType", out var type) && type is IXamlType xamlType) { @@ -99,7 +99,7 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod parentObject = context.ParentNodes().OfType().FirstOrDefault(); } - if (parentObject != null) + if (parentObject != null && !string.IsNullOrEmpty(propertyName)) { inferredDataContextTypeNode = InferDataContextOfPresentedItem(context, on, parentObject, propertyName); } @@ -122,7 +122,7 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod return node; } - private static AvaloniaXamlIlDataContextTypeMetadataNode InferDataContextOfPresentedItem( + private static AvaloniaXamlIlDataContextTypeMetadataNode? InferDataContextOfPresentedItem( AstTransformationContext context, XamlAstConstructableObjectNode on, XamlAstConstructableObjectNode parentObject, string propertyName) { @@ -135,7 +135,7 @@ private static AvaloniaXamlIlDataContextTypeMetadataNode InferDataContextOfPrese return null; } - IXamlType itemsCollectionType = null; + IXamlType? itemsCollectionType = null; if (context.GetAvaloniaTypes().IBinding.IsAssignableFrom(parentItemsValue.Type.GetClrType())) { if (parentItemsValue.Type.GetClrType().Equals(context.GetAvaloniaTypes().CompiledBindingExtension) @@ -217,7 +217,7 @@ private static IEnumerable GetAllInterfacesIncludingSelf(IXamlType ty [DebuggerDisplay("DataType = {DataContextType}")] class AvaloniaXamlIlDataContextTypeMetadataNode : XamlValueWithSideEffectNodeBase { - public virtual IXamlType DataContextType { get; } + public IXamlType DataContextType { get; } public AvaloniaXamlIlDataContextTypeMetadataNode(IXamlAstValueNode value, IXamlType targetType) : base(value, value) @@ -230,10 +230,8 @@ public AvaloniaXamlIlDataContextTypeMetadataNode(IXamlAstValueNode value, IXamlT class AvaloniaXamlIlUninferrableDataContextMetadataNode : AvaloniaXamlIlDataContextTypeMetadataNode { public AvaloniaXamlIlUninferrableDataContextMetadataNode(IXamlAstValueNode value) - : base(value, null) + : base(value, XamlPseudoType.Unknown) { } - - public override IXamlType DataContextType => XamlPseudoType.Unknown; } } diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDeferredResourceTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDeferredResourceTransformer.cs index 06ec916fe71..84ca68f4973 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDeferredResourceTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlDeferredResourceTransformer.cs @@ -28,7 +28,7 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod new XamlDirectCallPropertySetter(types.ResourceDictionaryDeferredAdd), }; } - else if (pa.Property.Name == "Resources" && pa.Property.Getter.ReturnType.Equals(types.IResourceDictionary) + else if (pa.Property.Name == "Resources" && pa.Property.Getter?.ReturnType.Equals(types.IResourceDictionary) == true && ShouldBeDeferred(pa.Values[1])) { pa.Values[1] = new XamlDeferredContentNode(pa.Values[1], types.XamlIlTypes.Object, context.Configuration); @@ -132,7 +132,7 @@ public void EmitWithArguments( emitter.EmitCall(_adder, true); } - public bool Equals(AdderSetter other) + public bool Equals(AdderSetter? other) { if (ReferenceEquals(null, other)) return false; @@ -142,7 +142,7 @@ public bool Equals(AdderSetter other) return _getter.Equals(other._getter) && _adder.Equals(other._adder); } - public override bool Equals(object obj) + public override bool Equals(object? obj) => Equals(obj as AdderSetter); public override int GetHashCode() diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlEnsureResourceDictionaryCapacityTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlEnsureResourceDictionaryCapacityTransformer.cs index 76781046b24..ca925eaca14 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlEnsureResourceDictionaryCapacityTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlEnsureResourceDictionaryCapacityTransformer.cs @@ -70,8 +70,8 @@ private static ResourcesInfo GetResourcesInfo(XamlPropertyAssignmentNode node, A { "Content" when node.Property.DeclaringType == types.ResourceDictionary => new ResourcesInfo(ResourcesMode.ResourceDictionaryContent, null) { Count = 1 }, - "Resources" when types.IResourceDictionary.IsAssignableFrom(node.Property.Getter.ReturnType) - => new ResourcesInfo(ResourcesMode.ElementResources, node.Property.Getter) { Count = 1 }, + "Resources" when node.Property.Getter is { } getter && types.IResourceDictionary.IsAssignableFrom(getter.ReturnType) + => new ResourcesInfo(ResourcesMode.ElementResources, getter) { Count = 1 }, _ => default }; diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlOptionMarkupExtensionTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlOptionMarkupExtensionTransformer.cs index 2b120286c4a..b6e2744125e 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlOptionMarkupExtensionTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlOptionMarkupExtensionTransformer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection.Emit; using XamlX; @@ -25,9 +26,9 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod var optionAttribute = context.GetAvaloniaTypes().MarkupExtensionOptionAttribute; var defaultOptionAttribute = context.GetAvaloniaTypes().MarkupExtensionDefaultOptionAttribute; - var typeArgument = type.GenericArguments?.FirstOrDefault(); + var typeArgument = type.GenericArguments.FirstOrDefault(); - IXamlAstValueNode defaultValue = null; + IXamlAstValueNode? defaultValue = null; var values = new List(); if (objectNode.Arguments.FirstOrDefault() is { } argument) @@ -64,7 +65,7 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod var optionsPropNode = onObj.Children.OfType() .SingleOrDefault(v => v.Property.GetClrProperty().Name == "Options") ?.Values.Single(); - var options = (optionsPropNode as XamlAstTextNode)?.Text?.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries) + var options = (optionsPropNode as XamlAstTextNode)?.Text.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty(); if (options.Length == 0) { @@ -128,8 +129,8 @@ bool AddBranchNode( throw new XamlTransformException("MarkupExtension option must not be null", li); } - var optionAsString = option.ToString(); - IXamlAstValueNode optionNode = null; + var optionAsString = option.ToString() ?? string.Empty; + IXamlAstValueNode? optionNode = null; foreach (var method in methods) { try @@ -184,7 +185,7 @@ bool AddBranchNode( IXamlAstValueNode TransformNode( IReadOnlyCollection values, - IXamlType suggestedType, + IXamlType? suggestedType, IXamlLineInfo line) { if (suggestedType is not null) @@ -212,7 +213,7 @@ internal sealed class OptionsMarkupExtensionNode : XamlMarkupExtensionNode, IXam public OptionsMarkupExtensionNode( XamlMarkupExtensionNode original, OptionsMarkupExtensionBranch[] branches, - IXamlAstValueNode defaultNode, + IXamlAstValueNode? defaultNode, IXamlType contextParameter) : base( original.Value, @@ -232,9 +233,9 @@ public override void VisitChildren(IXamlAstVisitor visitor) base.VisitChildren(visitor); } - public bool ConvertToReturnType(AstTransformationContext context, IXamlType type, out OptionsMarkupExtensionNode res) + public bool ConvertToReturnType(AstTransformationContext context, IXamlType type, [NotNullWhen(true)] out OptionsMarkupExtensionNode? res) { - IXamlAstValueNode convertedDefaultNode = null; + IXamlAstValueNode? convertedDefaultNode = null; if (ProvideValue.ExtensionNodeContainer.DefaultNode is { } defaultNode) { @@ -255,7 +256,7 @@ public bool ConvertToReturnType(AstTransformationContext context, IXamlType type return false; } - res = new OptionsMarkupExtensionNode(this, convertedBranches, convertedDefaultNode, _contextParameter); + res = new OptionsMarkupExtensionNode(this, convertedBranches!, convertedDefaultNode, _contextParameter); return true; } } @@ -264,19 +265,19 @@ internal sealed class OptionsMarkupExtensionNodesContainer : XamlAstNode { public OptionsMarkupExtensionNodesContainer( OptionsMarkupExtensionBranch[] branches, - IXamlAstValueNode defaultNode) : base(branches.FirstOrDefault()?.Value ?? defaultNode) + IXamlAstValueNode? defaultNode) : base((branches.FirstOrDefault()?.Value ?? defaultNode)!) { Branches = branches; DefaultNode = defaultNode; } public OptionsMarkupExtensionBranch[] Branches { get; } - public IXamlAstValueNode DefaultNode { get; private set; } + public IXamlAstValueNode? DefaultNode { get; private set; } public override void VisitChildren(IXamlAstVisitor visitor) { VisitList(Branches, visitor); - DefaultNode = (IXamlAstValueNode)DefaultNode?.Visit(visitor); + DefaultNode = (IXamlAstValueNode?)DefaultNode?.Visit(visitor); } public IXamlType GetReturnType() @@ -351,7 +352,7 @@ public void EmitCall(XamlEmitContext conte // - markup ext "@this" instance (always) // We always pop context from the stack, as this method decide by itself either context is needed. // We store "@this" as a local variable. But only if any conditional method is an instance method. - IXamlLocal @this = null; + IXamlLocal? @this = null; if (Parameters.Count > 0) { codeGen.Pop(); @@ -377,7 +378,7 @@ public void EmitCall(XamlEmitContext conte } if (!branch.ConditionMethod.IsStatic) { - codeGen.Ldloc(@this); + codeGen.Ldloc(@this!); } context.Emit(branch.Option, codeGen, branch.Option.Type.GetClrType()); codeGen.EmitCall(branch.ConditionMethod); @@ -402,7 +403,7 @@ public void EmitCall(XamlEmitContext conte codeGen.MarkLabel(ret); } - public bool Equals(IXamlMethod other) => ReferenceEquals(this, other); + public bool Equals(IXamlMethod? other) => ReferenceEquals(this, other); } } diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlPropertyPathTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlPropertyPathTransformer.cs index 067e01e6719..27413b386a1 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlPropertyPathTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlPropertyPathTransformer.cs @@ -14,7 +14,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers { class XamlPropertyPathException : XamlTransformException { - public XamlPropertyPathException(string message, IXamlLineInfo lineInfo, Exception innerException = null) + public XamlPropertyPathException(string message, IXamlLineInfo lineInfo, Exception? innerException = null) : base(message, lineInfo, innerException) { } @@ -50,7 +50,7 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod } var elements = new List(); - IXamlType currentType = parentScope.TargetType.GetClrType(); + var currentType = parentScope.TargetType.GetClrType(); var expectProperty = true; @@ -58,13 +58,13 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod var expectTraversal = false; var types = context.GetAvaloniaTypes(); - IXamlType GetType(string ns, string name) + IXamlType GetType(string? ns, string name) { return TypeReferenceResolver.ResolveType(context, $"{ns}:{name}", false, text, true).GetClrType(); } - void HandleProperty(string name, string typeNamespace, string typeName) + void HandleProperty(string name, string? typeNamespace, string? typeName) { if(!expectProperty || currentType == null) throw new XamlPropertyPathException("Unexpected property node", text); @@ -72,7 +72,7 @@ void HandleProperty(string name, string typeNamespace, string typeName) var propertySearchType = typeName != null ? GetType(typeNamespace, typeName) : currentType; - IXamlIlPropertyPathElementNode prop = null; + IXamlIlPropertyPathElementNode? prop = null; var avaloniaPropertyFieldName = name + "Property"; var avaloniaPropertyField = propertySearchType.GetAllFields().FirstOrDefault(f => f.IsStatic && f.IsPublic && f.Name == avaloniaPropertyFieldName); @@ -84,7 +84,8 @@ void HandleProperty(string name, string typeNamespace, string typeName) else { var clrProperty = propertySearchType.GetAllProperties().FirstOrDefault(p => p.Name == name); - prop = new XamlIClrPropertyPathElementNode(clrProperty); + if (clrProperty is not null) + prop = new XamlIClrPropertyPathElementNode(clrProperty); } if (prop == null) @@ -151,7 +152,7 @@ void HandleProperty(string name, string typeNamespace, string typeName) interface IXamlIlPropertyPathElementNode { void Emit(XamlEmitContext context, IXamlILEmitter codeGen); - IXamlType Type { get; } + IXamlType? Type { get; } } class XamlIlChildTraversalPropertyPathElementNode : IXamlIlPropertyPathElementNode @@ -159,9 +160,9 @@ class XamlIlChildTraversalPropertyPathElementNode : IXamlIlPropertyPathElementNo public void Emit(XamlEmitContext context, IXamlILEmitter codeGen) => codeGen.EmitCall( context.GetAvaloniaTypes() - .PropertyPathBuilder.FindMethod(m => m.Name == "ChildTraversal")); + .PropertyPathBuilder.GetMethod(m => m.Name == "ChildTraversal")); - public IXamlType Type => null; + public IXamlType? Type => null; } class XamlIlAvaloniaPropertyPropertyPathElementNode : IXamlIlPropertyPathElementNode @@ -178,7 +179,7 @@ public void Emit(XamlEmitContext context, => codeGen .Ldsfld(_field) .EmitCall(context.GetAvaloniaTypes() - .PropertyPathBuilder.FindMethod(m => m.Name == "Property")); + .PropertyPathBuilder.GetMethod(m => m.Name == "Property")); public IXamlType Type { get; } } @@ -198,10 +199,10 @@ public void Emit(XamlEmitContext context, .Emit(context, codeGen, _property); codeGen.EmitCall(context.GetAvaloniaTypes() - .PropertyPathBuilder.FindMethod(m => m.Name == "Property")); + .PropertyPathBuilder.GetMethod(m => m.Name == "Property")); } - public IXamlType Type => _property.Getter?.ReturnType ?? _property.Setter?.Parameters[0]; + public IXamlType Type => _property.PropertyType; } class XamlIlCastPropertyPathElementNode : IXamlIlPropertyPathElementNode @@ -220,7 +221,7 @@ public void Emit(XamlEmitContext context, codeGen .Ldtype(_type) .EmitCall(context.GetAvaloniaTypes() - .PropertyPathBuilder.FindMethod(m => m.Name == (_ensureType ? "EnsureType" : "Cast"))); + .PropertyPathBuilder.GetMethod(m => m.Name == (_ensureType ? "EnsureType" : "Cast"))); } public IXamlType Type => _type; @@ -241,14 +242,14 @@ public XamlIlPropertyPathNode(IXamlLineInfo lineInfo, } public IXamlAstTypeReference Type { get; } - public IXamlType PropertyType => _elements.LastOrDefault()?.Type; + public IXamlType? PropertyType => _elements.LastOrDefault()?.Type; public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) { codeGen - .Newobj(_types.PropertyPathBuilder.FindConstructor()); + .Newobj(_types.PropertyPathBuilder.GetConstructor()); foreach(var e in _elements) e.Emit(context, codeGen); - codeGen.EmitCall(_types.PropertyPathBuilder.FindMethod(m => m.Name == "Build")); + codeGen.EmitCall(_types.PropertyPathBuilder.GetMethod(m => m.Name == "Build")); return XamlILNodeEmitResult.Type(0, _types.PropertyPath); } } @@ -256,6 +257,6 @@ public XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen) + public XamlILNodeEmitResult? Emit(IXamlAstNode node, XamlEmitContext context, IXamlILEmitter codeGen) { if (!(node is HandleRootObjectScopeNode)) { diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSelectorTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSelectorTransformer.cs index 619940e2084..cfec681558b 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSelectorTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSelectorTransformer.cs @@ -15,7 +15,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers { internal class XamlSelectorsTransformException : XamlTransformException { - public XamlSelectorsTransformException(string message, IXamlLineInfo lineInfo, Exception innerException = null) + public XamlSelectorsTransformException(string message, IXamlLineInfo lineInfo, Exception? innerException = null) : base(message, lineInfo, innerException) { } @@ -46,14 +46,14 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod if (!(pn.Values[0] is XamlAstTextNode tn)) throw new XamlSelectorsTransformException("Selector property should be a text node", node); - var selectorType = pn.Property.GetClrProperty().Getter.ReturnType; + var selectorType = pn.Property.GetClrProperty().Getter!.ReturnType; var initialNode = new XamlIlSelectorInitialNode(node, selectorType); var avaloniaAttachedPropertyT = context.GetAvaloniaTypes().AvaloniaAttachedPropertyT; XamlIlSelectorNode Create(IEnumerable syntax, Func typeResolver) { XamlIlSelectorNode result = initialNode; - XamlIlOrSelectorNode results = null; + XamlIlOrSelectorNode? results = null; foreach (var i in syntax) { switch (i) @@ -73,7 +73,7 @@ XamlIlSelectorNode Create(IEnumerable syntax, break; case SelectorGrammar.PropertySyntax property: { - var type = result?.TargetType; + var type = result.TargetType; if (type == null) throw new XamlTransformException("Property selectors must be applied to a type.", node); @@ -96,7 +96,7 @@ XamlIlSelectorNode Create(IEnumerable syntax, } case SelectorGrammar.AttachedPropertySyntax attachedProperty: { - var targetType = result?.TargetType; + var targetType = result.TargetType; if (targetType == null) { throw new XamlTransformException("Attached Property selectors must be applied to a type.",node); @@ -172,7 +172,7 @@ XamlIlSelectorNode Create(IEnumerable syntax, } } - if (results != null && result != null) + if (results != null) { results.Add(result); } @@ -191,14 +191,13 @@ XamlIlSelectorNode Create(IEnumerable syntax, } var selector = Create(parsed, (p, n) - => TypeReferenceResolver.ResolveType(context, $"{p}:{n}", true, node, true) - ?? new XamlAstClrTypeReference(node, XamlPseudoType.Unknown, false)); + => TypeReferenceResolver.ResolveType(context, $"{p}:{n}", true, node, true)); pn.Values[0] = selector; var templateType = GetLastTemplateTypeFromSelector(selector); var styleNode = new AvaloniaXamlIlTargetTypeMetadataNode(on, - new XamlAstClrTypeReference(selector, selector.TargetType, false), + new XamlAstClrTypeReference(selector, selector.TargetType!, false), AvaloniaXamlIlTargetTypeMetadataNode.ScopeTypes.Style); return templateType switch @@ -210,7 +209,7 @@ XamlIlSelectorNode Create(IEnumerable syntax, }; } - private static IXamlType GetLastTemplateTypeFromSelector(XamlIlSelectorNode node) + private static IXamlType? GetLastTemplateTypeFromSelector(XamlIlSelectorNode? node) { while (node is not null) { @@ -219,7 +218,7 @@ private static IXamlType GetLastTemplateTypeFromSelector(XamlIlSelectorNode node SelectorType: XamlIlCombinatorSelector.CombinatorSelectorType.Template }) { - return node.Previous.TargetType; + return node.Previous?.TargetType; } node = node.Previous; } @@ -230,15 +229,15 @@ private static IXamlType GetLastTemplateTypeFromSelector(XamlIlSelectorNode node abstract class XamlIlSelectorNode : XamlAstNode, IXamlAstValueNode, IXamlAstEmitableNode { - internal XamlIlSelectorNode Previous { get; } - public abstract IXamlType TargetType { get; } + internal XamlIlSelectorNode? Previous { get; } + public abstract IXamlType? TargetType { get; } - public XamlIlSelectorNode(XamlIlSelectorNode previous, - IXamlLineInfo info = null, - IXamlType selectorType = null) : base(info ?? previous) + public XamlIlSelectorNode(XamlIlSelectorNode? previous, + IXamlLineInfo? info = null, + IXamlType? selectorType = null) : base((info ?? previous)!) { Previous = previous; - Type = selectorType == null ? previous.Type : new XamlAstClrTypeReference(this, selectorType, false); + Type = selectorType == null ? previous!.Type : new XamlAstClrTypeReference(this, selectorType, false); } public IXamlAstTypeReference Type { get; } @@ -256,7 +255,7 @@ public virtual XamlILNodeEmitResult Emit(XamlEmitContext context, IXamlILEmitter codeGen, Func method) { var selectors = context.Configuration.TypeSystem.GetType("Avalonia.Styling.Selectors"); - var found = selectors.FindMethod(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); } } @@ -268,7 +267,7 @@ public XamlIlSelectorInitialNode(IXamlLineInfo info, { } - public override IXamlType TargetType => null; + public override IXamlType? TargetType => null; protected override void DoEmit(XamlEmitContext context, IXamlILEmitter codeGen) => codeGen.Ldnull(); } @@ -310,7 +309,8 @@ public XamlIlStringSelector(XamlIlSelectorNode previous, SelectorType type, stri } - public override IXamlType TargetType => Previous?.TargetType; + public override IXamlType? TargetType => Previous?.TargetType; + protected override void DoEmit(XamlEmitContext context, IXamlILEmitter codeGen) { codeGen.Ldstr(String); @@ -336,7 +336,7 @@ public XamlIlCombinatorSelector(XamlIlSelectorNode previous, CombinatorSelectorT } public CombinatorSelectorType SelectorType => _type; - public override IXamlType TargetType => null; + public override IXamlType? TargetType => null; protected override void DoEmit(XamlEmitContext context, IXamlILEmitter codeGen) { var name = _type.ToString(); @@ -354,7 +354,8 @@ public XamlIlNotSelector(XamlIlSelectorNode previous, XamlIlSelectorNode argumen Argument = argument; } - public override IXamlType TargetType => Previous?.TargetType; + public override IXamlType? TargetType => Previous?.TargetType; + protected override void DoEmit(XamlEmitContext context, IXamlILEmitter codeGen) { context.Emit(Argument, codeGen, Type.GetClrType()); @@ -382,7 +383,8 @@ public XamlIlNthChildSelector(XamlIlSelectorNode previous, int step, int offset, _type = type; } - public override IXamlType TargetType => Previous?.TargetType; + public override IXamlType? TargetType => Previous?.TargetType; + protected override void DoEmit(XamlEmitContext context, IXamlILEmitter codeGen) { codeGen.Ldc_I4(_step); @@ -406,12 +408,13 @@ public XamlIlPropertyEqualsSelector(XamlIlSelectorNode previous, public IXamlProperty Property { get; set; } public IXamlAstValueNode Value { get; set; } - public override IXamlType TargetType => Previous?.TargetType; + public override IXamlType? TargetType => Previous?.TargetType; + protected override void DoEmit(XamlEmitContext context, IXamlILEmitter codeGen) { if (!XamlIlAvaloniaPropertyHelper.Emit(context, codeGen, Property)) throw new XamlX.XamlLoadException( - $"{Property.Name} of {(Property.Setter ?? Property.Getter).DeclaringType.GetFqn()} doesn't seem to be an AvaloniaProperty", + $"{Property.Name} of {Property.DeclaringType.GetFqn()} doesn't seem to be an AvaloniaProperty", this); context.Emit(Value, codeGen, context.Configuration.WellKnownTypes.Object); EmitCall(context, codeGen, @@ -437,7 +440,8 @@ public XamlIlAttachedPropertyEqualsSelector(XamlIlSelectorNode previous, public IXamlField PropertyFiled { get; set; } public IXamlAstValueNode Value { get; set; } - public override IXamlType TargetType => Previous?.TargetType; + public override IXamlType? TargetType => Previous?.TargetType; + protected override void DoEmit(XamlEmitContext context, IXamlILEmitter codeGen) { codeGen.Ldsfld(PropertyFiled); @@ -462,25 +466,25 @@ public void Add(XamlIlSelectorNode node) _selectors.Add(node); } - public override IXamlType TargetType + public override IXamlType? TargetType { get { - IXamlType result = null; + IXamlType? result = null; foreach (var selector in _selectors) { - if (selector.TargetType == null) + if (selector.TargetType is not { } targetType) { return null; } else if (result == null) { - result = selector.TargetType; + result = targetType; } else { - while (!result.IsAssignableFrom(selector.TargetType)) + while (result is not null && !result.IsAssignableFrom(selector.TargetType)) { result = result.BaseType; } @@ -500,11 +504,11 @@ protected override void DoEmit(XamlEmitContext() .FirstOrDefault(x => x.Property.GetClrProperty().Name == "Property"); if (property != null) { - avaloniaPropertyNode = property.Values.OfType().FirstOrDefault(); + var avaloniaPropertyNode = property.Values.OfType().FirstOrDefault(); if (avaloniaPropertyNode is null) { var propertyName = property.Values.OfType().FirstOrDefault()?.Text; @@ -61,7 +58,7 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod throw new XamlStyleTransformException("Setter.Property must be a string.", node); avaloniaPropertyNode = XamlIlAvaloniaPropertyHelper.CreateNode(context, propertyName, - new XamlAstClrTypeReference(lineInfo, targetType, false), property.Values[0]); + new XamlAstClrTypeReference(on, targetType, false), property.Values[0]); property.Values = new List {avaloniaPropertyNode}; } @@ -83,7 +80,7 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod var valueProperty = on.Children .OfType().FirstOrDefault(p => p.Property.GetClrProperty().Name == "Value"); - if (valueProperty?.Values?.Count == 1 && valueProperty.Values[0] is XamlAstTextNode) + if (valueProperty?.Values.Count == 1 && valueProperty.Values[0] is XamlAstTextNode) { if (!XamlTransformHelpers.TryGetCorrectlyTypedValue(context, valueProperty.Values[0], propType, out var converted)) @@ -101,8 +98,8 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod // but we have better validation in runtime for TemplatedBinding. // See Correctly_Resolve_TemplateBinding_In_Theme_Detached_Template test. if (!avaloniaTypes.ITemplateOfControl.IsAssignableFrom(propType) - && on.Children.OfType()?.FirstOrDefault() is { } valueObj - && avaloniaTypes.ITemplateOfControl.IsAssignableFrom(valueObj?.Type.GetClrType())) + && on.Children.OfType().FirstOrDefault() is { } valueObj + && avaloniaTypes.ITemplateOfControl.IsAssignableFrom(valueObj.Type.GetClrType())) { on.Children[on.Children.IndexOf(valueObj)] = new AvaloniaXamlIlTargetTypeMetadataNode(valueObj, new XamlAstClrTypeReference(on, targetType, false), @@ -154,10 +151,10 @@ public XamlIlDirectCallPropertySetter(IXamlMethod method, IXamlType type, bool a }; } - private bool Equals(XamlIlDirectCallPropertySetter other) - => Equals(_method, other._method) && Equals(_type, other._type); + private bool Equals(XamlIlDirectCallPropertySetter? other) + => other is not null && Equals(_method, other._method) && Equals(_type, other._type); - public override bool Equals(object obj) + public override bool Equals(object? obj) => Equals(obj as XamlIlDirectCallPropertySetter); public override int GetHashCode() diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlThemeVariantProviderTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlThemeVariantProviderTransformer.cs index 256a7472f36..02cdc181a69 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlThemeVariantProviderTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlThemeVariantProviderTransformer.cs @@ -24,7 +24,8 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod var themeDictionariesColl = avTypes.IDictionaryT.MakeGenericType(avTypes.ThemeVariant, avTypes.IThemeVariantProvider); if (context.ParentNodes().FirstOrDefault() is not XamlAstXamlPropertyValueNode propertyValueNode - || !themeDictionariesColl.IsAssignableFrom(propertyValueNode.Property.GetClrProperty().Getter.ReturnType)) + || propertyValueNode.Property.GetClrProperty().Getter is not { } getter + || !themeDictionariesColl.IsAssignableFrom(getter.ReturnType)) { return node; } diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlTransformInstanceAttachedProperties.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlTransformInstanceAttachedProperties.cs index 651bd80576b..34e8e0974b0 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlTransformInstanceAttachedProperties.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlTransformInstanceAttachedProperties.cs @@ -30,7 +30,7 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod if (clrProp != null && (clrProp.Getter?.IsStatic == false || clrProp.Setter?.IsStatic == false)) { - var declaringType = (clrProp.Getter ?? clrProp.Setter)?.DeclaringType; + var declaringType = clrProp.DeclaringType; var avaloniaPropertyFieldName = prop.Name + "Property"; var avaloniaPropertyField = declaringType.Fields.FirstOrDefault(f => f.IsStatic && f.Name == avaloniaPropertyFieldName); if (avaloniaPropertyField != null) @@ -52,10 +52,10 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod if (avaloniaPropertyType == null) return node; - if (avaloniaPropertyType.GenericArguments?.Count > 1) + if (avaloniaPropertyType.GenericArguments.Count > 1) return node; - var propertyType = avaloniaPropertyType.GenericArguments?.Count == 1 ? + var propertyType = avaloniaPropertyType.GenericArguments.Count == 1 ? avaloniaPropertyType.GenericArguments[0] : context.Configuration.WellKnownTypes.Object; @@ -97,8 +97,8 @@ public AvaloniaAttachedInstanceProperty(XamlAstNamePropertyReference prop, _avaloniaPropertyType = avaloniaPropertyType; // XamlIl doesn't support generic methods yet - if (_avaloniaPropertyType.GenericArguments?.Count > 0) - _avaloniaPropertyType = _avaloniaPropertyType.BaseType; + if (_avaloniaPropertyType.GenericArguments.Count > 0) + _avaloniaPropertyType = _avaloniaPropertyType.BaseType!; _avaloniaObject = avaloniaObject; _field = field; @@ -173,9 +173,9 @@ public GetterMethod(AvaloniaAttachedInstanceProperty parent) public IXamlMethod MakeGenericMethod(IReadOnlyList typeArguments) => throw new System.NotSupportedException(); - - public bool Equals(IXamlMethod other) => + public bool Equals(IXamlMethod? other) => other is GetterMethod m && m.Name == Name && m.DeclaringType.Equals(DeclaringType); + public IXamlType ReturnType => Parent.PropertyType; public IReadOnlyList Parameters { get; } diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs index 02201b81090..8fc4cfff76c 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs @@ -28,7 +28,6 @@ sealed class AvaloniaXamlIlWellKnownTypes public IXamlType IDisposable { get; } public IXamlType ICommand { get; } public XamlTypeWellKnownTypes XamlIlTypes { get; } - public XamlLanguageTypeMappings XamlIlMappings { get; } public IXamlType Transitions { get; } public IXamlType AssignBindingAttribute { get; } public IXamlType DependsOnAttribute { get; } @@ -143,12 +142,12 @@ sealed internal class InteractivityWellKnownTypes internal InteractivityWellKnownTypes(TransformerConfiguration cfg) { var ts = cfg.TypeSystem; - Interactive = ts.FindType("Avalonia.Interactivity.Interactive"); - RoutedEvent = ts.FindType("Avalonia.Interactivity.RoutedEvent"); - RoutedEventArgs = ts.FindType("Avalonia.Interactivity.RoutedEventArgs"); - var eventHanlderT = ts.FindType("System.EventHandler`1"); + 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"); RoutedEventHandler = eventHanlderT.MakeGenericType(RoutedEventArgs); - AddHandler = Interactive.FindMethod(m => m.IsPublic + AddHandler = Interactive.GetMethod(m => m.IsPublic && !m.IsStatic && m.Name == "AddHandler" && m.Parameters.Count == 4 @@ -157,15 +156,15 @@ internal InteractivityWellKnownTypes(TransformerConfiguration cfg) && m.Parameters[2].IsEnum && m.Parameters[3].Equals(cfg.WellKnownTypes.Boolean) ); - AddHandlerT = Interactive.FindMethod(m => m.IsPublic + AddHandlerT = Interactive.GetMethod(m => m.IsPublic && !m.IsStatic && m.Name == "AddHandler" && 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 + && m.Parameters[0].GenericArguments.Count == 1 // This is specific this case workaround to check is generic method && (cfg.WellKnownTypes.Delegate).IsAssignableFrom(m.Parameters[1]) && m.Parameters[2].IsEnum - && m.Parameters[3].Equals(cfg.WellKnownTypes.Boolean) == true + && m.Parameters[3].Equals(cfg.WellKnownTypes.Boolean) ); } @@ -186,7 +185,7 @@ public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg) AvaloniaAttachedPropertyT = cfg.TypeSystem.GetType("Avalonia.AttachedProperty`1"); BindingPriority = cfg.TypeSystem.GetType("Avalonia.Data.BindingPriority"); AvaloniaObjectSetStyledPropertyValue = AvaloniaObject - .FindMethod(m => m.IsPublic && !m.IsStatic && m.Name == "SetValue" + .GetMethod(m => m.IsPublic && !m.IsStatic && m.Name == "SetValue" && m.Parameters.Count == 3 && m.Parameters[0].Name == "StyledProperty`1" && m.Parameters[2].Equals(BindingPriority)); @@ -205,7 +204,7 @@ public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg) AvaloniaListAttribute = cfg.TypeSystem.GetType("Avalonia.Metadata.AvaloniaListAttribute"); AvaloniaList = cfg.TypeSystem.GetType("Avalonia.Collections.AvaloniaList`1"); OnExtensionType = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.On"); - AvaloniaObjectBindMethod = AvaloniaObjectExtensions.FindMethod("Bind", IDisposable, false, AvaloniaObject, + AvaloniaObjectBindMethod = AvaloniaObjectExtensions.GetMethod("Bind", IDisposable, false, AvaloniaObject, AvaloniaProperty, IBinding, cfg.WellKnownTypes.Object); UnsetValueType = cfg.TypeSystem.GetType("Avalonia.UnsetValueType"); @@ -230,7 +229,7 @@ public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg) NameScopeSetNameScope = NameScope.GetMethod(new FindMethodMethodSignature("SetNameScope", XamlIlTypes.Void, StyledElement, INameScope) { IsStatic = true }); - AvaloniaObjectSetValueMethod = AvaloniaObject.FindMethod("SetValue", IDisposable, + 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"); @@ -292,7 +291,7 @@ public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg) StyledElementClassesProperty = StyledElement.Properties.First(x => x.Name == "Classes" && x.PropertyType.Equals(Classes)); ClassesBindMethod = cfg.TypeSystem.GetType("Avalonia.StyledElementExtensions") - .FindMethod("BindClass", IDisposable, false, StyledElement, + .GetMethod("BindClass", IDisposable, false, StyledElement, cfg.WellKnownTypes.String, IBinding, cfg.WellKnownTypes.Object); @@ -311,10 +310,10 @@ public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg) MergeResourceInclude = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.Styling.MergeResourceInclude"); IResourceDictionary = cfg.TypeSystem.GetType("Avalonia.Controls.IResourceDictionary"); ResourceDictionary = cfg.TypeSystem.GetType("Avalonia.Controls.ResourceDictionary"); - ResourceDictionaryDeferredAdd = ResourceDictionary.FindMethod("AddDeferred", XamlIlTypes.Void, true, XamlIlTypes.Object, + ResourceDictionaryDeferredAdd = ResourceDictionary.GetMethod("AddDeferred", XamlIlTypes.Void, true, XamlIlTypes.Object, cfg.TypeSystem.GetType("Avalonia.Controls.IDeferredContent")); - ResourceDictionaryEnsureCapacity = ResourceDictionary.FindMethod("EnsureCapacity", XamlIlTypes.Void, true, XamlIlTypes.Int32); - ResourceDictionaryGetCount = ResourceDictionary.FindMethod("get_Count", XamlIlTypes.Int32, true); + 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() { cfg.WellKnownTypes.String, UriKind }); diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Visitors/NameScopeRegistrationVisitor.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Visitors/NameScopeRegistrationVisitor.cs index 4acc43fdabc..28aef1f770c 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Visitors/NameScopeRegistrationVisitor.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Visitors/NameScopeRegistrationVisitor.cs @@ -25,7 +25,7 @@ IXamlAstNode IXamlAstVisitor.Visit(IXamlAstNode node) && node is AvaloniaNameScopeRegistrationXamlIlNode nameScopeRegistration && nameScopeRegistration.Name is XamlAstTextNode textNode) { - this[textNode.Text] = (nameScopeRegistration.TargetType, textNode); + this[textNode.Text] = (nameScopeRegistration.TargetType ?? XamlPseudoType.Unknown, textNode); } return node; diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs index 2ec19a1aa48..3ecd855980a 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs @@ -51,9 +51,8 @@ public static bool Emit(XamlIlEmitContext context, IXamlILEmitter emitter, XamlA public static bool Emit(XamlIlEmitContext context, IXamlILEmitter emitter, IXamlProperty property) { - var type = (property.Getter ?? property.Setter).DeclaringType; var name = property.Name + "Property"; - var found = type.Fields.FirstOrDefault(f => f.IsStatic && f.Name == name); + var found = property.DeclaringType.Fields.FirstOrDefault(f => f.IsStatic && f.Name == name); if (found == null) return false; @@ -225,11 +224,13 @@ protected AvaloniaPropertyCustomSetter( AvaloniaXamlIlWellKnownTypes types, IXamlType declaringType, IXamlField avaloniaProperty, - bool allowNull) + bool allowNull, + IReadOnlyList parameters) { Types = types; AvaloniaProperty = avaloniaProperty; TargetType = declaringType; + Parameters = parameters; BinderParameters = new PropertySetterBinderParameters { AllowXNull = allowNull, @@ -241,7 +242,7 @@ protected AvaloniaPropertyCustomSetter( public PropertySetterBinderParameters BinderParameters { get; } - public IReadOnlyList Parameters { get; set; } + public IReadOnlyList Parameters { get; } public IReadOnlyList CustomAttributes => Array.Empty(); public abstract void Emit(IXamlILEmitter emitter); @@ -251,7 +252,7 @@ public abstract void EmitWithArguments( IXamlILEmitter emitter, IReadOnlyList arguments); - public bool Equals(AvaloniaPropertyCustomSetter other) + public bool Equals(AvaloniaPropertyCustomSetter? other) { if (ReferenceEquals(null, other)) return false; @@ -261,7 +262,7 @@ public bool Equals(AvaloniaPropertyCustomSetter other) return GetType() == other.GetType() && AvaloniaProperty.Equals(other.AvaloniaProperty); } - public override bool Equals(object obj) + public override bool Equals(object? obj) => Equals(obj as AvaloniaPropertyCustomSetter); public override int GetHashCode() @@ -270,11 +271,12 @@ public override int GetHashCode() class BindingSetter : AvaloniaPropertyCustomSetter { - public BindingSetter(AvaloniaXamlIlWellKnownTypes types, + public BindingSetter( + AvaloniaXamlIlWellKnownTypes types, IXamlType declaringType, - IXamlField avaloniaProperty) : base(types, declaringType, avaloniaProperty, false) + IXamlField avaloniaProperty) + : base(types, declaringType, avaloniaProperty, false, [types.IBinding]) { - Parameters = new[] { types.IBinding }; } public override void Emit(IXamlILEmitter emitter) @@ -307,11 +309,12 @@ private void EmitAnchorAndBind(IXamlILEmitter emitter) class BindingWithPrioritySetter : AvaloniaPropertyCustomSetter { - public BindingWithPrioritySetter(AvaloniaXamlIlWellKnownTypes types, + public BindingWithPrioritySetter( + AvaloniaXamlIlWellKnownTypes types, IXamlType declaringType, - IXamlField avaloniaProperty) : base(types, declaringType, avaloniaProperty, false) + IXamlField avaloniaProperty) + : base(types, declaringType, avaloniaProperty, false, [types.BindingPriority, types.IBinding]) { - Parameters = new[] { types.BindingPriority, types.IBinding }; } public override void Emit(IXamlILEmitter emitter) @@ -345,11 +348,13 @@ private void EmitAnchorAndBind(IXamlILEmitter emitter) class SetValueWithPrioritySetter : AvaloniaPropertyCustomSetter { - public SetValueWithPrioritySetter(AvaloniaXamlIlWellKnownTypes types, IXamlType declaringType, IXamlField avaloniaProperty, + public SetValueWithPrioritySetter( + AvaloniaXamlIlWellKnownTypes types, + IXamlType declaringType, + IXamlField avaloniaProperty, IXamlType propertyType) - : base(types, declaringType, avaloniaProperty, propertyType.AcceptsNull()) + : base(types, declaringType, avaloniaProperty, propertyType.AcceptsNull(), [types.BindingPriority, propertyType]) { - Parameters = new[] { types.BindingPriority, propertyType }; } public override void Emit(IXamlILEmitter emitter) @@ -393,10 +398,12 @@ private void EmitSetStyledPropertyValue(IXamlILEmitter emitter) class UnsetValueSetter : AvaloniaPropertyCustomSetter { - public UnsetValueSetter(AvaloniaXamlIlWellKnownTypes types, IXamlType declaringType, IXamlField avaloniaProperty) - : base(types, declaringType, avaloniaProperty, false) + public UnsetValueSetter( + AvaloniaXamlIlWellKnownTypes types, + IXamlType declaringType, + IXamlField avaloniaProperty) + : base(types, declaringType, avaloniaProperty, false, [types.UnsetValueType]) { - Parameters = new[] { types.UnsetValueType }; } public override void Emit(IXamlILEmitter codegen) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs index 0adb26973d6..d86e137079b 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs @@ -21,7 +21,7 @@ static class XamlIlBindingPathHelper { public static IXamlType UpdateCompiledBindingExtension(AstTransformationContext context, XamlAstConstructableObjectNode binding, Func startTypeResolver, IXamlType selfType) { - IXamlType bindingResultType = null; + IXamlType? bindingResultType; if (binding.Arguments.Count > 0 && binding.Arguments[0] is ParsedBindingPathNode bindingPath) { var transformed = TransformBindingPath( @@ -90,8 +90,12 @@ private static XamlIlBindingPathNode TransformForTargetTyping(XamlIlBindingPathN if (GetPropertyType(context, parentNode) == context.GetAvaloniaTypes().ICommand && lastElement is XamlIlClrMethodPathElementNode methodPathElement) { - IXamlMethod executeMethod = methodPathElement.Method; - IXamlMethod canExecuteMethod = executeMethod.DeclaringType.FindMethod(new FindMethodMethodSignature($"Can{executeMethod.Name}", context.Configuration.WellKnownTypes.Boolean, context.Configuration.WellKnownTypes.Object)); + var executeMethod = methodPathElement.Method; + var canExecuteMethod = executeMethod.DeclaringType.FindMethod(new FindMethodMethodSignature( + $"Can{executeMethod.Name}", + context.Configuration.WellKnownTypes.Boolean, + context.Configuration.WellKnownTypes.Object)); + List dependsOnProperties = new(); if (canExecuteMethod is not null) { @@ -99,7 +103,7 @@ private static XamlIlBindingPathNode TransformForTargetTyping(XamlIlBindingPathN { if (attr.Type == context.GetAvaloniaTypes().DependsOnAttribute) { - dependsOnProperties.Add((string)attr.Parameters[0]); + dependsOnProperties.Add((string)attr.Parameters[0]!); } } } @@ -110,7 +114,7 @@ private static XamlIlBindingPathNode TransformForTargetTyping(XamlIlBindingPathN return transformed; } - private static IXamlType GetPropertyType(AstTransformationContext context, XamlPropertyAssignmentNode node) + private static IXamlType? GetPropertyType(AstTransformationContext context, XamlPropertyAssignmentNode node) { var setterType = context.GetAvaloniaTypes().Setter; @@ -126,11 +130,11 @@ private static IXamlType GetPropertyType(AstTransformationContext context, XamlP .FirstOrDefault(x => x.Property.GetClrProperty().Name == "Property"); var property = propertyAssignment?.Values.FirstOrDefault() as IXamlIlAvaloniaPropertyNode; - if (property.AvaloniaPropertyType is { } propertyType) + if (property?.AvaloniaPropertyType is { } propertyType) return propertyType; } - return node.Property?.Getter?.ReturnType; + return node.Property.Getter?.ReturnType; } private static XamlIlBindingPathNode TransformBindingPath(AstTransformationContext context, IXamlLineInfo lineInfo, Func startTypeResolver, IXamlType selfType, IEnumerable bindingExpression) @@ -150,7 +154,7 @@ private static XamlIlBindingPathNode TransformBindingPath(AstTransformationConte case BindingExpressionGrammar.StreamNode _: { IXamlType targetType = targetTypeResolver(); - IXamlType observableType; + IXamlType? observableType; if (targetType.GenericTypeDefinition?.Equals(context.Configuration.TypeSystem.FindType("System.IObservable`1")) == true) { observableType = targetType; @@ -165,10 +169,13 @@ private static XamlIlBindingPathNode TransformBindingPath(AstTransformationConte nodes.Add(new XamlIlStreamObservablePathElementNode(observableType.GenericArguments[0])); break; } + bool foundTask = false; + var taskType = context.Configuration.TypeSystem.GetType("System.Threading.Tasks.Task`1"); + for (var currentType = targetType; currentType != null; currentType = currentType.BaseType) { - if (currentType.GenericTypeDefinition.Equals(context.Configuration.TypeSystem.GetType("System.Threading.Tasks.Task`1"))) + if (currentType.GenericTypeDefinition?.Equals(taskType) == true) { foundTask = true; nodes.Add(new XamlIlStreamTaskPathElementNode(currentType.GenericArguments[0])); @@ -216,13 +223,13 @@ private static XamlIlBindingPathNode TransformBindingPath(AstTransformationConte break; } - IXamlProperty property = null; + IXamlProperty? property = null; foreach (var currentType in TraverseTypeHierarchy(targetType)) { var defaultMemberAttribute = currentType.CustomAttributes.FirstOrDefault(x => x.Type.Namespace == "System.Reflection" && x.Type.Name == "DefaultMemberAttribute"); if (defaultMemberAttribute != null) { - property = currentType.GetAllProperties().FirstOrDefault(x => x.Name == (string)defaultMemberAttribute.Parameters[0]); + property = currentType.GetAllProperties().FirstOrDefault(x => x.Name == (string)defaultMemberAttribute.Parameters[0]!); break; } } @@ -255,8 +262,17 @@ private static XamlIlBindingPathNode TransformBindingPath(AstTransformationConte } case BindingExpressionGrammar.AttachedPropertyNameNode attachedProp: var avaloniaPropertyFieldName = attachedProp.PropertyName + "Property"; - var avaloniaPropertyField = GetType(attachedProp.Namespace, attachedProp.TypeName).GetAllFields().FirstOrDefault(f => + var propertyOwnerType = GetType(attachedProp.Namespace, attachedProp.TypeName); + var avaloniaPropertyField = propertyOwnerType.GetAllFields().FirstOrDefault(f => f.IsStatic && f.IsPublic && f.Name == avaloniaPropertyFieldName); + + if (avaloniaPropertyField is null) + { + throw new XamlTransformException( + $"Unable to find {avaloniaPropertyFieldName} field on type {propertyOwnerType.GetFullName()}", + lineInfo); + } + nodes.Add(new XamlIlAvaloniaPropertyPropertyPathElementNode(avaloniaPropertyField, XamlIlAvaloniaPropertyHelper.GetAvaloniaPropertyType(avaloniaPropertyField, context.GetAvaloniaTypes(), lineInfo))); break; @@ -305,7 +321,7 @@ private static XamlIlBindingPathNode TransformBindingPath(AstTransformationConte } break; case BindingExpressionGrammar.NameNode elementName: - IXamlType elementType = null; + IXamlType? elementType = null; foreach (var deferredContent in context.ParentNodes().OfType()) { elementType = ScopeRegistrationFinder.GetTargetType(deferredContent, elementName.Name); @@ -343,7 +359,7 @@ private static XamlIlBindingPathNode TransformBindingPath(AstTransformationConte return new XamlIlBindingPathNode(lineInfo, context.GetAvaloniaTypes().CompiledBindingPath, transformNodes, nodes); - IXamlType GetType(string ns, string name) + IXamlType GetType(string? ns, string? name) { return TypeReferenceResolver.ResolveType(context, $"{ns}:{name}", false, lineInfo, true).GetClrType(); @@ -406,9 +422,9 @@ private ScopeRegistrationFinder(string name) string Name { get; } - IXamlType TargetType { get; set; } + IXamlType? TargetType { get; set; } - public static IXamlType GetTargetType(IXamlAstNode namescopeRoot, string name) + public static IXamlType? GetTargetType(IXamlAstNode namescopeRoot, string name) { // If we start from the nested scope - skip it. if (namescopeRoot is NestedScopeMetadataNode scope) @@ -471,7 +487,7 @@ public XamlIlNotPathElementNode(IXamlType boolType) public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) { - codeGen.EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.FindMethod(m => m.Name == "Not")); + codeGen.EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.GetMethod(m => m.Name == "Not")); } } @@ -486,7 +502,7 @@ public XamlIlStreamObservablePathElementNode(IXamlType type) public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) { - codeGen.EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.FindMethod(m => m.Name == "StreamObservable").MakeGenericMethod(new[] { Type })); + codeGen.EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.GetMethod(m => m.Name == "StreamObservable").MakeGenericMethod(new[] { Type })); } } @@ -501,7 +517,7 @@ public XamlIlStreamTaskPathElementNode(IXamlType type) public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) { - codeGen.EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.FindMethod(m => m.Name == "StreamTask").MakeGenericMethod(new[] { Type })); + codeGen.EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.GetMethod(m => m.Name == "StreamTask").MakeGenericMethod(new[] { Type })); } } @@ -516,7 +532,7 @@ public SelfPathElementNode(IXamlType type) public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) { - codeGen.EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.FindMethod(m => m.Name == "Self")); + codeGen.EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.GetMethod(m => m.Name == "Self")); } } @@ -536,7 +552,7 @@ public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) { codeGen.Ldtype(Type) .Ldc_I4(_level) - .EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.FindMethod(m => m.Name == "Ancestor")); + .EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.GetMethod(m => m.Name == "Ancestor")); } } @@ -556,7 +572,7 @@ public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) { codeGen.Ldtype(Type) .Ldc_I4(_level) - .EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.FindMethod(m => m.Name == "VisualAncestor")); + .EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.GetMethod(m => m.Name == "VisualAncestor")); } } @@ -581,7 +597,7 @@ public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) .Ldloc(context.ContextLocal) .Ldfld(scopeField) .Ldstr(_name) - .EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.FindMethod(m => m.Name == "ElementName")); + .EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.GetMethod(m => m.Name == "ElementName")); } } @@ -597,7 +613,7 @@ public TemplatedParentPathElementNode(IXamlType elementType) public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) { codeGen - .EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.FindMethod(m => m.Name == "TemplatedParent")); + .EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.GetMethod(m => m.Name == "TemplatedParent")); } } @@ -617,7 +633,7 @@ public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) context.Configuration.GetExtra() .EmitLoadAvaloniaPropertyAccessorFactory(context, codeGen); codeGen.EmitCall(context.GetAvaloniaTypes() - .CompiledBindingPathBuilder.FindMethod(m => m.Name == "Property")); + .CompiledBindingPathBuilder.GetMethod(m => m.Name == "Property")); } public IXamlType Type { get; } @@ -642,10 +658,10 @@ public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) codeGen .EmitCall(context.GetAvaloniaTypes() - .CompiledBindingPathBuilder.FindMethod(m => m.Name == "Property")); + .CompiledBindingPathBuilder.GetMethod(m => m.Name == "Property")); } - public IXamlType Type => _property.Getter?.ReturnType ?? _property.Setter?.Parameters[0]; + public IXamlType Type => _property.PropertyType; } class XamlIlClrMethodPathElementNode : IXamlIlBindingPathElementNode @@ -662,7 +678,7 @@ public XamlIlClrMethodPathElementNode(IXamlMethod method, IXamlType systemDelega public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) { - IXamlTypeBuilder newDelegateTypeBuilder = null; + IXamlTypeBuilder? newDelegateTypeBuilder = null; IXamlType specificDelegateType; if (Method.ReturnType == context.Configuration.WellKnownTypes.Void && Method.Parameters.Count == 0) { @@ -699,7 +715,7 @@ public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) .Ldtoken(Method) .Ldtoken(specificDelegateType) .EmitCall(context.GetAvaloniaTypes() - .CompiledBindingPathBuilder.FindMethod(m => m.Name == "Method")); + .CompiledBindingPathBuilder.GetMethod(m => m.Name == "Method")); newDelegateTypeBuilder?.CreateType(); } @@ -708,10 +724,14 @@ public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) class XamlIlClrMethodAsCommandPathElementNode : IXamlIlBindingPathElementNode { private readonly IXamlMethod _executeMethod; - private readonly IXamlMethod _canExecuteMethod; + private readonly IXamlMethod? _canExecuteMethod; private readonly IReadOnlyList _dependsOnProperties; - public XamlIlClrMethodAsCommandPathElementNode(IXamlType iCommandType, IXamlMethod executeMethod, IXamlMethod canExecuteMethod, IReadOnlyList dependsOnProperties) + public XamlIlClrMethodAsCommandPathElementNode( + IXamlType iCommandType, + IXamlMethod executeMethod, + IXamlMethod? canExecuteMethod, + IReadOnlyList dependsOnProperties) { Type = iCommandType; _executeMethod = executeMethod; @@ -719,7 +739,6 @@ public XamlIlClrMethodAsCommandPathElementNode(IXamlType iCommandType, IXamlMeth _dependsOnProperties = dependsOnProperties; } - public IXamlType Type { get; } public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) @@ -773,7 +792,7 @@ public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) codeGen .EmitCall(context.GetAvaloniaTypes() - .CompiledBindingPathBuilder.FindMethod(m => m.Name == "Command")); + .CompiledBindingPathBuilder.GetMethod(m => m.Name == "Command")); } } @@ -813,10 +832,10 @@ public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) } codeGen.EmitCall(context.GetAvaloniaTypes() - .CompiledBindingPathBuilder.FindMethod(m => m.Name == "Property")); + .CompiledBindingPathBuilder.GetMethod(m => m.Name == "Property")); } - public IXamlType Type => _property.Getter?.ReturnType ?? _property.Setter?.Parameters[0]; + public IXamlType Type => _property.PropertyType; } class XamlIlArrayIndexerPathElementNode : IXamlIlBindingPathElementNode @@ -856,10 +875,10 @@ public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) codeGen.Ldloc(indices) .Ldtype(Type) .EmitCall(context.GetAvaloniaTypes() - .CompiledBindingPathBuilder.FindMethod(m => m.Name == "ArrayElement")); + .CompiledBindingPathBuilder.GetMethod(m => m.Name == "ArrayElement")); } - public IXamlType Type => _arrayType.ArrayElementType; + public IXamlType Type => _arrayType.ArrayElementType!; } class RawSourcePathElementNode : XamlAstNode, IXamlIlBindingPathElementNode @@ -880,7 +899,7 @@ public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) context.Emit(_rawSource, codeGen, Type); codeGen .EmitCall(context.GetAvaloniaTypes() - .CompiledBindingPathBuilder.FindMethod(m => m.Name == "SetRawSource")); + .CompiledBindingPathBuilder.GetMethod(m => m.Name == "SetRawSource")); } } @@ -895,7 +914,7 @@ public TypeCastPathElementNode(IXamlType ancestorType) public void Emit(XamlIlEmitContext context, IXamlILEmitter codeGen) { - codeGen.EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.FindMethod(m => m.Name == "TypeCast").MakeGenericMethod(new[] { Type })); + codeGen.EmitCall(context.GetAvaloniaTypes().CompiledBindingPathBuilder.GetMethod(m => m.Name == "TypeCast").MakeGenericMethod(new[] { Type })); } } @@ -931,7 +950,7 @@ public XamlILNodeEmitResult Emit(XamlIlEmitContext context, IXamlILEmitter codeG // of 1 to indicate that we don't want TemplatedParent compatibility hacks enabled. codeGen .Ldc_I4(1) - .Newobj(types.CompiledBindingPathBuilder.FindConstructor(new() { intType })); + .Newobj(types.CompiledBindingPathBuilder.GetConstructor(new() { intType })); foreach (var transform in _transformElements) { @@ -943,7 +962,7 @@ public XamlILNodeEmitResult Emit(XamlIlEmitContext context, IXamlILEmitter codeG element.Emit(context, codeGen); } - codeGen.EmitCall(types.CompiledBindingPathBuilder.FindMethod(m => m.Name == "Build")); + codeGen.EmitCall(types.CompiledBindingPathBuilder.GetMethod(m => m.Name == "Build")); return XamlILNodeEmitResult.Type(0, types.CompiledBindingPath); } diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlClrPropertyInfoHelper.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlClrPropertyInfoHelper.cs index 16e66c5b723..fb7b017956d 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlClrPropertyInfoHelper.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlClrPropertyInfoHelper.cs @@ -3,7 +3,6 @@ using System.Linq; using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers; using XamlX.Ast; -using XamlX.Transform; using XamlX.TypeSystem; using XamlX.IL; using XamlX.Emit; @@ -22,9 +21,12 @@ public XamlIlClrPropertyInfoEmitter(IXamlTypeBuilder builder) _builder = builder; } - static string GetKey(IXamlProperty property, string indexerArgumentsKey) + static string GetKey(IXamlProperty property, string? indexerArgumentsKey) { - var baseKey = property.Getter.DeclaringType.GetFullName() + "." + property.Name; + var declaringType = (property.Getter ?? property.Setter)?.DeclaringType + ?? throw new InvalidOperationException($"Couldn't get declaring type for property {property}"); + + var baseKey = declaringType.GetFullName() + "." + property.Name; if (indexerArgumentsKey is null) { @@ -34,9 +36,14 @@ static string GetKey(IXamlProperty property, string indexerArgumentsKey) return baseKey + $"[{indexerArgumentsKey}]"; } - public IXamlType Emit(XamlEmitContext context, IXamlILEmitter codeGen, IXamlProperty property, IReadOnlyCollection indexerArguments = null, string indexerArgumentsKey = null) + public IXamlType Emit( + XamlEmitContext context, + IXamlILEmitter codeGen, + IXamlProperty property, + IReadOnlyCollection? indexerArguments = null, + string? indexerArgumentsKey = null) { - indexerArguments = indexerArguments ?? Array.Empty(); + indexerArguments ??= []; var types = context.GetAvaloniaTypes(); IXamlMethod Get() { @@ -83,7 +90,7 @@ void Load(IXamlMethod m, IXamlILEmitter cg, bool passThis) new[] {types.XamlIlTypes.Object}, name + "!Getter", XamlVisibility.Private, true, false); if (getter != null) { - Load(property.Getter, getter.Generator, !property.Getter.IsStatic); + Load(property.Getter!, getter.Generator, !property.Getter!.IsStatic); getter.Generator.EmitCall(property.Getter); if (property.Getter.ReturnType.IsValueType) @@ -98,7 +105,7 @@ void Load(IXamlMethod m, IXamlILEmitter cg, bool passThis) name + "!Setter", XamlVisibility.Private, true, false); if (setter != null) { - Load(property.Setter, setter.Generator, !property.Getter.IsStatic); + Load(property.Setter!, setter.Generator, !property.Setter!.IsStatic); setter.Generator.Ldarg(1); @@ -128,7 +135,7 @@ void Load(IXamlMethod m, IXamlILEmitter cg, bool passThis) .MarkLabel(cacheMiss) .Ldstr(property.Name); - void EmitFunc(IXamlILEmitter emitter, IXamlMethod method, IXamlType del) + void EmitFunc(IXamlILEmitter emitter, IXamlMethod? method, IXamlType del) { if (method == null) emitter.Ldnull(); diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs index 938438ebb81..bc51aea039a 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs @@ -17,7 +17,7 @@ class XamlIlPropertyInfoAccessorFactoryEmitter { private const string IndexerClosureFactoryMethodName = "CreateAccessor"; private readonly IXamlTypeBuilder _indexerClosureTypeBuilder; - private IXamlType _indexerClosureType; + private IXamlType? _indexerClosureType; public XamlIlPropertyInfoAccessorFactoryEmitter(IXamlTypeBuilder indexerClosureType) { _indexerClosureTypeBuilder = indexerClosureType; @@ -57,7 +57,7 @@ public IXamlType EmitLoadIndexerAccessorFactory(XamlIlEmitContext context, IXaml } context.Emit(value, codeGen, intType); - codeGen.Newobj(_indexerClosureType.FindConstructor(new List { intType })); + codeGen.Newobj(_indexerClosureType.GetConstructor(new List { intType })); EmitLoadPropertyAccessorFactory(context, codeGen, _indexerClosureType, IndexerClosureFactoryMethodName, isStatic: false); return EmitCreateAccessorFactoryDelegate(context, codeGen); } diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlTrampolineBuilder.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlTrampolineBuilder.cs index f50f5a09c5c..ae26aec993b 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlTrampolineBuilder.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlTrampolineBuilder.cs @@ -54,10 +54,10 @@ public IXamlMethod EmitCommandExecuteTrampoline(XamlEmitContext m.Name == "get_CurrentCulture")) + .EmitCall(context.Configuration.WellKnownTypes.CultureInfo.GetMethod(m => m.Name == "get_CurrentCulture")) .Ldloca(convertedValue) .EmitCall( - context.GetAvaloniaTypes().TypeUtilities.FindMethod(m => m.Name == "TryConvert"), + context.GetAvaloniaTypes().TypeUtilities.GetMethod(m => m.Name == "TryConvert"), swallowResult: true) .Ldloc(convertedValue) .Unbox_Any(executeMethod.Parameters[0]); diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github b/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github index 941dafce490..f5aa2e37cb8 160000 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github @@ -1 +1 @@ -Subproject commit 941dafce490ffd21178f4493a7f0425e9d478e60 +Subproject commit f5aa2e37cb8d75857aed649742765c464d5b8fd9 diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs index d7c8003b2b9..5b86116106b 100644 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs @@ -361,7 +361,7 @@ public static IServiceProvider CreateRootServiceProviderV2() { return new RootServiceProvider(new NameScope(), null); } - public static IServiceProvider CreateRootServiceProviderV3(IServiceProvider parentServiceProvider) + public static IServiceProvider CreateRootServiceProviderV3(IServiceProvider? parentServiceProvider) { return new RootServiceProvider(new NameScope(), parentServiceProvider); } diff --git a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj index c0daef63a08..4255813c5fe 100644 --- a/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj +++ b/src/tools/Avalonia.Designer.HostApp/Avalonia.Designer.HostApp.csproj @@ -14,11 +14,12 @@ - + + diff --git a/src/tools/Avalonia.Designer.HostApp/DesignXamlLoader.cs b/src/tools/Avalonia.Designer.HostApp/DesignXamlLoader.cs index f2e8eb42b83..dfa70373b64 100644 --- a/src/tools/Avalonia.Designer.HostApp/DesignXamlLoader.cs +++ b/src/tools/Avalonia.Designer.HostApp/DesignXamlLoader.cs @@ -19,11 +19,11 @@ public object Load(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfigur return AvaloniaXamlIlRuntimeCompiler.Load(document, configuration); } - private void PreloadDepsAssemblies(Assembly targetAssembly) + private void PreloadDepsAssemblies(Assembly? targetAssembly) { // Assemblies loaded in memory (e.g. single file) return empty string from Location. // In these cases, don't try probing next to the assembly. - var assemblyLocation = targetAssembly.Location; + var assemblyLocation = targetAssembly?.Location; if (string.IsNullOrEmpty(assemblyLocation)) { return; @@ -32,7 +32,7 @@ private void PreloadDepsAssemblies(Assembly targetAssembly) var depsJsonFile = Path.ChangeExtension(assemblyLocation, ".deps.json"); if (!File.Exists(depsJsonFile)) { - var sameDir = Path.GetDirectoryName(depsJsonFile); + var sameDir = Path.GetDirectoryName(depsJsonFile)!; var fallbackDepsFiles = Directory.GetFiles(sameDir, "*.deps.json"); if (fallbackDepsFiles.Length == 1) { diff --git a/src/tools/Avalonia.Generators/Avalonia.Generators.csproj b/src/tools/Avalonia.Generators/Avalonia.Generators.csproj index fbd331b6e06..a5a4cf9039e 100644 --- a/src/tools/Avalonia.Generators/Avalonia.Generators.csproj +++ b/src/tools/Avalonia.Generators/Avalonia.Generators.csproj @@ -8,6 +8,7 @@ false true true + enable @@ -16,20 +17,21 @@ - + - - + + + - + - + diff --git a/src/tools/Avalonia.Generators/Common/Domain/IViewResolver.cs b/src/tools/Avalonia.Generators/Common/Domain/IViewResolver.cs index c3c219e3f01..49ceb6f69ee 100644 --- a/src/tools/Avalonia.Generators/Common/Domain/IViewResolver.cs +++ b/src/tools/Avalonia.Generators/Common/Domain/IViewResolver.cs @@ -5,7 +5,7 @@ namespace Avalonia.Generators.Common.Domain; internal interface IViewResolver { - ResolvedView ResolveView(string xaml); + ResolvedView? ResolveView(string xaml); } internal record ResolvedView(string ClassName, IXamlType XamlType, string Namespace, XamlDocument Xaml); diff --git a/src/tools/Avalonia.Generators/Common/XamlXViewResolver.cs b/src/tools/Avalonia.Generators/Common/XamlXViewResolver.cs index 5bbe0c060d4..b0495b2840e 100644 --- a/src/tools/Avalonia.Generators/Common/XamlXViewResolver.cs +++ b/src/tools/Avalonia.Generators/Common/XamlXViewResolver.cs @@ -14,18 +14,18 @@ internal class XamlXViewResolver : IViewResolver, IXamlAstVisitor private readonly RoslynTypeSystem _typeSystem; private readonly MiniCompiler _compiler; private readonly bool _checkTypeValidity; - private readonly Action _onTypeInvalid; - private readonly Action _onUnhandledError; + private readonly Action? _onTypeInvalid; + private readonly Action? _onUnhandledError; - private ResolvedView _resolvedClass; - private XamlDocument _xaml; + private ResolvedView? _resolvedClass; + private XamlDocument? _xaml; public XamlXViewResolver( RoslynTypeSystem typeSystem, MiniCompiler compiler, bool checkTypeValidity = false, - Action onTypeInvalid = null, - Action onUnhandledError = null) + Action? onTypeInvalid = null, + Action? onUnhandledError = null) { _checkTypeValidity = checkTypeValidity; _onTypeInvalid = onTypeInvalid; @@ -34,7 +34,7 @@ public XamlXViewResolver( _compiler = compiler; } - public ResolvedView ResolveView(string xaml) + public ResolvedView? ResolveView(string xaml) { try { @@ -86,7 +86,7 @@ IXamlAstNode IXamlAstVisitor.Visit(IXamlAstNode node) var nameSpace = string.Join(".", split.Take(split.Length - 1)); var className = split.Last(); - _resolvedClass = new ResolvedView(className, clrType, nameSpace, _xaml); + _resolvedClass = new ResolvedView(className, clrType, nameSpace, _xaml!); return node; } } diff --git a/src/tools/Avalonia.Generators/Compiler/RoslynTypeSystem.cs b/src/tools/Avalonia.Generators/Compiler/RoslynTypeSystem.cs index 59aaed2c11d..d2034d96ae7 100644 --- a/src/tools/Avalonia.Generators/Compiler/RoslynTypeSystem.cs +++ b/src/tools/Avalonia.Generators/Compiler/RoslynTypeSystem.cs @@ -28,18 +28,18 @@ public RoslynTypeSystem(CSharpCompilation compilation) public IEnumerable Assemblies => _assemblies; - public IXamlAssembly FindAssembly(string name) => + public IXamlAssembly? FindAssembly(string name) => Assemblies .FirstOrDefault(a => string.Equals(a.Name, name, StringComparison.OrdinalIgnoreCase)); [UnconditionalSuppressMessage("Trimming", "IL2092", Justification = TrimmingMessages.Roslyn)] - public IXamlType FindType(string name) => + public IXamlType? FindType(string name) => _assemblies .Select(assembly => assembly.FindType(name)) .FirstOrDefault(type => type != null); [UnconditionalSuppressMessage("Trimming", "IL2092", Justification = TrimmingMessages.Roslyn)] - public IXamlType FindType(string name, string assembly) => + public IXamlType? FindType(string name, string assembly) => _assemblies .Select(assemblyInstance => assemblyInstance.FindType(name)) .FirstOrDefault(type => type != null); @@ -62,7 +62,7 @@ other is RoslynAssembly roslynAssembly && .Select(data => new RoslynAttribute(data, this)) .ToList(); - public IXamlType FindType(string fullName) + public IXamlType? FindType(string fullName) { var type = _symbol.GetTypeByMetadataName(fullName); return type is null ? null : new RoslynType(type, this); @@ -84,14 +84,14 @@ public bool Equals(IXamlCustomAttribute other) => other is RoslynAttribute attribute && _data == attribute._data; - public IXamlType Type => new RoslynType(_data.AttributeClass, _assembly); + public IXamlType Type => new RoslynType(_data.AttributeClass!, _assembly); - public List Parameters => + public List Parameters => _data.ConstructorArguments .Select(argument => argument.Value) .ToList(); - public Dictionary Properties => + public Dictionary Properties => _data.NamedArguments.ToDictionary( pair => pair.Key, pair => pair.Value.Value); @@ -132,7 +132,7 @@ other is RoslynType roslynType && public bool IsNestedPrivate => _symbol.DeclaredAccessibility == Accessibility.Private; - public IXamlType DeclaringType => + public IXamlType? DeclaringType => _symbol.ContainingType is { } containingType ? new RoslynType(containingType, _assembly) : null; public IReadOnlyList Properties => @@ -142,18 +142,18 @@ other is RoslynType roslynType && .Select(property => new RoslynProperty(property, _assembly)) .ToList(); - public IReadOnlyList Events { get; } = new List(); + public IReadOnlyList Events => []; - public IReadOnlyList Fields { get; } = new List(); + public IReadOnlyList Fields => []; - public IReadOnlyList Methods { get; } = new List(); + public IReadOnlyList Methods => []; public IReadOnlyList Constructors => _symbol.Constructors .Select(method => new RoslynConstructor(method, _assembly)) .ToList(); - public IReadOnlyList CustomAttributes { get; } = Array.Empty(); + public IReadOnlyList CustomAttributes => []; public IReadOnlyList GenericArguments { get; private set; } = new List(); @@ -169,15 +169,15 @@ public IXamlType MakeGenericType(IReadOnlyList typeArguments) public bool IsArray => false; - public IXamlType ArrayElementType { get; } = null; + public IXamlType? ArrayElementType => null; - public IXamlType MakeArrayType(int dimensions) => null; + public IXamlType MakeArrayType(int dimensions) => throw new NotSupportedException(); - public IXamlType BaseType => _symbol.BaseType == null ? null : new RoslynType(_symbol.BaseType, _assembly); + public IXamlType? BaseType => _symbol.BaseType is { } baseType ? new RoslynType(baseType, _assembly) : null; - public bool IsValueType { get; } = false; + public bool IsValueType => false; - public bool IsEnum { get; } = false; + public bool IsEnum => false; public IReadOnlyList Interfaces => _symbol.AllInterfaces @@ -186,9 +186,9 @@ public IXamlType MakeGenericType(IReadOnlyList typeArguments) public bool IsInterface => _symbol.IsAbstract; - public IXamlType GetEnumUnderlyingType() => null; + public IXamlType GetEnumUnderlyingType() => throw new NotSupportedException(); - public IReadOnlyList GenericParameters { get; } = new List(); + public IReadOnlyList GenericParameters => []; public bool IsFunctionPointer => false; } @@ -217,6 +217,10 @@ other is RoslynConstructor roslynConstructor && .Select(parameter => new RoslynParameter(_assembly, parameter).ParameterType) .ToList(); + public string Name => _symbol.Name; + + public IXamlType DeclaringType => new RoslynType(_symbol.ContainingType, _assembly); + public IXamlParameterInfo GetParameterInfo(int index) => new RoslynParameter(_assembly, _symbol.Parameters[index]); } @@ -237,18 +241,20 @@ other is RoslynProperty roslynProperty && public string Name => _symbol.Name; + public IXamlType DeclaringType => new RoslynType(_symbol.ContainingType, _assembly); + public IXamlType PropertyType => _symbol.Type is INamedTypeSymbol namedTypeSymbol ? new RoslynType(namedTypeSymbol, _assembly) - : null; + : XamlPseudoType.Unknown; - public IXamlMethod Getter => _symbol.GetMethod == null ? null : new RoslynMethod(_symbol.GetMethod, _assembly); + public IXamlMethod? Getter => _symbol.GetMethod == null ? null : new RoslynMethod(_symbol.GetMethod, _assembly); - public IXamlMethod Setter => _symbol.SetMethod == null ? null : new RoslynMethod(_symbol.SetMethod, _assembly); + public IXamlMethod? Setter => _symbol.SetMethod == null ? null : new RoslynMethod(_symbol.SetMethod, _assembly); - public IReadOnlyList CustomAttributes { get; } = Array.Empty(); + public IReadOnlyList CustomAttributes => []; - public IReadOnlyList IndexerParameters { get; } = new List(); + public IReadOnlyList IndexerParameters => []; } internal class RoslynParameter : IXamlParameterInfo @@ -298,10 +304,11 @@ other is RoslynMethod roslynMethod && _symbol.Parameters.Select(parameter => new RoslynParameter(_assembly, parameter).ParameterType) .ToList(); - public IXamlType DeclaringType => new RoslynType((INamedTypeSymbol)_symbol.ReceiverType, _assembly); - - public IXamlMethod MakeGenericMethod(IReadOnlyList typeArguments) => null; + public IXamlType DeclaringType => new RoslynType(_symbol.ContainingType, _assembly); + + public IXamlMethod MakeGenericMethod(IReadOnlyList typeArguments) => throw new NotSupportedException(); + + public IReadOnlyList CustomAttributes => []; - public IReadOnlyList CustomAttributes { get; } = Array.Empty(); public IXamlParameterInfo GetParameterInfo(int index) => new RoslynParameter(_assembly, _symbol.Parameters[index]); } diff --git a/src/tools/Avalonia.Generators/GeneratorContextExtensions.cs b/src/tools/Avalonia.Generators/GeneratorContextExtensions.cs index 9690e5606ad..a388e74d270 100644 --- a/src/tools/Avalonia.Generators/GeneratorContextExtensions.cs +++ b/src/tools/Avalonia.Generators/GeneratorContextExtensions.cs @@ -29,7 +29,7 @@ public static void ReportNameGeneratorInvalidType(this GeneratorExecutionContext $"Avalonia x:Name generator was unable to generate names for type '{typeName}'. " + $"The type '{typeName}' does not exist in the assembly."); - private static void Report(this GeneratorExecutionContext context, string id, string title, string message = null, string description = null) => + private static void Report(this GeneratorExecutionContext context, string id, string title, string? message = null, string? description = null) => context.ReportDiagnostic( Diagnostic.Create( new DiagnosticDescriptor( diff --git a/src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameSourceGenerator.cs b/src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameSourceGenerator.cs index fad7283ded8..e93895db2e4 100644 --- a/src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameSourceGenerator.cs +++ b/src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameSourceGenerator.cs @@ -57,7 +57,7 @@ private static IEnumerable ResolveAdditionalFiles(GeneratorExecu && sourceItemGroup == "AvaloniaXaml"); } - private static INameGenerator CreateNameGenerator(GeneratorExecutionContext context) + private static INameGenerator? CreateNameGenerator(GeneratorExecutionContext context) { var options = new GeneratorOptions(context); if (!options.AvaloniaNameGeneratorIsEnabled) diff --git a/tests/Avalonia.Generators.Tests/InitializeComponent/InitializeComponentTests.cs b/tests/Avalonia.Generators.Tests/InitializeComponent/InitializeComponentTests.cs index 1d0070f2f1e..15fb282ed97 100644 --- a/tests/Avalonia.Generators.Tests/InitializeComponent/InitializeComponentTests.cs +++ b/tests/Avalonia.Generators.Tests/InitializeComponent/InitializeComponentTests.cs @@ -44,11 +44,12 @@ public async Task Should_Generate_FindControl_Refs_From_Avalonia_Markup_File( var xaml = await View.Load(markup); var classInfo = classResolver.ResolveView(xaml); + Assert.NotNull(classInfo); var nameResolver = new XamlXNameResolver(); var names = nameResolver.ResolveNames(classInfo.Xaml); var generator = new InitializeComponentCodeGenerator(types, devToolsMode); - var generatorVersion = typeof(InitializeComponentCodeGenerator).Assembly.GetName().Version.ToString(); + var generatorVersion = typeof(InitializeComponentCodeGenerator).Assembly.GetName().Version?.ToString(); var code = generator .GenerateCode("SampleView", "Sample.App", classInfo.XamlType, names) diff --git a/tests/Avalonia.Generators.Tests/OnlyProperties/OnlyPropertiesTests.cs b/tests/Avalonia.Generators.Tests/OnlyProperties/OnlyPropertiesTests.cs index ceb15af629d..3f498c2be20 100644 --- a/tests/Avalonia.Generators.Tests/OnlyProperties/OnlyPropertiesTests.cs +++ b/tests/Avalonia.Generators.Tests/OnlyProperties/OnlyPropertiesTests.cs @@ -37,11 +37,12 @@ public async Task Should_Generate_FindControl_Refs_From_Avalonia_Markup_File(str var xaml = await View.Load(markup); var classInfo = classResolver.ResolveView(xaml); + Assert.NotNull(classInfo); var nameResolver = new XamlXNameResolver(); var names = nameResolver.ResolveNames(classInfo.Xaml); var generator = new OnlyPropertiesCodeGenerator(); - var generatorVersion = typeof(OnlyPropertiesCodeGenerator).Assembly.GetName().Version.ToString(); + var generatorVersion = typeof(OnlyPropertiesCodeGenerator).Assembly.GetName().Version?.ToString(); var code = generator .GenerateCode("SampleView", "Sample.App", classInfo.XamlType, names) diff --git a/tests/Avalonia.Generators.Tests/XamlXClassResolverTests.cs b/tests/Avalonia.Generators.Tests/XamlXClassResolverTests.cs index 79a1109d570..8d6db6ce478 100644 --- a/tests/Avalonia.Generators.Tests/XamlXClassResolverTests.cs +++ b/tests/Avalonia.Generators.Tests/XamlXClassResolverTests.cs @@ -34,6 +34,7 @@ public async Task Should_Resolve_Base_Class_From_Xaml_File(string nameSpace, str MiniCompiler.CreateDefault(types, MiniCompiler.AvaloniaXmlnsDefinitionAttribute)); var resolvedClass = resolver.ResolveView(xaml); + Assert.NotNull(resolvedClass); Assert.Equal(className, resolvedClass.ClassName); Assert.Equal(nameSpace, resolvedClass.Namespace); } diff --git a/tests/Avalonia.Generators.Tests/XamlXNameResolverTests.cs b/tests/Avalonia.Generators.Tests/XamlXNameResolverTests.cs index 0399294d173..538e6b92420 100644 --- a/tests/Avalonia.Generators.Tests/XamlXNameResolverTests.cs +++ b/tests/Avalonia.Generators.Tests/XamlXNameResolverTests.cs @@ -135,6 +135,7 @@ private static IReadOnlyList ResolveNames(string xaml) MiniCompiler.AvaloniaXmlnsDefinitionAttribute)); var classInfo = classResolver.ResolveView(xaml); + Assert.NotNull(classInfo); var nameResolver = new XamlXNameResolver(); return nameResolver.ResolveNames(classInfo.Xaml); } From 07ab0e223fa78c7d23f3e35261b3841fbe852b9f Mon Sep 17 00:00:00 2001 From: Julien Lebosquain Date: Thu, 23 May 2024 00:13:51 +0200 Subject: [PATCH 2/5] Update .NET SDK --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 8e84e96f229..b423edba49d 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.101", + "version": "8.0.204", "rollForward": "latestFeature" }, "msbuild-sdks": { From 2f7ec0bdbe1990e5ed075eb6c2b5080da049cf4b Mon Sep 17 00:00:00 2001 From: Julien Lebosquain Date: Sat, 13 Jul 2024 11:52:40 +0200 Subject: [PATCH 3/5] Update XamlX to latest master --- src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github b/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github index f5aa2e37cb8..14fed0cb066 160000 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github @@ -1 +1 @@ -Subproject commit f5aa2e37cb8d75857aed649742765c464d5b8fd9 +Subproject commit 14fed0cb0666a9b3f71cb635cf61eb6010d4ff64 From 571b263b9b4cfa85829507f549bfc4a7cee0155d Mon Sep 17 00:00:00 2001 From: Julien Lebosquain Date: Thu, 30 May 2024 18:07:11 +0200 Subject: [PATCH 4/5] Use ILRepack tool instead of submodule --- .gitmodules | 3 -- nukebuild/Build.cs | 6 ++-- nukebuild/BuildTasksPatcher.cs | 34 ++++++++----------- nukebuild/_build.csproj | 4 +-- nukebuild/il-repack | 1 - .../Avalonia.Build.Tasks.csproj | 12 ++++--- 6 files changed, 27 insertions(+), 33 deletions(-) delete mode 160000 nukebuild/il-repack diff --git a/.gitmodules b/.gitmodules index 032bc879cc5..2d11fdfa9e1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,3 @@ [submodule "src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github"] path = src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github url = https://github.com/kekekeks/XamlX.git -[submodule "nukebuild/il-repack"] - path = nukebuild/il-repack - url = https://github.com/Gillibald/il-repack diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs index d1d6e043c1e..c71a0c1e39e 100644 --- a/nukebuild/Build.cs +++ b/nukebuild/Build.cs @@ -40,7 +40,8 @@ partial class Build : NukeBuild [PackageExecutable("Microsoft.DotNet.GenAPI.Tool", "Microsoft.DotNet.GenAPI.Tool.dll", Framework = "net8.0")] Tool ApiGenTool; - + [PackageExecutable("dotnet-ilrepack", "ILRepackTool.dll", Framework = "net8.0")] + Tool IlRepackTool; protected override void OnBuildInitialized() { @@ -307,7 +308,8 @@ void DoMemoryTest() .Executes(() => { BuildTasksPatcher.PatchBuildTasksInPackage(Parameters.NugetIntermediateRoot / "Avalonia.Build.Tasks." + - Parameters.Version + ".nupkg"); + Parameters.Version + ".nupkg", + IlRepackTool); var config = Numerge.MergeConfiguration.LoadFile(RootDirectory / "nukebuild" / "numerge.config"); EnsureCleanDirectory(Parameters.NugetRoot); if(!Numerge.NugetPackageMerger.Merge(Parameters.NugetIntermediateRoot, Parameters.NugetRoot, config, diff --git a/nukebuild/BuildTasksPatcher.cs b/nukebuild/BuildTasksPatcher.cs index f2dd217657f..6bb71f43209 100644 --- a/nukebuild/BuildTasksPatcher.cs +++ b/nukebuild/BuildTasksPatcher.cs @@ -2,9 +2,9 @@ using System.IO; using System.IO.Compression; using System.Linq; -using ILRepacking; using Mono.Cecil; using Mono.Cecil.Cil; +using Nuke.Common.Tooling; public class BuildTasksPatcher { @@ -56,7 +56,7 @@ private static string GetSourceLinkInfo(string path) return null; } - public static void PatchBuildTasksInPackage(string packagePath) + public static void PatchBuildTasksInPackage(string packagePath, Tool ilRepackTool) { using (var archive = new ZipArchive(File.Open(packagePath, FileMode.Open, FileAccess.ReadWrite), ZipArchiveMode.Update)) @@ -70,7 +70,7 @@ public static void PatchBuildTasksInPackage(string packagePath) Directory.CreateDirectory(tempDir); var temp = Path.Combine(tempDir, entry.Name); var output = temp + ".output"; - File.Copy(typeof(Microsoft.Build.Framework.ITask).Assembly.GetModules()[0].FullyQualifiedName, + File.Copy(GetAssemblyPath(typeof(Microsoft.Build.Framework.ITask)), Path.Combine(tempDir, "Microsoft.Build.Framework.dll")); var patched = new MemoryStream(); try @@ -78,22 +78,15 @@ public static void PatchBuildTasksInPackage(string packagePath) entry.ExtractToFile(temp, true); // Get Original SourceLinkInfo Content var sourceLinkInfoContent = GetSourceLinkInfo(temp); - var repack = new ILRepacking.ILRepack(new RepackOptions() - { - Internalize = true, - InputAssemblies = new[] - { - temp, - typeof(Mono.Cecil.AssemblyDefinition).Assembly.GetModules()[0].FullyQualifiedName, - typeof(Mono.Cecil.Rocks.MethodBodyRocks).Assembly.GetModules()[0].FullyQualifiedName, - typeof(Mono.Cecil.Pdb.PdbReaderProvider).Assembly.GetModules()[0].FullyQualifiedName, - typeof(Mono.Cecil.Mdb.MdbReaderProvider).Assembly.GetModules()[0].FullyQualifiedName, - }, - SearchDirectories = Array.Empty(), - DebugInfo = true, // Allowed read debug info - OutputFile = output - }); - repack.Repack(); + + var cecilAsm = GetAssemblyPath(typeof(Mono.Cecil.AssemblyDefinition)); + var cecilRocksAsm = GetAssemblyPath(typeof(Mono.Cecil.Rocks.MethodBodyRocks)); + var cecilPdbAsm = GetAssemblyPath(typeof(Mono.Cecil.Pdb.PdbReaderProvider)); + var cecilMdbAsm = GetAssemblyPath(typeof(Mono.Cecil.Mdb.MdbReaderProvider)); + + ilRepackTool.Invoke( + $"/internalize /out:\"{output}\" \"{temp}\" \"{cecilAsm}\" \"{cecilRocksAsm}\" \"{cecilPdbAsm}\" \"{cecilMdbAsm}\"", + tempDir); // 'hurr-durr assembly with the same name is already loaded' prevention using (var asm = AssemblyDefinition.ReadAssembly(output, @@ -161,4 +154,7 @@ public static void PatchBuildTasksInPackage(string packagePath) } } } + + private static string GetAssemblyPath(Type typeInAssembly) + => typeInAssembly.Assembly.GetModules()[0].FullyQualifiedName; } diff --git a/nukebuild/_build.csproj b/nukebuild/_build.csproj index 7c89b896c7a..a2c4f890da9 100644 --- a/nukebuild/_build.csproj +++ b/nukebuild/_build.csproj @@ -20,7 +20,6 @@ - all @@ -29,6 +28,7 @@ + @@ -38,9 +38,7 @@ - - diff --git a/nukebuild/il-repack b/nukebuild/il-repack deleted file mode 160000 index 892f079ea8c..00000000000 --- a/nukebuild/il-repack +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 892f079ea8cb0c178f0a68f53a7a7eac13acdda9 diff --git a/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj b/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj index 61069630a5e..04b89ed4d9a 100644 --- a/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj +++ b/src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj @@ -1,6 +1,7 @@  - netstandard2.0 + netstandard2.0 + enable false tools $(DefineConstants);BUILDTASK;XAMLX_CECIL_INTERNAL;XAMLX_INTERNAL @@ -114,13 +115,14 @@ Markup/%(RecursiveDir)%(FileName)%(Extension) - - + + - - + + + From 0d644806474b7950a72c7b8bd5ad51dbc4075811 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Sun, 28 Jul 2024 20:57:49 -0700 Subject: [PATCH 5/5] Fix build --- .../Transformers/AvaloniaXamlIlSetterTransformer.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs index 7f60ed77ff2..aecc4b47de8 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs @@ -87,9 +87,8 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod && XamlTransformHelpers.TryGetCorrectlyTypedValue(context, textValue, propType, out _)) { - var setterValueProperty = new SetterValueProperty( - (IXamlLineInfo)valueProperty?.Property ?? textValue, + (IXamlLineInfo?)valueProperty?.Property ?? textValue, on.Type.GetClrType(), propType, avaloniaTypes); if (valueProperty is not null) {