Пример #1
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.ChangeAccessibility) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddStaticModifier) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveThisModifier) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.MakeContainingClassNonStatic) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddPartialModifier) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveOutModifier) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveRefModifier) &&
                !Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddModifierAbstract))
            {
                return;
            }

            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindToken(root, context.Span.Start, out SyntaxToken token))
            {
                return;
            }

            SyntaxNode node = token.Parent;

            if (!node.Kind().SupportsModifiers())
            {
                node = node.FirstAncestor(f => f.Kind().SupportsModifiers());
            }

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

            if (node == null)
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.ModifierIsNotValidForThisItem:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        break;
                    }

                    SyntaxTokenList modifiers = node.GetModifiers();

                    if (modifiers.Contains(token))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, token);
                        break;
                    }
                    else if (IsInterfaceMemberOrExplicitInterfaceImplementation(node))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifiers(context, diagnostic, node, modifiers, f =>
                            {
                                switch (f.Kind())
                                {
                                case SyntaxKind.PublicKeyword:
                                case SyntaxKind.ProtectedKeyword:
                                case SyntaxKind.InternalKeyword:
                                case SyntaxKind.PrivateKeyword:
                                case SyntaxKind.StaticKeyword:
                                case SyntaxKind.VirtualKeyword:
                                case SyntaxKind.OverrideKeyword:
                                case SyntaxKind.AbstractKeyword:
                                    {
                                        return(true);
                                    }
                                }

                                return(false);
                            });
                    }
                    else if (node.IsKind(SyntaxKind.IndexerDeclaration))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.StaticKeyword);
                    }
                    else if (node.IsKind(SyntaxKind.PropertyDeclaration))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.AsyncKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.MoreThanOneProtectionModifier:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, token);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.AccessibilityModifiersMayNotBeUsedOnAccessorsInInterface:
                case CompilerDiagnosticIdentifiers.AccessModifiersAreNotAllowedOnStaticConstructors:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveAccessModifiers(context, diagnostic, node);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ModifiersCannotBePlacedOnEventAccessorDeclarations:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifiers(context, diagnostic, node);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.OnlyMethodsClassesStructsOrInterfacesMayBePartial:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.PartialKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ClassCannotBeBothStaticAndSealed:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.StaticKeyword, additionalKey: nameof(SyntaxKind.StaticKeyword));
                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.SealedKeyword, additionalKey: nameof(SyntaxKind.SealedKeyword));
                    break;
                }

                case CompilerDiagnosticIdentifiers.FieldCanNotBeBothVolatileAndReadOnly:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        break;
                    }

                    var fieldDeclaration = (FieldDeclarationSyntax)node;

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, fieldDeclaration, SyntaxKind.VolatileKeyword, additionalKey: nameof(SyntaxKind.VolatileKeyword));
                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, fieldDeclaration, SyntaxKind.ReadOnlyKeyword, additionalKey: nameof(SyntaxKind.ReadOnlyKeyword));
                    break;
                }

                case CompilerDiagnosticIdentifiers.NewProtectedMemberDeclaredInSealedClass:
                case CompilerDiagnosticIdentifiers.StaticClassesCannotContainProtectedMembers:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.ChangeAccessibility))
                    {
                        ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternalOrPrivate);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.VirtualOrAbstractmembersCannotBePrivate:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.ChangeAccessibility))
                    {
                        ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternalOrProtected);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.AbstractPropertiesCannotHavePrivateAccessors:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveAccessModifiers(context, diagnostic, node, additionalKey: CodeFixIdentifiers.RemoveInvalidModifier);
                    }

                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.ChangeAccessibility))
                    {
                        ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternalOrProtected);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.StaticMemberCannotBeMarkedOverrideVirtualOrAbstract:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        break;
                    }

                    if (!node.IsParentKind(SyntaxKind.ClassDeclaration) ||
                        !((ClassDeclarationSyntax)node.Parent).Modifiers.Contains(SyntaxKind.StaticKeyword))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.StaticKeyword, additionalKey: nameof(SyntaxKind.StaticKeyword));
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.OverrideKeyword, additionalKey: nameof(SyntaxKind.OverrideKeyword));
                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.VirtualKeyword, additionalKey: nameof(SyntaxKind.VirtualKeyword));
                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.AbstractKeyword, additionalKey: nameof(SyntaxKind.AbstractKeyword));
                    break;
                }

                case CompilerDiagnosticIdentifiers.AsyncModifierCanOnlyBeUsedInMethodsThatHaveBody:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.AsyncKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.PartialMethodCannotHaveAccessModifiersOrVirtualAbstractOverrideNewSealedOrExternModifiers:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifiers(context, diagnostic, node, f =>
                        {
                            switch (f.Kind())
                            {
                            case SyntaxKind.PublicKeyword:
                            case SyntaxKind.ProtectedKeyword:
                            case SyntaxKind.InternalKeyword:
                            case SyntaxKind.PrivateKeyword:
                            case SyntaxKind.VirtualKeyword:
                            case SyntaxKind.AbstractKeyword:
                            case SyntaxKind.OverrideKeyword:
                            case SyntaxKind.NewKeyword:
                            case SyntaxKind.SealedKeyword:
                            case SyntaxKind.ExternKeyword:
                                {
                                    return(true);
                                }
                            }

                            return(false);
                        });

                    break;
                }

                case CompilerDiagnosticIdentifiers.ExtensionMethodMustBeStatic:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddStaticModifier))
                    {
                        AddStaticModifier(context, diagnostic, node, CodeFixIdentifiers.AddStaticModifier);
                    }

                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveThisModifier))
                    {
                        var methodDeclaration = (MethodDeclarationSyntax)node;

                        ParameterSyntax parameter = methodDeclaration.ParameterList.Parameters.First();

                        SyntaxToken modifier = parameter.Modifiers.Find(SyntaxKind.ThisKeyword);

                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, parameter, modifier, additionalKey: CodeFixIdentifiers.RemoveThisModifier);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ExtensionMethodMustBeDefinedInNonGenericStaticClass:
                {
                    if (!node.IsKind(SyntaxKind.ClassDeclaration))
                    {
                        return;
                    }

                    var classDeclaration = (ClassDeclarationSyntax)node;

                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddStaticModifier) &&
                        !classDeclaration.IsStatic())
                    {
                        AddStaticModifier(context, diagnostic, node, CodeFixIdentifiers.AddStaticModifier);
                    }

                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveThisModifier))
                    {
                        IEnumerable <ParameterSyntax> thisParameters = classDeclaration.Members
                                                                       .Where(f => f.IsKind(SyntaxKind.MethodDeclaration))
                                                                       .Cast <MethodDeclarationSyntax>()
                                                                       .Select(f => f.ParameterList?.Parameters.FirstOrDefault())
                                                                       .Where(f => f?.Modifiers.Contains(SyntaxKind.ThisKeyword) == true);

                        ModifiersCodeFixRegistrator.RemoveModifier(
                            context,
                            diagnostic,
                            thisParameters,
                            SyntaxKind.ThisKeyword,
                            title: "Remove 'this' modifier from extension methods",
                            additionalKey: CodeFixIdentifiers.RemoveThisModifier);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.NoDefiningDeclarationFoundForImplementingDeclarationOfPartialMethod:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.PartialKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.MethodHasParameterModifierThisWhichIsNotOnFirstParameter:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveThisModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, token.Parent, token);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotDeclareInstanceMembersInStaticClass:
                case CompilerDiagnosticIdentifiers.StaticClassesCannotHaveInstanceConstructors:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddStaticModifier))
                    {
                        AddStaticModifier(context, diagnostic, node, CodeFixIdentifiers.AddStaticModifier);
                    }

                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.MakeContainingClassNonStatic))
                    {
                        var classDeclaration = (ClassDeclarationSyntax)node.Parent;

                        ModifiersCodeFixRegistrator.RemoveModifier(
                            context,
                            diagnostic,
                            classDeclaration,
                            classDeclaration.Modifiers.Find(SyntaxKind.StaticKeyword),
                            title: "Make containing class non-static",
                            additionalKey: CodeFixIdentifiers.MakeContainingClassNonStatic);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.ElementsDefinedInNamespaceCannotBeExplicitlyDeclaredAsPrivateProtectedOrProtectedInternal:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.ChangeAccessibility))
                    {
                        ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternal);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.NamespaceAlreadyContainsDefinition:
                case CompilerDiagnosticIdentifiers.TypeAlreadyContainsDefinition:
                {
                    if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddPartialModifier))
                    {
                        break;
                    }

                    if (!node.IsKind(
                            SyntaxKind.ClassDeclaration,
                            SyntaxKind.StructDeclaration,
                            SyntaxKind.InterfaceDeclaration,
                            SyntaxKind.MethodDeclaration))
                    {
                        return;
                    }

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

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

                    ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences;

                    if (syntaxReferences.Length <= 1)
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.AddModifier(
                        context,
                        diagnostic,
                        ImmutableArray.CreateRange(syntaxReferences, f => f.GetSyntax(context.CancellationToken)),
                        SyntaxKind.PartialKeyword);

                    break;
                }

                case CompilerDiagnosticIdentifiers.NoSuitableMethodFoundToOverride:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveInvalidModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.OverrideKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.AsyncMethodsCannotHaveRefOrOutParameters:
                case CompilerDiagnosticIdentifiers.IteratorsCannotHaveRefOrOutParameters:
                case CompilerDiagnosticIdentifiers.ReadOnlyFieldCannotBePassedAsRefOrOutValue:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveRefModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.RefKeyword, additionalKey: nameof(SyntaxKind.RefKeyword));
                    }

                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveOutModifier))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.OutKeyword, additionalKey: nameof(SyntaxKind.OutKeyword));
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CannotHaveInstancePropertyOrFieldInitializersInStruct:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddStaticModifier))
                    {
                        AddStaticModifier(context, diagnostic, node);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.MemberMustDeclareBodyBecauseItIsNotMarkedAbstractExternOrPartial:
                {
                    if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddModifierAbstract) &&
                        node.Kind() == SyntaxKind.MethodDeclaration &&
                        (node.Parent as ClassDeclarationSyntax)?.Modifiers.Contains(SyntaxKind.AbstractKeyword) == true)
                    {
                        ModifiersCodeFixRegistrator.AddModifier(context, diagnostic, node, SyntaxKind.AbstractKeyword);
                    }

                    break;
                }
                }
            }
        }
Пример #2
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindToken(root, context.Span.Start, out SyntaxToken token))
            {
                return;
            }

            SyntaxNode node = token.Parent;

            if (!CSharpFacts.CanHaveModifiers(node.Kind()))
            {
                node = node.FirstAncestor(f => CSharpFacts.CanHaveModifiers(f.Kind()));
            }

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

            if (node == null)
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.CS0106_ModifierIsNotValidForThisItem:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree))
                    {
                        break;
                    }

                    SyntaxTokenList modifiers = SyntaxInfo.ModifierListInfo(node).Modifiers;

                    if (modifiers.Contains(token))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, token);
                        break;
                    }
                    else if (IsInterfaceMemberOrExplicitInterfaceImplementation(node))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifiers(
                            context,
                            diagnostic,
                            node,
                            modifiers,
                            f =>
                            {
                                switch (f.Kind())
                                {
                                case SyntaxKind.PublicKeyword:
                                case SyntaxKind.ProtectedKeyword:
                                case SyntaxKind.InternalKeyword:
                                case SyntaxKind.PrivateKeyword:
                                case SyntaxKind.StaticKeyword:
                                case SyntaxKind.VirtualKeyword:
                                case SyntaxKind.OverrideKeyword:
                                case SyntaxKind.AbstractKeyword:
                                    {
                                        return(true);
                                    }
                                }

                                return(false);
                            });
                    }
                    else if (node.IsKind(SyntaxKind.MethodDeclaration, SyntaxKind.PropertyDeclaration, SyntaxKind.IndexerDeclaration, SyntaxKind.EventDeclaration, SyntaxKind.EventFieldDeclaration) &&
                             node.IsParentKind(SyntaxKind.StructDeclaration, SyntaxKind.RecordStructDeclaration) &&
                             modifiers.Contains(SyntaxKind.VirtualKeyword))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.VirtualKeyword);
                    }
                    else if (node.IsKind(SyntaxKind.IndexerDeclaration) &&
                             modifiers.Contains(SyntaxKind.StaticKeyword))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.StaticKeyword);
                    }
                    else if (node.IsKind(SyntaxKind.PropertyDeclaration, SyntaxKind.IndexerDeclaration, SyntaxKind.EventDeclaration, SyntaxKind.EventFieldDeclaration) &&
                             modifiers.Contains(SyntaxKind.AsyncKeyword))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.AsyncKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0107_MoreThanOneProtectionModifier:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, token);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0275_AccessibilityModifiersMayNotBeUsedOnAccessorsInInterface:
                case CompilerDiagnosticIdentifiers.CS0515_AccessModifiersAreNotAllowedOnStaticConstructors:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.RemoveAccessibility(context, diagnostic, node);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS1609_ModifiersCannotBePlacedOnEventAccessorDeclarations:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifiers(context, diagnostic, node);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0753_OnlyMethodsClassesStructsOrInterfacesMayBePartial:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.PartialKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0441_ClassCannotBeBothStaticAndSealed:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree))
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.StaticKeyword, additionalKey: nameof(SyntaxKind.StaticKeyword));
                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.SealedKeyword, additionalKey: nameof(SyntaxKind.SealedKeyword));
                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0678_FieldCanNotBeBothVolatileAndReadOnly:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree))
                    {
                        break;
                    }

                    var fieldDeclaration = (FieldDeclarationSyntax)node;

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, fieldDeclaration, SyntaxKind.VolatileKeyword, additionalKey: nameof(SyntaxKind.VolatileKeyword));
                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, fieldDeclaration, SyntaxKind.ReadOnlyKeyword, additionalKey: nameof(SyntaxKind.ReadOnlyKeyword));
                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0628_NewProtectedMemberDeclaredInSealedClass:
                case CompilerDiagnosticIdentifiers.CS1057_StaticClassesCannotContainProtectedMembers:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeAccessibility, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternalOrPrivate);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0621_VirtualOrAbstractMembersCannotBePrivate:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveVirtualModifier, context.Document, root.SyntaxTree))
                    {
                        ModifierListInfo modifierInfo = SyntaxInfo.ModifierListInfo(node);

                        if (modifierInfo.IsVirtual)
                        {
                            ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.VirtualKeyword, additionalKey: nameof(SyntaxKind.VirtualKeyword));
                        }
                    }

                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeAccessibility, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternalOrProtected);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0442_AbstractPropertiesCannotHavePrivateAccessors:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.RemoveAccessibility(context, diagnostic, node, additionalKey: CodeFixIdentifiers.RemoveInvalidModifier);
                    }

                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeAccessibility, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternalOrProtected);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0112_StaticMemberCannotBeMarkedOverrideVirtualOrAbstract:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree))
                    {
                        break;
                    }

                    if (!node.IsParentKind(SyntaxKind.ClassDeclaration) ||
                        !((ClassDeclarationSyntax)node.Parent).Modifiers.Contains(SyntaxKind.StaticKeyword))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.StaticKeyword, additionalKey: nameof(SyntaxKind.StaticKeyword));
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.OverrideKeyword, additionalKey: nameof(SyntaxKind.OverrideKeyword));
                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.VirtualKeyword, additionalKey: nameof(SyntaxKind.VirtualKeyword));
                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.AbstractKeyword, additionalKey: nameof(SyntaxKind.AbstractKeyword));
                    break;
                }

                case CompilerDiagnosticIdentifiers.CS1994_AsyncModifierCanOnlyBeUsedInMethodsThatHaveBody:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.AsyncKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0750_PartialMethodCannotHaveAccessModifiersOrVirtualAbstractOverrideNewSealedOrExternModifiers:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree))
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifiers(
                        context,
                        diagnostic,
                        node,
                        f =>
                        {
                            switch (f.Kind())
                            {
                            case SyntaxKind.PublicKeyword:
                            case SyntaxKind.ProtectedKeyword:
                            case SyntaxKind.InternalKeyword:
                            case SyntaxKind.PrivateKeyword:
                            case SyntaxKind.VirtualKeyword:
                            case SyntaxKind.AbstractKeyword:
                            case SyntaxKind.OverrideKeyword:
                            case SyntaxKind.NewKeyword:
                            case SyntaxKind.SealedKeyword:
                            case SyntaxKind.ExternKeyword:
                                {
                                    return(true);
                                }
                            }

                            return(false);
                        });

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS1105_ExtensionMethodMustBeStatic:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier, context.Document, root.SyntaxTree))
                    {
                        AddStaticModifier(context, diagnostic, node, CodeFixIdentifiers.AddStaticModifier);
                    }

                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveThisModifier, context.Document, root.SyntaxTree))
                    {
                        var methodDeclaration = (MethodDeclarationSyntax)node;

                        ParameterSyntax parameter = methodDeclaration.ParameterList.Parameters[0];

                        SyntaxToken modifier = parameter.Modifiers.Find(SyntaxKind.ThisKeyword);

                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, parameter, modifier, additionalKey: CodeFixIdentifiers.RemoveThisModifier);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS1106_ExtensionMethodMustBeDefinedInNonGenericStaticClass:
                {
                    if (node is not ClassDeclarationSyntax classDeclaration)
                    {
                        return;
                    }

                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier, context.Document, root.SyntaxTree) &&
                        !classDeclaration.Modifiers.Contains(SyntaxKind.StaticKeyword))
                    {
                        AddStaticModifier(context, diagnostic, node, CodeFixIdentifiers.AddStaticModifier);
                    }

                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveThisModifier, context.Document, root.SyntaxTree))
                    {
                        IEnumerable <ParameterSyntax> thisParameters = classDeclaration.Members
                                                                       .Where(f => f.IsKind(SyntaxKind.MethodDeclaration))
                                                                       .Cast <MethodDeclarationSyntax>()
                                                                       .Select(f => f.ParameterList?.Parameters.FirstOrDefault())
                                                                       .Where(f => f?.Modifiers.Contains(SyntaxKind.ThisKeyword) == true);

                        ModifiersCodeFixRegistrator.RemoveModifier(
                            context,
                            diagnostic,
                            thisParameters,
                            SyntaxKind.ThisKeyword,
                            title: "Remove 'this' modifier from extension methods",
                            additionalKey: CodeFixIdentifiers.RemoveThisModifier);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0759_NoDefiningDeclarationFoundForImplementingDeclarationOfPartialMethod:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.PartialKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS1100_MethodHasParameterModifierThisWhichIsNotOnFirstParameter:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveThisModifier, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, token.Parent, token);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0708_CannotDeclareInstanceMembersInStaticClass:
                case CompilerDiagnosticIdentifiers.CS0710_StaticClassesCannotHaveInstanceConstructors:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier, context.Document, root.SyntaxTree))
                    {
                        AddStaticModifier(context, diagnostic, node, CodeFixIdentifiers.AddStaticModifier);
                    }

                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeContainingClassNonStatic, context.Document, root.SyntaxTree))
                    {
                        var classDeclaration = (ClassDeclarationSyntax)node.Parent;

                        ModifiersCodeFixRegistrator.RemoveModifier(
                            context,
                            diagnostic,
                            classDeclaration,
                            classDeclaration.Modifiers.Find(SyntaxKind.StaticKeyword),
                            title: "Make containing class non-static",
                            additionalKey: CodeFixIdentifiers.MakeContainingClassNonStatic);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS1527_ElementsDefinedInNamespaceCannotBeExplicitlyDeclaredAsPrivateProtectedOrProtectedInternal:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeAccessibility, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternal);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0101_NamespaceAlreadyContainsDefinition:
                case CompilerDiagnosticIdentifiers.CS0102_TypeAlreadyContainsDefinition:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddPartialModifier, context.Document, root.SyntaxTree))
                    {
                        break;
                    }

                    if (!node.IsKind(
                            SyntaxKind.ClassDeclaration,
                            SyntaxKind.StructDeclaration,
                            SyntaxKind.RecordStructDeclaration,
                            SyntaxKind.InterfaceDeclaration,
                            SyntaxKind.MethodDeclaration))
                    {
                        return;
                    }

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

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

                    ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences;

                    if (syntaxReferences.Length <= 1)
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.AddModifier(
                        context,
                        diagnostic,
                        ImmutableArray.CreateRange(syntaxReferences, f => f.GetSyntax(context.CancellationToken)),
                        SyntaxKind.PartialKeyword,
                        title: $"Make {CSharpFacts.GetTitle(node)} partial");

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0115_NoSuitableMethodFoundToOverride:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.OverrideKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS1988_AsyncMethodsCannotHaveRefOrOutParameters:
                case CompilerDiagnosticIdentifiers.CS1623_IteratorsCannotHaveRefOrOutParameters:
                case CompilerDiagnosticIdentifiers.CS0192_ReadOnlyFieldCannotBePassedAsRefOrOutValue:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveRefModifier, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.RefKeyword, additionalKey: nameof(SyntaxKind.RefKeyword));
                    }

                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveOutModifier, context.Document, root.SyntaxTree))
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.OutKeyword, additionalKey: nameof(SyntaxKind.OutKeyword));
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0573_CannotHaveInstancePropertyOrFieldInitializersInStruct:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier, context.Document, root.SyntaxTree))
                    {
                        AddStaticModifier(context, diagnostic, node);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0501_MemberMustDeclareBodyBecauseItIsNotMarkedAbstractExternOrPartial:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddModifierAbstract, context.Document, root.SyntaxTree) &&
                        node.IsKind(SyntaxKind.MethodDeclaration) &&
                        (node.Parent as ClassDeclarationSyntax)?.Modifiers.Contains(SyntaxKind.AbstractKeyword) == true)
                    {
                        ModifiersCodeFixRegistrator.AddModifier(context, diagnostic, node, SyntaxKind.AbstractKeyword);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0549_NewVirtualMemberInSealedClass:
                {
                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveVirtualModifier, context.Document, root.SyntaxTree))
                    {
                        if (node is AccessorDeclarationSyntax &&
                            SyntaxInfo.ModifierListInfo(node.Parent.Parent).IsVirtual)
                        {
                            node = node.Parent.Parent;
                        }

                        ModifiersCodeFixRegistrator.RemoveModifier(
                            context,
                            diagnostic,
                            node,
                            SyntaxKind.VirtualKeyword,
                            additionalKey: CodeFixIdentifiers.RemoveVirtualModifier);
                    }

                    if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeContainingClassUnsealed, context.Document, root.SyntaxTree) &&
                        node.Parent is ClassDeclarationSyntax classDeclaration)
                    {
                        ModifiersCodeFixRegistrator.RemoveModifier(
                            context,
                            diagnostic,
                            classDeclaration,
                            SyntaxKind.SealedKeyword,
                            title: "Make containing class unsealed",
                            additionalKey: CodeFixIdentifiers.MakeContainingClassUnsealed);
                    }

                    break;
                }

                case CompilerDiagnosticIdentifiers.CS8340_InstanceFieldsOfReadOnlyStructsMustBeReadOnly:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeMemberReadOnly, context.Document, root.SyntaxTree))
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.AddModifier(context, diagnostic, node, SyntaxKind.ReadOnlyKeyword);
                    break;
                }

                case CompilerDiagnosticIdentifiers.CS0238_MemberCannotBeSealedBecauseItIsNotOverride:
                {
                    if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveSealedModifier, context.Document, root.SyntaxTree))
                    {
                        break;
                    }

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

                    if (semanticModel.GetDiagnostic(
                            CompilerDiagnosticIdentifiers.CS0114_MemberHidesInheritedMemberToMakeCurrentMethodOverrideThatImplementationAddOverrideKeyword,
                            CSharpUtility.GetIdentifier(node).Span,
                            context.CancellationToken) != null)
                    {
                        break;
                    }

                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.SealedKeyword);
                    break;
                }
                }
            }
        }