// 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. using System; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Linq; using Microsoft.CodeAnalysis; namespace Analyzer.Utilities.Extensions { internal static class IPropertySymbolExtensions { /// <summary> /// Check if a property is an auto-property. /// TODO: Remove this helper when https://github.com/dotnet/roslyn/issues/46682 is handled. /// </summary> public static bool IsAutoProperty(this IPropertySymbol propertySymbol) => propertySymbol.ContainingType.GetMembers().OfType<IFieldSymbol>().Any(f => f.IsImplicitlyDeclared && propertySymbol.Equals(f.AssociatedSymbol)); public static bool IsIsCompletedFromAwaiterPattern( [NotNullWhen(true)] this IPropertySymbol? property, [NotNullWhen(true)] INamedTypeSymbol? inotifyCompletionType, [NotNullWhen(true)] INamedTypeSymbol? icriticalNotifyCompletionType) { if (property is null || !property.Name.Equals("IsCompleted", StringComparison.Ordinal) || property.Type?.SpecialType != SpecialType.System_Boolean) { return false; } var containingType = property.ContainingType?.OriginalDefinition; return containingType.DerivesFrom(inotifyCompletionType) || containingType.DerivesFrom(icriticalNotifyCompletionType); } public static ImmutableArray<IPropertySymbol> GetOriginalDefinitions(this IPropertySymbol propertySymbol) { ImmutableArray<IPropertySymbol>.Builder originalDefinitionsBuilder = ImmutableArray.CreateBuilder<IPropertySymbol>(); if (propertySymbol.IsOverride && (propertySymbol.OverriddenProperty != null)) { originalDefinitionsBuilder.Add(propertySymbol.OverriddenProperty); } if (!propertySymbol.ExplicitInterfaceImplementations.IsEmpty) { originalDefinitionsBuilder.AddRange(propertySymbol.ExplicitInterfaceImplementations); } var typeSymbol = propertySymbol.ContainingType; var methodSymbolName = propertySymbol.Name; originalDefinitionsBuilder.AddRange(typeSymbol.AllInterfaces .SelectMany(m => m.GetMembers(methodSymbolName)) .OfType<IPropertySymbol>() .Where(m => propertySymbol.Parameters.Length == m.Parameters.Length && propertySymbol.IsIndexer == m.IsIndexer && typeSymbol.FindImplementationForInterfaceMember(m) != null)); return originalDefinitionsBuilder.ToImmutable(); } } } |