File: PullMemberUp\MemberAndDestinationValidator.cs
Web Access
Project: src\src\Features\Core\Portable\Microsoft.CodeAnalysis.Features.csproj (Microsoft.CodeAnalysis.Features)
// 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.Diagnostics.CodeAnalysis;
using System.Threading;
using Microsoft.CodeAnalysis.Shared.Extensions;
 
namespace Microsoft.CodeAnalysis.PullMemberUp;
 
internal static class MemberAndDestinationValidator
{
    public static bool IsDestinationValid(Solution solution, INamedTypeSymbol destination, CancellationToken cancellationToken)
    {
        // Make sure destination is class or interface since it could be ErrorTypeSymbol
        if (destination.TypeKind is not TypeKind.Interface and not TypeKind.Class)
        {
            return false;
        }
 
        // Don't provide any refactoring option if the destination is not in source.
        // If the destination is generated code, also don't provide refactoring since we can't make sure if we won't break it.
        var isDestinationInSourceAndNotGeneratedCode =
            destination.Locations.Any(static (location, arg) => location.IsInSource && !arg.solution.GetRequiredDocument(location.SourceTree).IsGeneratedCode(arg.cancellationToken), (solution, cancellationToken));
        return isDestinationInSourceAndNotGeneratedCode;
    }
 
    public static bool IsMemberValid([NotNullWhen(true)] ISymbol? member)
    {
        if (member is null)
        {
            return false;
        }
 
        if (member.IsImplicitlyDeclared)
        {
            return false;
        }
 
        // Static, abstract and accessiblity are not checked here but in PullMembersUpOptionsBuilder.cs since there are
        // two refactoring options provided for pull members up,
        // 1. Quick Action (Only allow members that don't cause error)
        // 2. Dialog box (Allow modifers may cause error and will provide fixing)
        return member switch
        {
            IMethodSymbol methodSymbol => methodSymbol.MethodKind == MethodKind.Ordinary,
            _ => member.IsKind(SymbolKind.Property) || member.IsKind(SymbolKind.Event) || member.IsKind(SymbolKind.Field),
        };
    }
}