public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Diagnostic diagnostic = context.Diagnostics[0];

            if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeAccessibility))
            {
                return;
            }

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

            if (!TryFindFirstAncestorOrSelf(
                    root,
                    context.Span,
                    out SyntaxNode node,
                    predicate: CSharpOverriddenSymbolInfo.CanCreate))
            {
                return;
            }

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

            OverriddenSymbolInfo overrideInfo = CSharpOverriddenSymbolInfo.Create(node, semanticModel, context.CancellationToken);

            if (!overrideInfo.Success)
            {
                return;
            }

            Accessibility newAccessibility = overrideInfo.OverriddenSymbol.DeclaredAccessibility;

            CodeAction codeAction = CodeAction.Create(
                $"Change accessibility to '{SyntaxFacts.GetText(newAccessibility)}'",
                cancellationToken =>
            {
                if (node.Kind() == SyntaxKind.VariableDeclarator)
                {
                    node = node.Parent.Parent;
                }

                SyntaxNode newNode;

                if (newAccessibility == Accessibility.Public &&
                    node is AccessorDeclarationSyntax)
                {
                    newNode = SyntaxAccessibility.WithoutExplicitAccessibility(node);
                }
                else
                {
                    newNode = SyntaxAccessibility.WithExplicitAccessibility(node, newAccessibility);
                }

                return(context.Document.ReplaceNodeAsync(node, newNode, cancellationToken));
            },
                GetEquivalenceKey(diagnostic));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
Beispiel #2
0
        public static Task <Document> RefactorAsync(
            Document document,
            ConstructorDeclarationSyntax constructorDeclaration,
            CancellationToken cancellationToken)
        {
            ConstructorDeclarationSyntax newNode = SyntaxAccessibility.WithExplicitAccessibility(constructorDeclaration, Accessibility.Protected);

            return(document.ReplaceNodeAsync(constructorDeclaration, newNode, cancellationToken));
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ChangeAccessibility))
            {
                return;
            }

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

            if (!TryFindFirstAncestorOrSelf(
                    root,
                    context.Span,
                    out SyntaxNode node,
                    predicate: f => OverriddenSymbolInfo.CanCreate(f)))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case CompilerDiagnosticIdentifiers.CannotChangeAccessModifiersWhenOverridingInheritedMember:
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    OverriddenSymbolInfo overrideInfo = OverriddenSymbolInfo.Create(node, semanticModel, context.CancellationToken);

                    if (!overrideInfo.Success)
                    {
                        break;
                    }

                    Accessibility newAccessibility = overrideInfo.OverriddenSymbol.DeclaredAccessibility;

                    CodeAction codeAction = CodeAction.Create(
                        $"Change accessibility to '{SyntaxFacts.GetText(newAccessibility)}'",
                        cancellationToken =>
                        {
                            if (node.Kind() == SyntaxKind.VariableDeclarator)
                            {
                                node = node.Parent.Parent;
                            }

                            SyntaxNode newNode = SyntaxAccessibility.WithExplicitAccessibility(node, newAccessibility);

                            return(context.Document.ReplaceNodeAsync(node, newNode, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }
                }
            }
        }
Beispiel #4
0
        public static Task <Document> RefactorAsync(
            Document document,
            SyntaxNode node,
            Accessibility newAccessibility,
            CancellationToken cancellationToken)
        {
            SyntaxNode newNode = SyntaxAccessibility.WithExplicitAccessibility(node, newAccessibility);

            return(document.ReplaceNodeAsync(node, newNode, cancellationToken));
        }
        public static Task <Document> RefactorAsync(
            Document document,
            MemberDeclarationSyntax memberDeclaration,
            Accessibility accessibility,
            CancellationToken cancellationToken)
        {
            MemberDeclarationSyntax newNode = SyntaxAccessibility.WithExplicitAccessibility(memberDeclaration, accessibility);

            return(document.ReplaceNodeAsync(memberDeclaration, newNode, cancellationToken));
        }
Beispiel #6
0
        public static async Task <Solution> RefactorAsync(
            Solution solution,
            MemberDeclarationListSelection selectedMembers,
            Accessibility newAccessibility,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            var members = new HashSet <MemberDeclarationSyntax>();

            foreach (MemberDeclarationSyntax member in selectedMembers)
            {
                ModifierFilter filter = SyntaxInfo.ModifierListInfo(member).GetFilter();

                if (filter.HasAnyFlag(ModifierFilter.Partial))
                {
                    ISymbol symbol = semanticModel.GetDeclaredSymbol(member, cancellationToken);

                    foreach (SyntaxReference reference in symbol.DeclaringSyntaxReferences)
                    {
                        members.Add((MemberDeclarationSyntax)reference.GetSyntax(cancellationToken));
                    }
                }
                else if (filter.HasAnyFlag(ModifierFilter.AbstractVirtualOverride))
                {
                    ISymbol symbol = GetBaseSymbolOrDefault(member, semanticModel, cancellationToken);

                    if (symbol != null)
                    {
                        foreach (MemberDeclarationSyntax member2 in GetMemberDeclarations(symbol, cancellationToken))
                        {
                            members.Add(member2);
                        }

                        foreach (MemberDeclarationSyntax member2 in await FindOverridingMemberDeclarationsAsync(symbol, solution, cancellationToken).ConfigureAwait(false))
                        {
                            members.Add(member2);
                        }
                    }
                    else
                    {
                        members.Add(member);
                    }
                }
                else
                {
                    members.Add(member);
                }
            }

            return(await solution.ReplaceNodesAsync(
                       members,
                       (node, _) => SyntaxAccessibility.WithExplicitAccessibility(node, newAccessibility),
                       cancellationToken)
                   .ConfigureAwait(false));
        }
Beispiel #7
0
        public static Task <Document> RefactorAsync(
            Document document,
            PropertyDeclarationSyntax propertyDeclaration,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            AccessorListSyntax accessorList = AccessorList();

            if (propertyDeclaration.ExpressionBody != null)
            {
                accessorList = accessorList
                               .AddAccessors(AutoGetAccessorDeclaration());
            }
            else
            {
                AccessorDeclarationSyntax getter = propertyDeclaration.Getter();
                if (getter != null)
                {
                    if (SyntaxAccessibility.GetExplicitAccessibility(getter) == Accessibility.Private)
                    {
                        getter = SyntaxAccessibility.WithExplicitAccessibility(getter, Accessibility.Protected);
                    }

                    accessorList = accessorList.AddAccessors(getter
                                                             .WithBody(null)
                                                             .WithSemicolonToken(SemicolonToken()));
                }

                AccessorDeclarationSyntax setter = propertyDeclaration.Setter();
                if (setter != null)
                {
                    if (SyntaxAccessibility.GetExplicitAccessibility(setter) == Accessibility.Private)
                    {
                        setter = SyntaxAccessibility.WithExplicitAccessibility(setter, Accessibility.Protected);
                    }

                    accessorList = accessorList.AddAccessors(setter
                                                             .WithBody(null)
                                                             .WithSemicolonToken(SemicolonToken()));
                }
            }

            PropertyDeclarationSyntax newNode = propertyDeclaration
                                                .WithExpressionBody(null)
                                                .WithSemicolonToken(default(SyntaxToken))
                                                .WithAccessorList(accessorList)
                                                .InsertModifier(SyntaxKind.AbstractKeyword)
                                                .RemoveModifier(SyntaxKind.VirtualKeyword)
                                                .WithTriviaFrom(propertyDeclaration)
                                                .WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(propertyDeclaration, newNode, cancellationToken));
        }
Beispiel #8
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out MemberDeclarationSyntax memberDeclaration))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case DiagnosticIdentifiers.RemoveRedundantOverridingMember:
                {
                    CodeAction codeAction = CodeActionFactory.RemoveMemberDeclaration(context.Document, memberDeclaration, equivalenceKey: GetEquivalenceKey(diagnostic));

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

                case DiagnosticIdentifiers.AddAccessibilityModifiersOrViceVersa:
                {
                    if (diagnostic.Properties.TryGetValue(nameof(Accessibility), out string accessibilityText))
                    {
                        var accessibility = (Accessibility)Enum.Parse(typeof(Accessibility), accessibilityText);

                        CodeAction codeAction = CodeAction.Create(
                            "Add accessibility modifiers",
                            ct =>
                            {
                                MemberDeclarationSyntax newNode = SyntaxAccessibility.WithExplicitAccessibility(memberDeclaration, accessibility);

                                return(context.Document.ReplaceNodeAsync(memberDeclaration, newNode, ct));
                            },
                            GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                    }
                    else
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Remove accessibility modifiers",
                            ct =>
                            {
                                MemberDeclarationSyntax newNode = SyntaxAccessibility.WithoutExplicitAccessibility(memberDeclaration);

                                return(context.Document.ReplaceNodeAsync(memberDeclaration, newNode, ct));
                            },
                            GetEquivalenceKey(diagnostic));

                        context.RegisterCodeFix(codeAction, diagnostic);
                    }

                    break;
                }

                case DiagnosticIdentifiers.RemoveRedundantSealedModifier:
                {
                    ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, memberDeclaration, SyntaxKind.SealedKeyword);
                    break;
                }

                case DiagnosticIdentifiers.AvoidSemicolonAtEndOfDeclaration:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Remove unnecessary semicolon",
                        cancellationToken => AvoidSemicolonAtEndOfDeclarationRefactoring.RefactorAsync(context.Document, memberDeclaration, cancellationToken),
                        GetEquivalenceKey(diagnostic));

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

                case DiagnosticIdentifiers.OrderModifiers:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Order modifiers",
                        ct => OrderModifiersAsync(context.Document, memberDeclaration, ct),
                        GetEquivalenceKey(diagnostic));

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

                case DiagnosticIdentifiers.MakeFieldReadOnly:
                {
                    var fieldDeclaration = (FieldDeclarationSyntax)memberDeclaration;

                    SeparatedSyntaxList <VariableDeclaratorSyntax> declarators = fieldDeclaration.Declaration.Variables;

                    string title = (declarators.Count == 1)
                                ? $"Make '{declarators[0].Identifier.ValueText}' read-only"
                                : "Make fields read-only";

                    ModifiersCodeFixRegistrator.AddModifier(context, diagnostic, fieldDeclaration, SyntaxKind.ReadOnlyKeyword, title: title);
                    break;
                }

                case DiagnosticIdentifiers.UseConstantInsteadOfField:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Use constant instead of field",
                        cancellationToken => UseConstantInsteadOfFieldRefactoring.RefactorAsync(context.Document, (FieldDeclarationSyntax)memberDeclaration, cancellationToken),
                        GetEquivalenceKey(diagnostic));

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

                case DiagnosticIdentifiers.UseReadOnlyAutoProperty:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Use read-only auto-property",
                        cancellationToken => UseReadOnlyAutoPropertyAsync(context.Document, (PropertyDeclarationSyntax)memberDeclaration, cancellationToken),
                        GetEquivalenceKey(diagnostic));

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

                case DiagnosticIdentifiers.ConvertCommentToDocumentationComment:
                {
                    CodeAction codeAction = CodeAction.Create(
                        ConvertCommentToDocumentationCommentRefactoring.Title,
                        cancellationToken => ConvertCommentToDocumentationCommentRefactoring.RefactorAsync(context.Document, memberDeclaration, context.Span, cancellationToken),
                        GetEquivalenceKey(diagnostic));

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

                case DiagnosticIdentifiers.MakeMethodExtensionMethod:
                {
                    var methodDeclaration = (MethodDeclarationSyntax)memberDeclaration;

                    CodeAction codeAction = CodeAction.Create(
                        "Make method an extension method",
                        cancellationToken =>
                        {
                            ParameterSyntax parameter = methodDeclaration.ParameterList.Parameters[0];

                            ParameterSyntax newParameter = ModifierList.Insert(parameter, SyntaxKind.ThisKeyword);

                            return(context.Document.ReplaceNodeAsync(parameter, newParameter, cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }
                }
            }
        }
Beispiel #9
0
        public static Task <Document> RefactorAsync(
            Document document,
            MemberDeclarationListSelection selectedMembers,
            Accessibility newAccessibility,
            CancellationToken cancellationToken)
        {
            SyntaxList <MemberDeclarationSyntax> newMembers = selectedMembers
                                                              .UnderlyingList
                                                              .ReplaceRange(selectedMembers.FirstIndex, selectedMembers.Count, selectedMembers.Select(f => SyntaxAccessibility.WithExplicitAccessibility(f, newAccessibility)));

            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(selectedMembers);

            return(document.ReplaceMembersAsync(info, newMembers, cancellationToken));
        }