public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.Document
                              .GetSyntaxRootAsync(context.CancellationToken)
                              .ConfigureAwait(false);

            ClassDeclarationSyntax classDeclaration = root
                                                      .FindNode(context.Span, getInnermostNodeForTie: true)?
                                                      .FirstAncestorOrSelf <ClassDeclarationSyntax>();

            Debug.Assert(classDeclaration != null, $"{nameof(classDeclaration)} is null");

            if (classDeclaration == null)
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case DiagnosticIdentifiers.MarkClassAsStatic:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Mark class as static",
                        cancellationToken =>
                        {
                            return(MarkClassAsStaticRefactoring.RefactorAsync(
                                       context.Document,
                                       classDeclaration,
                                       cancellationToken));
                        },
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.AddStaticModifierToAllPartialClassDeclarations:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Add static modifier",
                        cancellationToken =>
                        {
                            return(AddModifierRefactoring.RefactorAsync(
                                       context.Document,
                                       classDeclaration,
                                       SyntaxKind.StaticKeyword,
                                       cancellationToken));
                        },
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }
                }
            }
        }
        private void AnalyzeNamedType(SymbolAnalysisContext context)
        {
            var symbol = (INamedTypeSymbol)context.Symbol;

            RemovePartialModifierFromTypeWithSinglePartRefactoring.Analyze(context, symbol);

            MarkClassAsStaticRefactoring.Analyze(context, symbol);

            AddStaticModifierToAllPartialClassDeclarationsRefactoring.Analyze(context, symbol);

            DeclareTypeInsideNamespaceRefactoring.Analyze(context, symbol);
        }
        private void AnalyzeNamedType(SymbolAnalysisContext context)
        {
            if (GeneratedCodeAnalyzer?.IsGeneratedCode(context) == true)
            {
                return;
            }

            var symbol = (INamedTypeSymbol)context.Symbol;

            TypeKind kind = symbol.TypeKind;

            if (kind == TypeKind.Class ||
                kind == TypeKind.Struct ||
                kind == TypeKind.Interface)
            {
                ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences;

                if (syntaxReferences.Length == 1)
                {
                    var declaration = syntaxReferences[0].GetSyntax(context.CancellationToken) as MemberDeclarationSyntax;

                    if (declaration != null)
                    {
                        SyntaxToken partialToken = declaration.GetModifiers()
                                                   .FirstOrDefault(f => f.IsKind(SyntaxKind.PartialKeyword));

                        if (partialToken.IsKind(SyntaxKind.PartialKeyword))
                        {
                            context.ReportDiagnostic(
                                DiagnosticDescriptors.RemovePartialModifierFromTypeWithSinglePart,
                                partialToken.GetLocation());
                        }
                    }
                }
            }

            if (MarkClassAsStaticRefactoring.CanRefactor(symbol))
            {
                foreach (SyntaxReference syntaxReference in symbol.DeclaringSyntaxReferences)
                {
                    var classDeclaration = syntaxReference.GetSyntax(context.CancellationToken) as ClassDeclarationSyntax;

                    if (classDeclaration?.Modifiers.Contains(SyntaxKind.StaticKeyword) == false)
                    {
                        context.ReportDiagnostic(
                            DiagnosticDescriptors.MarkClassAsStatic,
                            classDeclaration.Identifier.GetLocation());

                        break;
                    }
                }
            }

            if (kind == TypeKind.Class &&
                symbol.IsStatic &&
                !symbol.IsImplicitClass &&
                !symbol.IsImplicitlyDeclared)
            {
                ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences;

                if (syntaxReferences.Length > 1)
                {
                    bool isStatic = false;
                    List <ClassDeclarationSyntax> classDeclarations = null;

                    foreach (SyntaxReference syntaxReference in syntaxReferences)
                    {
                        SyntaxNode node = syntaxReference.GetSyntax(context.CancellationToken);

                        Debug.Assert(node.IsKind(SyntaxKind.ClassDeclaration), node.Kind().ToString());

                        if (node.IsKind(SyntaxKind.ClassDeclaration))
                        {
                            var             classDeclaration = (ClassDeclarationSyntax)node;
                            SyntaxTokenList modifiers        = classDeclaration.Modifiers;

                            if (modifiers.Contains(SyntaxKind.StaticKeyword))
                            {
                                isStatic = true;
                            }
                            else if (!classDeclaration.ContainsDirectives(modifiers.Span))
                            {
                                if (classDeclarations == null)
                                {
                                    classDeclarations = new List <ClassDeclarationSyntax>();
                                }

                                classDeclarations.Add(classDeclaration);
                            }
                        }
                    }

                    if (isStatic &&
                        classDeclarations != null)
                    {
                        foreach (ClassDeclarationSyntax classDeclaration in classDeclarations)
                        {
                            context.ReportDiagnostic(
                                DiagnosticDescriptors.AddStaticModifierToAllPartialClassDeclarations,
                                classDeclaration.Identifier.GetLocation());
                        }
                    }
                }
            }

            if (symbol.ContainingNamespace?.IsGlobalNamespace == true)
            {
                ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences;

                foreach (SyntaxReference syntaxReference in syntaxReferences)
                {
                    SyntaxNode node = syntaxReference.GetSyntax(context.CancellationToken);

                    if (node != null)
                    {
                        SyntaxToken identifier = GetDeclarationIdentifier(kind, node);

                        if (!identifier.IsKind(SyntaxKind.None))
                        {
                            context.ReportDiagnostic(
                                DiagnosticDescriptors.DeclareTypeInsideNamespace,
                                identifier.GetLocation(),
                                identifier.ValueText);
                        }
                    }
                }
            }
        }
Ejemplo n.º 4
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            ClassDeclarationSyntax classDeclaration = root
                                                      .FindNode(context.Span, getInnermostNodeForTie: true)?
                                                      .FirstAncestorOrSelf <ClassDeclarationSyntax>();

            Debug.Assert(classDeclaration != null, $"{nameof(classDeclaration)} is null");

            if (classDeclaration == null)
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case DiagnosticIdentifiers.MarkClassAsStatic:
                {
                    CodeAction codeAction = null;

                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ISymbol symbol = semanticModel.GetDeclaredSymbol(classDeclaration, context.CancellationToken);

                    ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences;

                    if (syntaxReferences.Length == 1)
                    {
                        codeAction = CodeAction.Create(
                            $"Mark '{classDeclaration.Identifier.ValueText}' as static",
                            cancellationToken =>
                            {
                                return(MarkClassAsStaticRefactoring.RefactorAsync(
                                           context.Document,
                                           classDeclaration,
                                           cancellationToken));
                            },
                            diagnostic.Id + EquivalenceKeySuffix);
                    }
                    else
                    {
                        ImmutableArray <ClassDeclarationSyntax> classDeclarations = syntaxReferences
                                                                                    .Select(f => (ClassDeclarationSyntax)f.GetSyntax(context.CancellationToken))
                                                                                    .ToImmutableArray();

                        codeAction = CodeAction.Create(
                            $"Mark '{classDeclaration.Identifier.ValueText}' as static",
                            cancellationToken =>
                            {
                                return(MarkClassAsStaticRefactoring.RefactorAsync(
                                           context.Solution(),
                                           classDeclarations,
                                           cancellationToken));
                            },
                            diagnostic.Id + EquivalenceKeySuffix);
                    }

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.AddStaticModifierToAllPartialClassDeclarations:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Add static modifier",
                        cancellationToken =>
                        {
                            return(AddStaticModifierToAllPartialClassDeclarationsRefactoring.RefactorAsync(
                                       context.Document,
                                       classDeclaration,
                                       cancellationToken));
                        },
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }
                }
            }
        }