File: CodeRefactorings\MoveType\AbstractMoveTypeService.State.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.
 
#nullable disable
 
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.LanguageService;
using Microsoft.CodeAnalysis.Shared.Extensions;
 
namespace Microsoft.CodeAnalysis.CodeRefactorings.MoveType;
 
internal abstract partial class AbstractMoveTypeService<TService, TTypeDeclarationSyntax, TNamespaceDeclarationSyntax, TMemberDeclarationSyntax, TCompilationUnitSyntax>
{
    private sealed class State
    {
        public SemanticDocument SemanticDocument { get; }
 
        public TTypeDeclarationSyntax TypeNode { get; set; }
        public string TypeName { get; set; }
        public string DocumentNameWithoutExtension { get; set; }
        public bool IsDocumentNameAValidIdentifier { get; set; }
 
        private State(SemanticDocument document)
        {
            SemanticDocument = document;
        }
 
        internal static State Generate(
            SemanticDocument document, TTypeDeclarationSyntax typeDeclaration,
            CancellationToken cancellationToken)
        {
            var state = new State(document);
            if (!state.TryInitialize(typeDeclaration, cancellationToken))
            {
                return null;
            }
 
            return state;
        }
 
        private bool TryInitialize(
            TTypeDeclarationSyntax typeDeclaration,
            CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return false;
            }
 
            var tree = SemanticDocument.SyntaxTree;
            var root = SemanticDocument.Root;
            var syntaxFacts = SemanticDocument.Document.GetLanguageService<ISyntaxFactsService>();
 
            // compiler declared types, anonymous types, types defined in metadata should be filtered out.
            if (SemanticDocument.SemanticModel.GetDeclaredSymbol(typeDeclaration, cancellationToken) is not INamedTypeSymbol typeSymbol ||
                typeSymbol.Locations.Any(static loc => loc.IsInMetadata) ||
                typeSymbol.IsAnonymousType ||
                typeSymbol.IsImplicitlyDeclared ||
                typeSymbol.Name == string.Empty)
            {
                return false;
            }
 
            TypeNode = typeDeclaration;
            TypeName = typeSymbol.Name;
            DocumentNameWithoutExtension = Path.GetFileNameWithoutExtension(SemanticDocument.Document.Name);
            IsDocumentNameAValidIdentifier = syntaxFacts.IsValidIdentifier(DocumentNameWithoutExtension);
 
            return true;
        }
    }
}