From 2c124e5e047dfcd59e8828db27a071b0cc65474f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 30 Oct 2022 13:10:38 +0100 Subject: [PATCH 1/6] Rename a generator extension --- ...vableValidatorValidateAllPropertiesGenerator.Execute.cs | 4 ++-- .../Extensions/INamedTypeSymbolExtensions.cs | 7 +++---- .../Messaging/IMessengerRegisterAllGenerator.Execute.cs | 2 +- .../Models/HierarchyInfo.cs | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs index 4cbee7c8..e046c4f3 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs @@ -81,7 +81,7 @@ public static ValidationInfo GetInfo(INamedTypeSymbol typeSymbol) } return new( - typeSymbol.GetFullMetadataNameForFileName(), + typeSymbol.GetFullyQualifiedMetadataName(), typeSymbol.GetFullyQualifiedName(), propertyNames.ToImmutable()); } @@ -102,7 +102,7 @@ public static RecipientInfo GetInfo(INamedTypeSymbol typeSymbol, ImmutableArray< } return new( - typeSymbol.GetFullMetadataNameForFileName(), + typeSymbol.GetFullyQualifiedMetadataName(), typeSymbol.GetFullyQualifiedName(), names.ToImmutable()); } diff --git a/CommunityToolkit.Mvvm.SourceGenerators/Extensions/INamedTypeSymbolExtensions.cs b/CommunityToolkit.Mvvm.SourceGenerators/Extensions/INamedTypeSymbolExtensions.cs index 8afde729..88af0bda 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/Extensions/INamedTypeSymbolExtensions.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/Extensions/INamedTypeSymbolExtensions.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Text; using CommunityToolkit.Mvvm.SourceGenerators.Helpers; using Microsoft.CodeAnalysis; @@ -16,11 +15,11 @@ namespace CommunityToolkit.Mvvm.SourceGenerators.Extensions; internal static class INamedTypeSymbolExtensions { /// - /// Gets a valid filename for a given instance. + /// Gets a fully qualified metadata name for a given instance. /// /// The input instance. - /// The full metadata name for that is also a valid filename. - public static string GetFullMetadataNameForFileName(this INamedTypeSymbol symbol) + /// The fully qualified metadata name for . + public static string GetFullyQualifiedMetadataName(this INamedTypeSymbol symbol) { using ImmutableArrayBuilder builder = ImmutableArrayBuilder.Rent(); diff --git a/CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.Execute.cs b/CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.Execute.cs index a2703b44..9067f859 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.Execute.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.Execute.cs @@ -59,7 +59,7 @@ public static RecipientInfo GetInfo(INamedTypeSymbol typeSymbol, ImmutableArray< } return new( - typeSymbol.GetFullMetadataNameForFileName(), + typeSymbol.GetFullyQualifiedMetadataName(), typeSymbol.GetFullyQualifiedName(), names.ToImmutable()); } diff --git a/CommunityToolkit.Mvvm.SourceGenerators/Models/HierarchyInfo.cs b/CommunityToolkit.Mvvm.SourceGenerators/Models/HierarchyInfo.cs index 8dd010a5..365c95fb 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/Models/HierarchyInfo.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/Models/HierarchyInfo.cs @@ -41,7 +41,7 @@ public static HierarchyInfo From(INamedTypeSymbol typeSymbol) } return new( - typeSymbol.GetFullMetadataNameForFileName(), + typeSymbol.GetFullyQualifiedMetadataName(), typeSymbol.MetadataName, typeSymbol.ContainingNamespace.ToDisplayString(new(typeQualificationStyle: NameAndContainingTypesAndNamespaces)), hierarchy.ToImmutable()); From 2a8d1dbd0699f1a591dfb6e9961ef00603178f99 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 30 Oct 2022 13:17:01 +0100 Subject: [PATCH 2/6] Update some type extensions --- .../Extensions/INamedTypeSymbolExtensions.cs | 51 ------------ .../Extensions/ITypeSymbolExtensions.cs | 79 +++++++++++++++++++ 2 files changed, 79 insertions(+), 51 deletions(-) diff --git a/CommunityToolkit.Mvvm.SourceGenerators/Extensions/INamedTypeSymbolExtensions.cs b/CommunityToolkit.Mvvm.SourceGenerators/Extensions/INamedTypeSymbolExtensions.cs index 88af0bda..8b847bcf 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/Extensions/INamedTypeSymbolExtensions.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/Extensions/INamedTypeSymbolExtensions.cs @@ -2,9 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Generic; -using CommunityToolkit.Mvvm.SourceGenerators.Helpers; using Microsoft.CodeAnalysis; namespace CommunityToolkit.Mvvm.SourceGenerators.Extensions; @@ -14,55 +12,6 @@ namespace CommunityToolkit.Mvvm.SourceGenerators.Extensions; /// internal static class INamedTypeSymbolExtensions { - /// - /// Gets a fully qualified metadata name for a given instance. - /// - /// The input instance. - /// The fully qualified metadata name for . - public static string GetFullyQualifiedMetadataName(this INamedTypeSymbol symbol) - { - using ImmutableArrayBuilder builder = ImmutableArrayBuilder.Rent(); - - static void BuildFrom(ISymbol? symbol, in ImmutableArrayBuilder builder) - { - switch (symbol) - { - // Namespaces that are nested also append a leading '.' - case INamespaceSymbol { ContainingNamespace.IsGlobalNamespace: false }: - BuildFrom(symbol.ContainingNamespace, in builder); - builder.Add('.'); - builder.AddRange(symbol.MetadataName.AsSpan()); - break; - // Other namespaces (ie. the one right before global) skip the leading '.' - case INamespaceSymbol { IsGlobalNamespace: false }: - builder.AddRange(symbol.MetadataName.AsSpan()); - break; - // Types with no namespace just have their metadata name directly written - case ITypeSymbol { ContainingSymbol: INamespaceSymbol { IsGlobalNamespace: true } }: - builder.AddRange(symbol.MetadataName.AsSpan()); - break; - // Types with a containing non-global namespace also append a leading '.' - case ITypeSymbol { ContainingSymbol: INamespaceSymbol namespaceSymbol }: - BuildFrom(namespaceSymbol, in builder); - builder.Add('.'); - builder.AddRange(symbol.MetadataName.AsSpan()); - break; - // Nested types append a leading '+' - case ITypeSymbol { ContainingSymbol: ITypeSymbol typeSymbol }: - BuildFrom(typeSymbol, in builder); - builder.Add('+'); - builder.AddRange(symbol.MetadataName.AsSpan()); - break; - default: - break; - } - } - - BuildFrom(symbol, in builder); - - return builder.ToString(); - } - /// /// Gets all member symbols from a given instance, including inherited ones. /// diff --git a/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ITypeSymbolExtensions.cs b/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ITypeSymbolExtensions.cs index 50e8c8ea..e4ad86b2 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ITypeSymbolExtensions.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ITypeSymbolExtensions.cs @@ -4,6 +4,7 @@ using System; using System.Linq; +using CommunityToolkit.Mvvm.SourceGenerators.Helpers; using Microsoft.CodeAnalysis; namespace CommunityToolkit.Mvvm.SourceGenerators.Extensions; @@ -128,4 +129,82 @@ public static bool InheritsAttributeWithFullyQualifiedName(this ITypeSymbol type return false; } + + /// + /// Checks whether or not a given type symbol has a specified fully qualified metadata name. + /// + /// The input instance to check. + /// The full name to check. + /// Whether has a full name equals to . + public static bool HasFullyQualifiedMetadataName(this ITypeSymbol symbol, string name) + { + using ImmutableArrayBuilder builder = ImmutableArrayBuilder.Rent(); + + symbol.AppendFullyQualifiedMetadataName(in builder); + + return builder.WrittenSpan.SequenceEqual(name.AsSpan()); + } + + /// + /// Gets the fully qualified metadata name for a given instance. + /// + /// The input instance. + /// The fully qualified metadata name for . + public static string GetFullyQualifiedMetadataName(this ITypeSymbol symbol) + { + using ImmutableArrayBuilder builder = ImmutableArrayBuilder.Rent(); + + symbol.AppendFullyQualifiedMetadataName(in builder); + + return builder.ToString(); + } + + /// + /// Appends the fully qualified metadata name for a given symbol to a target builder. + /// + /// The input instance. + /// The target instance. + public static void AppendFullyQualifiedMetadataName(this ITypeSymbol symbol, in ImmutableArrayBuilder builder) + { + static void BuildFrom(ISymbol? symbol, in ImmutableArrayBuilder builder) + { + switch (symbol) + { + // Namespaces that are nested also append a leading '.' + case INamespaceSymbol { ContainingNamespace.IsGlobalNamespace: false }: + BuildFrom(symbol.ContainingNamespace, in builder); + builder.Add('.'); + builder.AddRange(symbol.MetadataName.AsSpan()); + break; + + // Other namespaces (ie. the one right before global) skip the leading '.' + case INamespaceSymbol { IsGlobalNamespace: false }: + builder.AddRange(symbol.MetadataName.AsSpan()); + break; + + // Types with no namespace just have their metadata name directly written + case ITypeSymbol { ContainingSymbol: INamespaceSymbol { IsGlobalNamespace: true } }: + builder.AddRange(symbol.MetadataName.AsSpan()); + break; + + // Types with a containing non-global namespace also append a leading '.' + case ITypeSymbol { ContainingSymbol: INamespaceSymbol namespaceSymbol }: + BuildFrom(namespaceSymbol, in builder); + builder.Add('.'); + builder.AddRange(symbol.MetadataName.AsSpan()); + break; + + // Nested types append a leading '+' + case ITypeSymbol { ContainingSymbol: ITypeSymbol typeSymbol }: + BuildFrom(typeSymbol, in builder); + builder.Add('+'); + builder.AddRange(symbol.MetadataName.AsSpan()); + break; + default: + break; + } + } + + BuildFrom(symbol, in builder); + } } From 777fd6ce902fccb11cc1f87e10b299ef5d07994e Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 30 Oct 2022 13:34:29 +0100 Subject: [PATCH 3/6] Remove more allocations --- .../INotifyPropertyChangedGenerator.cs | 6 +- .../ObservableObjectGenerator.cs | 8 +-- .../ObservablePropertyGenerator.Execute.cs | 62 +++++++++---------- .../ObservablePropertyGenerator.cs | 4 +- .../ObservableRecipientGenerator.cs | 12 ++-- ...rValidateAllPropertiesGenerator.Execute.cs | 10 +-- .../Extensions/ISymbolExtensions.cs | 12 ++-- .../Extensions/ITypeSymbolExtensions.cs | 20 +++--- .../Input/RelayCommandGenerator.Execute.cs | 24 ++++--- .../IMessengerRegisterAllGenerator.Execute.cs | 3 +- .../SyntaxValueProviderExtensions.cs | 4 +- 11 files changed, 80 insertions(+), 85 deletions(-) diff --git a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/INotifyPropertyChangedGenerator.cs b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/INotifyPropertyChangedGenerator.cs index 585c76a3..9a8bccbd 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/INotifyPropertyChangedGenerator.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/INotifyPropertyChangedGenerator.cs @@ -36,7 +36,7 @@ public INotifyPropertyChangedGenerator() INotifyPropertyChangedInfo? info = null; // Check if the type already implements INotifyPropertyChanged - if (typeSymbol.AllInterfaces.Any(i => i.HasFullyQualifiedName("global::System.ComponentModel.INotifyPropertyChanged"))) + if (typeSymbol.AllInterfaces.Any(i => i.HasFullyQualifiedMetadataName("System.ComponentModel.INotifyPropertyChanged"))) { diagnostics = ImmutableArray.Create(DiagnosticInfo.Create(DuplicateINotifyPropertyChangedInterfaceForINotifyPropertyChangedAttributeError, typeSymbol, typeSymbol)); @@ -44,8 +44,8 @@ public INotifyPropertyChangedGenerator() } // Check if the type uses [INotifyPropertyChanged] or [ObservableObject] already (in the type hierarchy too) - if (typeSymbol.HasOrInheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableObjectAttribute") || - typeSymbol.InheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.INotifyPropertyChangedAttribute")) + if (typeSymbol.HasOrInheritsAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableObjectAttribute") || + typeSymbol.InheritsAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.INotifyPropertyChangedAttribute")) { diagnostics = ImmutableArray.Create(DiagnosticInfo.Create(InvalidAttributeCombinationForINotifyPropertyChangedAttributeError, typeSymbol, typeSymbol)); diff --git a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableObjectGenerator.cs b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableObjectGenerator.cs index 74816446..a2f4bff2 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableObjectGenerator.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableObjectGenerator.cs @@ -32,7 +32,7 @@ private protected override int ValidateTargetTypeAndGetInfo(INamedTypeSymbol typ diagnostics = ImmutableArray.Empty; // Check if the type already implements INotifyPropertyChanged... - if (typeSymbol.AllInterfaces.Any(i => i.HasFullyQualifiedName("global::System.ComponentModel.INotifyPropertyChanged"))) + if (typeSymbol.AllInterfaces.Any(i => i.HasFullyQualifiedMetadataName("System.ComponentModel.INotifyPropertyChanged"))) { diagnostics = ImmutableArray.Create(DiagnosticInfo.Create(DuplicateINotifyPropertyChangedInterfaceForObservableObjectAttributeError, typeSymbol, typeSymbol)); @@ -40,7 +40,7 @@ private protected override int ValidateTargetTypeAndGetInfo(INamedTypeSymbol typ } // ...or INotifyPropertyChanging - if (typeSymbol.AllInterfaces.Any(i => i.HasFullyQualifiedName("global::System.ComponentModel.INotifyPropertyChanging"))) + if (typeSymbol.AllInterfaces.Any(i => i.HasFullyQualifiedMetadataName("System.ComponentModel.INotifyPropertyChanging"))) { diagnostics = ImmutableArray.Create(DiagnosticInfo.Create(DuplicateINotifyPropertyChangingInterfaceForObservableObjectAttributeError, typeSymbol, typeSymbol)); @@ -48,8 +48,8 @@ private protected override int ValidateTargetTypeAndGetInfo(INamedTypeSymbol typ } // Check if the type uses [INotifyPropertyChanged] or [ObservableObject] already (in the type hierarchy too) - if (typeSymbol.InheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableObjectAttribute") || - typeSymbol.HasOrInheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.INotifyPropertyChangedAttribute")) + if (typeSymbol.InheritsAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableObjectAttribute") || + typeSymbol.HasOrInheritsAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.INotifyPropertyChangedAttribute")) { diagnostics = ImmutableArray.Create(DiagnosticInfo.Create(InvalidAttributeCombinationForObservableObjectAttributeError, typeSymbol, typeSymbol)); diff --git a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.Execute.cs b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.Execute.cs index 6209609d..d8f44d66 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.Execute.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.Execute.cs @@ -162,7 +162,7 @@ public static bool TryGetInfo( } // Track the current attribute for forwarding if it is a validation attribute - if (attributeData.AttributeClass?.InheritsFromFullyQualifiedName("global::System.ComponentModel.DataAnnotations.ValidationAttribute") == true) + if (attributeData.AttributeClass?.InheritsFromFullyQualifiedMetadataName("System.ComponentModel.DataAnnotations.ValidationAttribute") == true) { hasAnyValidationAttributes = true; @@ -175,11 +175,11 @@ public static bool TryGetInfo( // - Scaffold column attributes (System.ComponentModel.DataAnnotations.ScaffoldColumnAttribute) // - Editable attributes (System.ComponentModel.DataAnnotations.EditableAttribute) // - Key attributes (System.ComponentModel.DataAnnotations.KeyAttribute) - if (attributeData.AttributeClass?.HasOrInheritsFromFullyQualifiedName("global::System.ComponentModel.DataAnnotations.UIHintAttribute") == true || - attributeData.AttributeClass?.HasOrInheritsFromFullyQualifiedName("global::System.ComponentModel.DataAnnotations.ScaffoldColumnAttribute") == true || - attributeData.AttributeClass?.HasFullyQualifiedName("global::System.ComponentModel.DataAnnotations.DisplayAttribute") == true || - attributeData.AttributeClass?.HasFullyQualifiedName("global::System.ComponentModel.DataAnnotations.EditableAttribute") == true || - attributeData.AttributeClass?.HasFullyQualifiedName("global::System.ComponentModel.DataAnnotations.KeyAttribute") == true) + if (attributeData.AttributeClass?.HasOrInheritsFromFullyQualifiedMetadataName("System.ComponentModel.DataAnnotations.UIHintAttribute") == true || + attributeData.AttributeClass?.HasOrInheritsFromFullyQualifiedMetadataName("System.ComponentModel.DataAnnotations.ScaffoldColumnAttribute") == true || + attributeData.AttributeClass?.HasFullyQualifiedMetadataName("System.ComponentModel.DataAnnotations.DisplayAttribute") == true || + attributeData.AttributeClass?.HasFullyQualifiedMetadataName("System.ComponentModel.DataAnnotations.EditableAttribute") == true || + attributeData.AttributeClass?.HasFullyQualifiedMetadataName("System.ComponentModel.DataAnnotations.KeyAttribute") == true) { forwardedAttributes.Add(AttributeInfo.From(attributeData)); } @@ -226,7 +226,7 @@ public static bool TryGetInfo( // Log the diagnostic for missing ObservableValidator, if needed if (hasAnyValidationAttributes && - !fieldSymbol.ContainingType.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableValidator")) + !fieldSymbol.ContainingType.InheritsFromFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableValidator")) { builder.Add( MissingObservableValidatorInheritanceForValidationAttributeError, @@ -275,9 +275,9 @@ private static bool IsTargetTypeValid(IFieldSymbol fieldSymbol, out bool shouldI // - It inherits from ObservableObject (in which case it also implements INotifyPropertyChanging). // - It has the [ObservableObject] attribute (on itself or any of its base types). // - It has the [INotifyPropertyChanged] attribute (on itself or any of its base types). - bool isObservableObject = fieldSymbol.ContainingType.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableObject"); - bool hasObservableObjectAttribute = fieldSymbol.ContainingType.HasOrInheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableObjectAttribute"); - bool hasINotifyPropertyChangedAttribute = fieldSymbol.ContainingType.HasOrInheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.INotifyPropertyChangedAttribute"); + bool isObservableObject = fieldSymbol.ContainingType.InheritsFromFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableObject"); + bool hasObservableObjectAttribute = fieldSymbol.ContainingType.HasOrInheritsAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableObjectAttribute"); + bool hasINotifyPropertyChangedAttribute = fieldSymbol.ContainingType.HasOrInheritsAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.INotifyPropertyChangedAttribute"); shouldInvokeOnPropertyChanging = isObservableObject || hasObservableObjectAttribute; @@ -300,8 +300,8 @@ private static bool IsGeneratedPropertyInvalid(string propertyName, ITypeSymbol { return propertyType.SpecialType == SpecialType.System_Object || - propertyType.HasOrInheritsFromFullyQualifiedName("global::System.ComponentModel.PropertyChangedEventArgs") || - propertyType.HasOrInheritsFromFullyQualifiedName("global::System.ComponentModel.PropertyChangingEventArgs"); + propertyType.HasOrInheritsFromFullyQualifiedMetadataName("System.ComponentModel.PropertyChangedEventArgs") || + propertyType.HasOrInheritsFromFullyQualifiedMetadataName("System.ComponentModel.PropertyChangingEventArgs"); } return false; @@ -334,7 +334,7 @@ bool IsPropertyNameValidWithGeneratedMembers(string propertyName) { if (member is IFieldSymbol otherFieldSymbol && !SymbolEqualityComparer.Default.Equals(fieldSymbol, otherFieldSymbol) && - otherFieldSymbol.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute") && + otherFieldSymbol.HasAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute") && propertyName == GetGeneratedPropertyName(otherFieldSymbol)) { return true; @@ -344,7 +344,7 @@ bool IsPropertyNameValidWithGeneratedMembers(string propertyName) return false; } - if (attributeData.AttributeClass?.HasFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyPropertyChangedForAttribute") == true) + if (attributeData.AttributeClass?.HasFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.NotifyPropertyChangedForAttribute") == true) { foreach (string? dependentPropertyName in attributeData.GetConstructorArguments()) { @@ -397,8 +397,8 @@ bool IsCommandNameValid(string commandName, out bool shouldLookForGeneratedMembe // target is definitely not valid, and the additional checks below can just be skipped. The property // is valid if it's of type IRelayCommand, or it has IRelayCommand in the set of all interfaces. if (propertySymbol.Type is INamedTypeSymbol typeSymbol && - (typeSymbol.HasFullyQualifiedName("global::CommunityToolkit.Mvvm.Input.IRelayCommand") || - typeSymbol.HasInterfaceWithFullyQualifiedName("global::CommunityToolkit.Mvvm.Input.IRelayCommand"))) + (typeSymbol.HasFullyQualifiedMetadataName("CommunityToolkit.Mvvm.Input.IRelayCommand") || + typeSymbol.HasInterfaceWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.Input.IRelayCommand"))) { shouldLookForGeneratedMembersToo = true; @@ -423,7 +423,7 @@ bool IsCommandNameValidWithGeneratedMembers(string commandName) foreach (ISymbol member in fieldSymbol.ContainingType.GetAllMembers()) { if (member is IMethodSymbol methodSymbol && - methodSymbol.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.Input.RelayCommandAttribute") && + methodSymbol.HasAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.Input.RelayCommandAttribute") && commandName == RelayCommandGenerator.Execute.GetGeneratedFieldAndPropertyNames(methodSymbol).PropertyName) { return true; @@ -433,7 +433,7 @@ bool IsCommandNameValidWithGeneratedMembers(string commandName) return false; } - if (attributeData.AttributeClass?.HasFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyCanExecuteChangedForAttribute") == true) + if (attributeData.AttributeClass?.HasFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.NotifyCanExecuteChangedForAttribute") == true) { foreach (string? commandName in attributeData.GetConstructorArguments()) { @@ -470,11 +470,11 @@ bool IsCommandNameValidWithGeneratedMembers(string commandName) /// Whether or not the generated property for is in a type annotated with [NotifyPropertyChangedRecipients]. private static bool TryGetIsNotifyingRecipients(IFieldSymbol fieldSymbol, out bool isBroadcastTargetValid) { - if (fieldSymbol.ContainingType?.HasOrInheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyPropertyChangedRecipientsAttribute") == true) + if (fieldSymbol.ContainingType?.HasOrInheritsAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.NotifyPropertyChangedRecipientsAttribute") == true) { // If the containing type is valid, track it - if (fieldSymbol.ContainingType.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableRecipient") || - fieldSymbol.ContainingType.HasOrInheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableRecipientAttribute")) + if (fieldSymbol.ContainingType.InheritsFromFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableRecipient") || + fieldSymbol.ContainingType.HasOrInheritsAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableRecipientAttribute")) { isBroadcastTargetValid = true; @@ -509,7 +509,7 @@ private static bool TryGetIsNotifyingRecipients( bool hasOrInheritsClassLevelNotifyPropertyChangedRecipients, out bool isBroadcastTargetValid) { - if (attributeData.AttributeClass?.HasFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyPropertyChangedRecipientsAttribute") == true) + if (attributeData.AttributeClass?.HasFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.NotifyPropertyChangedRecipientsAttribute") == true) { // Emit a diagnostic if the attribute is unnecessary if (hasOrInheritsClassLevelNotifyPropertyChangedRecipients) @@ -522,8 +522,8 @@ private static bool TryGetIsNotifyingRecipients( } // If the containing type is valid, track it - if (fieldSymbol.ContainingType.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableRecipient") || - fieldSymbol.ContainingType.HasOrInheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableRecipientAttribute")) + if (fieldSymbol.ContainingType.InheritsFromFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableRecipient") || + fieldSymbol.ContainingType.HasOrInheritsAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableRecipientAttribute")) { isBroadcastTargetValid = true; @@ -555,8 +555,8 @@ private static bool TryGetIsNotifyingRecipients( public static Diagnostic? GetIsNotifyingRecipientsDiagnosticForType(INamedTypeSymbol typeSymbol) { // If the containing type is valid, track it - if (!typeSymbol.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableRecipient") && - !typeSymbol.HasOrInheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableRecipientAttribute")) + if (!typeSymbol.InheritsFromFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableRecipient") && + !typeSymbol.HasOrInheritsAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableRecipientAttribute")) { return Diagnostic.Create( InvalidTypeForNotifyPropertyChangedRecipientsError, @@ -575,10 +575,10 @@ private static bool TryGetIsNotifyingRecipients( /// Whether or not the generated property for used [NotifyDataErrorInfo]. private static bool TryGetNotifyDataErrorInfo(IFieldSymbol fieldSymbol, out bool isValidationTargetValid) { - if (fieldSymbol.ContainingType?.HasOrInheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyDataErrorInfoAttribute") == true) + if (fieldSymbol.ContainingType?.HasOrInheritsAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.NotifyDataErrorInfoAttribute") == true) { // If the containing type is valid, track it - if (fieldSymbol.ContainingType.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableValidator")) + if (fieldSymbol.ContainingType.InheritsFromFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableValidator")) { isValidationTargetValid = true; @@ -612,7 +612,7 @@ private static bool TryGetNotifyDataErrorInfo( bool hasOrInheritsClassLevelNotifyDataErrorInfo, out bool isValidationTargetValid) { - if (attributeData.AttributeClass?.HasFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyDataErrorInfoAttribute") == true) + if (attributeData.AttributeClass?.HasFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.NotifyDataErrorInfoAttribute") == true) { // Emit a diagnostic if the attribute is unnecessary if (hasOrInheritsClassLevelNotifyDataErrorInfo) @@ -625,7 +625,7 @@ private static bool TryGetNotifyDataErrorInfo( } // If the containing type is valid, track it - if (fieldSymbol.ContainingType.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableValidator")) + if (fieldSymbol.ContainingType.InheritsFromFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableValidator")) { isValidationTargetValid = true; @@ -657,7 +657,7 @@ private static bool TryGetNotifyDataErrorInfo( public static Diagnostic? GetIsNotifyDataErrorInfoDiagnosticForType(INamedTypeSymbol typeSymbol) { // If the containing type is valid, track it - if (!typeSymbol.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableValidator")) + if (!typeSymbol.InheritsFromFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableValidator")) { return Diagnostic.Create( InvalidTypeForNotifyDataErrorInfoError, diff --git a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.cs b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.cs index 2adabf88..6dd81327 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.cs @@ -124,7 +124,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) // Filter only the type symbols with [NotifyPropertyChangedRecipients] and create diagnostics for them IncrementalValuesProvider notifyRecipientsErrors = classSymbols - .Where(static item => item.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyPropertyChangedRecipientsAttribute")) + .Where(static item => item.HasAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.NotifyPropertyChangedRecipientsAttribute")) .Select(static (item, _) => Execute.GetIsNotifyingRecipientsDiagnosticForType(item)) .Where(static item => item is not null)!; @@ -134,7 +134,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) // Filter only the type symbols with [NotifyDataErrorInfo] and create diagnostics for them IncrementalValuesProvider notifyDataErrorInfoErrors = classSymbols - .Where(static item => item.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.NotifyDataErrorInfoAttribute")) + .Where(static item => item.HasAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.NotifyDataErrorInfoAttribute")) .Select(static (item, _) => Execute.GetIsNotifyDataErrorInfoDiagnosticForType(item)) .Where(static item => item is not null)!; diff --git a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableRecipientGenerator.cs b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableRecipientGenerator.cs index e56147b0..359fef78 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableRecipientGenerator.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableRecipientGenerator.cs @@ -38,7 +38,7 @@ public ObservableRecipientGenerator() ObservableRecipientInfo? info = null; // Check if the type already inherits from ObservableRecipient - if (typeSymbol.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableRecipient")) + if (typeSymbol.InheritsFromFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableRecipient")) { diagnostics = ImmutableArray.Create(DiagnosticInfo.Create(DuplicateObservableRecipientError, typeSymbol, typeSymbol)); @@ -46,7 +46,7 @@ public ObservableRecipientGenerator() } // Check if the type already inherits [ObservableRecipient] - if (typeSymbol.InheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableRecipientAttribute")) + if (typeSymbol.InheritsAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableRecipientAttribute")) { diagnostics = ImmutableArray.Create(DiagnosticInfo.Create(InvalidAttributeCombinationForObservableRecipientAttributeError, typeSymbol, typeSymbol)); @@ -55,10 +55,10 @@ public ObservableRecipientGenerator() // In order to use [ObservableRecipient], the target type needs to inherit from ObservableObject, // or be annotated with [ObservableObject] or [INotifyPropertyChanged] (with additional helpers). - if (!typeSymbol.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableObject") && - !typeSymbol.HasOrInheritsAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableObjectAttribute") && + if (!typeSymbol.InheritsFromFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableObject") && + !typeSymbol.HasOrInheritsAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableObjectAttribute") && !typeSymbol.HasOrInheritsAttribute(static a => - a.AttributeClass?.HasFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.INotifyPropertyChangedAttribute") == true && + a.AttributeClass?.HasFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.INotifyPropertyChangedAttribute") == true && !a.HasNamedArgument("IncludeAdditionalHelperMethods", false))) { diagnostics = ImmutableArray.Create(DiagnosticInfo.Create(MissingBaseObservableObjectFunctionalityError, typeSymbol, typeSymbol)); @@ -70,7 +70,7 @@ public ObservableRecipientGenerator() string typeName = typeSymbol.Name; bool hasExplicitConstructors = !(typeSymbol.InstanceConstructors.Length == 1 && typeSymbol.InstanceConstructors[0] is { Parameters.IsEmpty: true, IsImplicitlyDeclared: true }); bool isAbstract = typeSymbol.IsAbstract; - bool isObservableValidator = typeSymbol.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableValidator"); + bool isObservableValidator = typeSymbol.InheritsFromFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableValidator"); bool isRequiresUnreferencedCodeAttributeAvailable = compilation.HasAccessibleTypeWithMetadataName("System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute"); bool hasOnActivatedMethod = typeSymbol.GetMembers().Any(m => m is IMethodSymbol { Parameters.IsEmpty: true, Name: "OnActivated" }); bool hasOnDeactivatedMethod = typeSymbol.GetMembers().Any(m => m is IMethodSymbol { Parameters.IsEmpty: true, Name: "OnDeactivated" }); diff --git a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs index e046c4f3..575e71e2 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs @@ -31,7 +31,7 @@ private static class Execute /// Whether inherits from ObservableValidator. public static bool IsObservableValidator(INamedTypeSymbol typeSymbol) { - return typeSymbol.InheritsFromFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservableValidator"); + return typeSymbol.InheritsFromFullyQualifiedMetadataName("CommunityToolkit.Mvvm.ComponentModel.ObservableValidator"); } /// @@ -56,15 +56,15 @@ public static ValidationInfo GetInfo(INamedTypeSymbol typeSymbol) // all generators run in an undefined order and looking at the same original compilation, so the // current one wouldn't be able to see generated properties from other generators directly. if (memberSymbol is IFieldSymbol && - !attributes.Any(static a => a.AttributeClass?.HasFullyQualifiedName( - "global::CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute") == true)) + !attributes.Any(static a => a.AttributeClass?.HasFullyQualifiedMetadataName( + "CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute") == true)) { continue; } // Skip the current member if there are no validation attributes applied to it - if (!attributes.Any(a => a.AttributeClass?.InheritsFromFullyQualifiedName( - "global::System.ComponentModel.DataAnnotations.ValidationAttribute") == true)) + if (!attributes.Any(a => a.AttributeClass?.InheritsFromFullyQualifiedMetadataName( + "System.ComponentModel.DataAnnotations.ValidationAttribute") == true)) { continue; } diff --git a/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ISymbolExtensions.cs b/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ISymbolExtensions.cs index 207fc61f..a54073fd 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ISymbolExtensions.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ISymbolExtensions.cs @@ -47,18 +47,18 @@ public static bool HasFullyQualifiedName(this ISymbol symbol, string name) } /// - /// Checks whether or not a given symbol has an attribute with the specified full name. + /// Checks whether or not a given symbol has an attribute with the specified fully qualified metadata name. /// /// The input instance to check. /// The attribute name to look for. /// Whether or not has an attribute with the specified name. - public static bool HasAttributeWithFullyQualifiedName(this ISymbol symbol, string name) + public static bool HasAttributeWithFullyQualifiedMetadataName(this ISymbol symbol, string name) { ImmutableArray attributes = symbol.GetAttributes(); foreach (AttributeData attribute in attributes) { - if (attribute.AttributeClass?.HasFullyQualifiedName(name) == true) + if (attribute.AttributeClass?.HasFullyQualifiedMetadataName(name) == true) { return true; } @@ -69,19 +69,19 @@ public static bool HasAttributeWithFullyQualifiedName(this ISymbol symbol, strin #if !ROSLYN_4_3_1_OR_GREATER /// - /// Tries to get an attribute with the specified full name. + /// Tries to get an attribute with the specified fully qualified metadata name. /// /// The input instance to check. /// The attribute name to look for. /// The resulting attribute, if it was found. /// Whether or not has an attribute with the specified name. - public static bool TryGetAttributeWithFullyQualifiedName(this ISymbol symbol, string name, [NotNullWhen(true)] out AttributeData? attributeData) + public static bool TryGetAttributeWithFullyQualifiedMetadataName(this ISymbol symbol, string name, [NotNullWhen(true)] out AttributeData? attributeData) { ImmutableArray attributes = symbol.GetAttributes(); foreach (AttributeData attribute in attributes) { - if (attribute.AttributeClass?.HasFullyQualifiedName(name) == true) + if (attribute.AttributeClass?.HasFullyQualifiedMetadataName(name) == true) { attributeData = attribute; diff --git a/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ITypeSymbolExtensions.cs b/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ITypeSymbolExtensions.cs index e4ad86b2..82884d3e 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ITypeSymbolExtensions.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ITypeSymbolExtensions.cs @@ -20,11 +20,11 @@ internal static class ITypeSymbolExtensions /// The target instance to check. /// The full name of the type to check for inheritance. /// Whether or not is or inherits from . - public static bool HasOrInheritsFromFullyQualifiedName(this ITypeSymbol typeSymbol, string name) + public static bool HasOrInheritsFromFullyQualifiedMetadataName(this ITypeSymbol typeSymbol, string name) { for (ITypeSymbol? currentType = typeSymbol; currentType is not null; currentType = currentType.BaseType) { - if (currentType.HasFullyQualifiedName(name)) + if (currentType.HasFullyQualifiedMetadataName(name)) { return true; } @@ -39,13 +39,13 @@ public static bool HasOrInheritsFromFullyQualifiedName(this ITypeSymbol typeSymb /// The target instance to check. /// The full name of the type to check for inheritance. /// Whether or not inherits from . - public static bool InheritsFromFullyQualifiedName(this ITypeSymbol typeSymbol, string name) + public static bool InheritsFromFullyQualifiedMetadataName(this ITypeSymbol typeSymbol, string name) { INamedTypeSymbol? baseType = typeSymbol.BaseType; while (baseType != null) { - if (baseType.HasFullyQualifiedName(name)) + if (baseType.HasFullyQualifiedMetadataName(name)) { return true; } @@ -62,11 +62,11 @@ public static bool InheritsFromFullyQualifiedName(this ITypeSymbol typeSymbol, s /// The target instance to check. /// The full name of the type to check for interface implementation. /// Whether or not has an interface with the specified name. - public static bool HasInterfaceWithFullyQualifiedName(this ITypeSymbol typeSymbol, string name) + public static bool HasInterfaceWithFullyQualifiedMetadataName(this ITypeSymbol typeSymbol, string name) { foreach (INamedTypeSymbol interfaceType in typeSymbol.AllInterfaces) { - if (interfaceType.HasFullyQualifiedName(name)) + if (interfaceType.HasFullyQualifiedMetadataName(name)) { return true; } @@ -100,11 +100,11 @@ public static bool HasOrInheritsAttribute(this ITypeSymbol typeSymbol, FuncThe target instance to check. /// The name of the attribute to look for. /// Whether or not has an attribute with the specified type name. - public static bool HasOrInheritsAttributeWithFullyQualifiedName(this ITypeSymbol typeSymbol, string name) + public static bool HasOrInheritsAttributeWithFullyQualifiedMetadataName(this ITypeSymbol typeSymbol, string name) { for (ITypeSymbol? currentType = typeSymbol; currentType is not null; currentType = currentType.BaseType) { - if (currentType.HasAttributeWithFullyQualifiedName(name)) + if (currentType.HasAttributeWithFullyQualifiedMetadataName(name)) { return true; } @@ -120,11 +120,11 @@ public static bool HasOrInheritsAttributeWithFullyQualifiedName(this ITypeSymbol /// The target instance to check. /// The name of the attribute to look for. /// Whether or not has an attribute with the specified type name. - public static bool InheritsAttributeWithFullyQualifiedName(this ITypeSymbol typeSymbol, string name) + public static bool InheritsAttributeWithFullyQualifiedMetadataName(this ITypeSymbol typeSymbol, string name) { if (typeSymbol.BaseType is INamedTypeSymbol baseTypeSymbol) { - return HasOrInheritsAttributeWithFullyQualifiedName(baseTypeSymbol, name); + return HasOrInheritsAttributeWithFullyQualifiedMetadataName(baseTypeSymbol, name); } return false; diff --git a/CommunityToolkit.Mvvm.SourceGenerators/Input/RelayCommandGenerator.Execute.cs b/CommunityToolkit.Mvvm.SourceGenerators/Input/RelayCommandGenerator.Execute.cs index 1a1bdef0..62117a8c 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/Input/RelayCommandGenerator.Execute.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/Input/RelayCommandGenerator.Execute.cs @@ -371,7 +371,7 @@ private static bool IsCommandDefinitionUnique(IMethodSymbol methodSymbol, in Imm foreach (ISymbol symbol in methodSymbol.ContainingType.BaseType?.GetAllMembers(methodSymbol.Name) ?? Enumerable.Empty()) { if (symbol is IMethodSymbol otherSymbol && - otherSymbol.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.Input.RelayCommandAttribute")) + otherSymbol.HasAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.Input.RelayCommandAttribute")) { diagnostics.Add( MultipleRelayCommandMethodOverloadsError, @@ -387,7 +387,7 @@ private static bool IsCommandDefinitionUnique(IMethodSymbol methodSymbol, in Imm foreach (ISymbol symbol in methodSymbol.ContainingType.GetMembers(methodSymbol.Name)) { if (symbol is IMethodSymbol otherSymbol && - otherSymbol.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.Input.RelayCommandAttribute")) + otherSymbol.HasAttributeWithFullyQualifiedMetadataName("CommunityToolkit.Mvvm.Input.RelayCommandAttribute")) { // If the first [RelayCommand] overload is the current symbol, return immediately. This makes it so // that if multiple overloads are present, only the ones after the first declared one will have @@ -431,8 +431,7 @@ public static (string FieldName, string PropertyName) GetGeneratedFieldAndProper // Strip the "Async" suffix for methods returning a Task type if (methodSymbol.Name.EndsWith("Async") && - (methodSymbol.ReturnType.HasFullyQualifiedName("global::System.Threading.Tasks.Task") || - methodSymbol.ReturnType.InheritsFromFullyQualifiedName("global::System.Threading.Tasks.Task"))) + methodSymbol.ReturnType.HasOrInheritsFromFullyQualifiedMetadataName("System.Threading.Tasks.Task")) { propertyName = propertyName.Substring(0, propertyName.Length - "Async".Length); } @@ -509,8 +508,7 @@ private static bool TryMapCommandTypesFromMethod( } // Map all Task-returning methods - if (methodSymbol.ReturnType.HasFullyQualifiedName("global::System.Threading.Tasks.Task") || - methodSymbol.ReturnType.InheritsFromFullyQualifiedName("global::System.Threading.Tasks.Task")) + if (methodSymbol.ReturnType.HasOrInheritsFromFullyQualifiedMetadataName("System.Threading.Tasks.Task")) { // Map to IAsyncRelayCommand, AsyncRelayCommand, Func if (methodSymbol.Parameters.Length == 0) @@ -530,7 +528,7 @@ private static bool TryMapCommandTypesFromMethod( methodSymbol.Parameters[0] is IParameterSymbol { RefKind: RefKind.None, Type: { IsRefLikeType: false, TypeKind: not TypeKind.Pointer and not TypeKind.FunctionPointer } } singleParameter) { // Map to IAsyncRelayCommand, AsyncRelayCommand, Func - if (singleParameter.Type.HasFullyQualifiedName("global::System.Threading.CancellationToken")) + if (singleParameter.Type.HasFullyQualifiedMetadataName("System.Threading.CancellationToken")) { commandInterfaceType = "global::CommunityToolkit.Mvvm.Input.IAsyncRelayCommand"; commandClassType = "global::CommunityToolkit.Mvvm.Input.AsyncRelayCommand"; @@ -559,7 +557,7 @@ private static bool TryMapCommandTypesFromMethod( if (methodSymbol.Parameters.Length == 2 && methodSymbol.Parameters[0] is IParameterSymbol { RefKind: RefKind.None, Type: { IsRefLikeType: false, TypeKind: not TypeKind.Pointer and not TypeKind.FunctionPointer } } firstParameter && methodSymbol.Parameters[1] is IParameterSymbol { RefKind: RefKind.None, Type: { IsRefLikeType: false, TypeKind: not TypeKind.Pointer and not TypeKind.FunctionPointer } } secondParameter && - secondParameter.Type.HasFullyQualifiedName("global::System.Threading.CancellationToken")) + secondParameter.Type.HasFullyQualifiedMetadataName("System.Threading.CancellationToken")) { commandInterfaceType = "global::CommunityToolkit.Mvvm.Input.IAsyncRelayCommand"; commandClassType = "global::CommunityToolkit.Mvvm.Input.AsyncRelayCommand"; @@ -787,7 +785,7 @@ private static bool TryGetCanExecuteExpressionFromSymbol( if (canExecuteSymbol is IMethodSymbol canExecuteMethodSymbol) { // The return type must always be a bool - if (!canExecuteMethodSymbol.ReturnType.HasFullyQualifiedName("bool")) + if (!canExecuteMethodSymbol.ReturnType.HasFullyQualifiedMetadataName("System.Boolean")) { goto Failure; } @@ -822,7 +820,7 @@ private static bool TryGetCanExecuteExpressionFromSymbol( else if (canExecuteSymbol is IPropertySymbol { GetMethod: not null } canExecutePropertySymbol) { // The property type must always be a bool - if (!canExecutePropertySymbol.Type.HasFullyQualifiedName("bool")) + if (!canExecutePropertySymbol.Type.HasFullyQualifiedMetadataName("System.Boolean")) { goto Failure; } @@ -863,7 +861,7 @@ private static bool TryGetCanExecuteMemberFromGeneratedProperty( { // Only look for instance fields of bool type if (memberSymbol is not IFieldSymbol { IsStatic: false } fieldSymbol || - !fieldSymbol.Type.HasFullyQualifiedName("bool")) + !fieldSymbol.Type.HasFullyQualifiedMetadataName("System.Boolean")) { continue; } @@ -872,8 +870,8 @@ private static bool TryGetCanExecuteMemberFromGeneratedProperty( // Only filter fields with the [ObservableProperty] attribute if (memberSymbol is IFieldSymbol && - !attributes.Any(static a => a.AttributeClass?.HasFullyQualifiedName( - "global::CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute") == true)) + !attributes.Any(static a => a.AttributeClass?.HasFullyQualifiedMetadataName( + "CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute") == true)) { continue; } diff --git a/CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.Execute.cs b/CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.Execute.cs index 9067f859..6a50d4b6 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.Execute.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/Messaging/IMessengerRegisterAllGenerator.Execute.cs @@ -33,8 +33,7 @@ public static ImmutableArray GetInterfaces(INamedTypeSymbol ty foreach (INamedTypeSymbol interfaceSymbol in typeSymbol.AllInterfaces) { - if (interfaceSymbol.MetadataName is "IRecipient`1" && - interfaceSymbol.OriginalDefinition.HasFullyQualifiedName("global::CommunityToolkit.Mvvm.Messaging.IRecipient")) + if (interfaceSymbol.HasFullyQualifiedMetadataName("CommunityToolkit.Mvvm.Messaging.IRecipient`1")) { iRecipientInterfaces.Add(interfaceSymbol); } diff --git a/CommunityToolkit.Mvvm.SourceGenerators/Polyfills/SyntaxValueProviderExtensions.cs b/CommunityToolkit.Mvvm.SourceGenerators/Polyfills/SyntaxValueProviderExtensions.cs index b5ac1ab6..44a94982 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/Polyfills/SyntaxValueProviderExtensions.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/Polyfills/SyntaxValueProviderExtensions.cs @@ -38,8 +38,6 @@ public static IncrementalValuesProvider ForAttributeWithMetadataName( Func predicate, Func transform) { - string fullyQualifiedMetadataNameWithGlobalPrefix = $"global::{fullyQualifiedMetadataName}"; - return syntaxValueProvider .CreateSyntaxProvider( @@ -56,7 +54,7 @@ public static IncrementalValuesProvider ForAttributeWithMetadataName( } // Skip symbols without the target attribute - if (!symbol.TryGetAttributeWithFullyQualifiedName(fullyQualifiedMetadataNameWithGlobalPrefix, out AttributeData? attributeData)) + if (!symbol.TryGetAttributeWithFullyQualifiedMetadataName(fullyQualifiedMetadataName, out AttributeData? attributeData)) { return null; } From b4b1e45c85c581232601637addf6d44b5ce186cf Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 30 Oct 2022 13:35:32 +0100 Subject: [PATCH 4/6] Remove unnecessary code --- ...rValidateAllPropertiesGenerator.Execute.cs | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs index 575e71e2..fb85b183 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.Execute.cs @@ -8,7 +8,6 @@ using CommunityToolkit.Mvvm.SourceGenerators.ComponentModel.Models; using CommunityToolkit.Mvvm.SourceGenerators.Extensions; using CommunityToolkit.Mvvm.SourceGenerators.Helpers; -using CommunityToolkit.Mvvm.SourceGenerators.Messaging.Models; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -86,27 +85,6 @@ public static ValidationInfo GetInfo(INamedTypeSymbol typeSymbol) propertyNames.ToImmutable()); } - /// - /// Gets the instance from the given info. - /// - /// The type symbol for the target type being inspected. - /// The input array of interface type symbols being handled. - /// A instance for the current type being inspected. - public static RecipientInfo GetInfo(INamedTypeSymbol typeSymbol, ImmutableArray interfaceSymbols) - { - using ImmutableArrayBuilder names = ImmutableArrayBuilder.Rent(); - - foreach (INamedTypeSymbol interfaceSymbol in interfaceSymbols) - { - names.Add(interfaceSymbol.TypeArguments[0].GetFullyQualifiedName()); - } - - return new( - typeSymbol.GetFullyQualifiedMetadataName(), - typeSymbol.GetFullyQualifiedName(), - names.ToImmutable()); - } - /// /// Gets the head instance. /// From 56e218f20069a0c73ffb4331ff82fad77ac210b6 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 30 Oct 2022 13:39:28 +0100 Subject: [PATCH 5/6] Make AppendFullyQualifiedMetadataName private --- .../Extensions/ITypeSymbolExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ITypeSymbolExtensions.cs b/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ITypeSymbolExtensions.cs index 82884d3e..52a81398 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ITypeSymbolExtensions.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/Extensions/ITypeSymbolExtensions.cs @@ -164,7 +164,7 @@ public static string GetFullyQualifiedMetadataName(this ITypeSymbol symbol) /// /// The input instance. /// The target instance. - public static void AppendFullyQualifiedMetadataName(this ITypeSymbol symbol, in ImmutableArrayBuilder builder) + private static void AppendFullyQualifiedMetadataName(this ITypeSymbol symbol, in ImmutableArrayBuilder builder) { static void BuildFrom(ISymbol? symbol, in ImmutableArrayBuilder builder) { From 90b91f85fe9c16bca36d67ecbe04e5472f5fda20 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 30 Oct 2022 13:45:12 +0100 Subject: [PATCH 6/6] Improve boolean type checks --- .../Input/RelayCommandGenerator.Execute.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/CommunityToolkit.Mvvm.SourceGenerators/Input/RelayCommandGenerator.Execute.cs b/CommunityToolkit.Mvvm.SourceGenerators/Input/RelayCommandGenerator.Execute.cs index 62117a8c..89b85295 100644 --- a/CommunityToolkit.Mvvm.SourceGenerators/Input/RelayCommandGenerator.Execute.cs +++ b/CommunityToolkit.Mvvm.SourceGenerators/Input/RelayCommandGenerator.Execute.cs @@ -785,7 +785,7 @@ private static bool TryGetCanExecuteExpressionFromSymbol( if (canExecuteSymbol is IMethodSymbol canExecuteMethodSymbol) { // The return type must always be a bool - if (!canExecuteMethodSymbol.ReturnType.HasFullyQualifiedMetadataName("System.Boolean")) + if (canExecuteMethodSymbol.ReturnType is not { SpecialType: SpecialType.System_Boolean }) { goto Failure; } @@ -820,7 +820,7 @@ private static bool TryGetCanExecuteExpressionFromSymbol( else if (canExecuteSymbol is IPropertySymbol { GetMethod: not null } canExecutePropertySymbol) { // The property type must always be a bool - if (!canExecutePropertySymbol.Type.HasFullyQualifiedMetadataName("System.Boolean")) + if (canExecutePropertySymbol.Type is not { SpecialType: SpecialType.System_Boolean }) { goto Failure; } @@ -860,8 +860,7 @@ private static bool TryGetCanExecuteMemberFromGeneratedProperty( foreach (ISymbol memberSymbol in containingType.GetAllMembers()) { // Only look for instance fields of bool type - if (memberSymbol is not IFieldSymbol { IsStatic: false } fieldSymbol || - !fieldSymbol.Type.HasFullyQualifiedMetadataName("System.Boolean")) + if (memberSymbol is not IFieldSymbol { IsStatic: false, Type.SpecialType: SpecialType.System_Boolean } fieldSymbol) { continue; }