Example #1
0
        public static void RemoveModifier <TNode>(
            CodeFixContext context,
            Diagnostic diagnostic,
            IEnumerable <TNode> nodes,
            SyntaxKind modifierKind,
            string title         = null,
            string additionalKey = null) where TNode : SyntaxNode
        {
            if (nodes is IList <TNode> list)
            {
                if (list.Count == 0)
                {
                    return;
                }

                if (list.Count == 1)
                {
                    RemoveModifier(context, diagnostic, list[0], modifierKind, title, additionalKey);
                    return;
                }
            }

            CodeAction codeAction = CodeAction.Create(
                title ?? GetRemoveModifierTitle(modifierKind),
                cancellationToken =>
            {
                return(context.Solution().ReplaceNodesAsync(
                           nodes,
                           (f, _) => Modifier.Remove(f, modifierKind),
                           cancellationToken));
            },
                GetEquivalenceKey(diagnostic, additionalKey));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
Example #2
0
        public static void AddModifier <TNode>(
            CodeFixContext context,
            Diagnostic diagnostic,
            IEnumerable <TNode> nodes,
            SyntaxKind kind,
            string title               = null,
            string additionalKey       = null,
            IModifierComparer comparer = null) where TNode : SyntaxNode
        {
            if (nodes is IList <TNode> list &&
                list.Count == 1)
            {
                AddModifier(context, diagnostic, list[0], kind, title, additionalKey, comparer);
                return;
            }

            CodeAction codeAction = CodeAction.Create(
                title ?? GetAddModifierTitle(kind),
                cancellationToken =>
            {
                return(context.Solution().ReplaceNodesAsync(
                           nodes,
                           (f, g) => AddModifier(f, kind, comparer),
                           cancellationToken));
            },
                GetEquivalenceKey(diagnostic, additionalKey));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
        private void AddStaticModifier(
            CodeFixContext context,
            Diagnostic diagnostic,
            SyntaxNode node,
            SemanticModel semanticModel)
        {
            ISymbol symbol = semanticModel.GetSymbol(node, context.CancellationToken);

            if (symbol == null)
            {
                return;
            }

            SyntaxNode syntax = symbol.GetSyntaxOrDefault(context.CancellationToken);

            if (syntax == null)
            {
                return;
            }

            if (syntax.Kind() == SyntaxKind.VariableDeclarator)
            {
                syntax = syntax.Parent?.Parent;
            }

            Debug.Assert(syntax.IsKind(SyntaxKind.EventDeclaration, SyntaxKind.EventFieldDeclaration, SyntaxKind.FieldDeclaration, SyntaxKind.MethodDeclaration, SyntaxKind.PropertyDeclaration), syntax.ToString());

            if (!(syntax is MemberDeclarationSyntax memberDeclaration))
            {
                return;
            }

            if (memberDeclaration.GetModifiers().Contains(SyntaxKind.StaticKeyword))
            {
                return;
            }

            Document document = context.Document;

            SyntaxTree tree = memberDeclaration.SyntaxTree;

            if (tree != node.SyntaxTree)
            {
                document = context.Solution().GetDocument(tree);
            }

            ModifiersCodeFixRegistrator.AddModifier(
                context,
                document,
                diagnostic,
                memberDeclaration,
                SyntaxKind.StaticKeyword,
                title: $"Make '{symbol.Name}' static",
                additionalKey: CodeFixIdentifiers.AddStaticModifier);
        }
        private void AddPartialModifier(CodeFixContext context, Diagnostic diagnostic, ImmutableArray <SyntaxNode> nodes)
        {
            CodeAction codeAction = CodeAction.Create(
                "Add 'partial' modifier",
                cancellationToken =>
            {
                return(context.Solution().ReplaceNodesAsync(
                           nodes,
                           (f, g) => f.InsertModifier(SyntaxKind.PartialKeyword, ModifierComparer.Instance),
                           cancellationToken));
            },
                GetEquivalenceKey(diagnostic));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Diagnostic diagnostic = context.Diagnostics[0];

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

            if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.SynchronizeAccessibility, context.Document, root.SyntaxTree))
            {
                return;
            }

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

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

            var symbol = (INamedTypeSymbol)semanticModel.GetDeclaredSymbol(memberDeclaration, context.CancellationToken);

            ImmutableArray <MemberDeclarationSyntax> memberDeclarations = ImmutableArray.CreateRange(
                symbol.DeclaringSyntaxReferences,
                f => (MemberDeclarationSyntax)f.GetSyntax(context.CancellationToken));

            foreach (Accessibility accessibility in memberDeclarations
                     .Select(f => SyntaxAccessibility.GetExplicitAccessibility(f))
                     .Where(f => f != Accessibility.NotApplicable))
            {
                if (SyntaxAccessibility.IsValidAccessibility(memberDeclaration, accessibility))
                {
                    CodeAction codeAction = CodeAction.Create(
                        $"Change accessibility to '{SyntaxFacts.GetText(accessibility)}'",
                        ct => ChangeAccessibilityRefactoring.RefactorAsync(context.Solution(), memberDeclarations, accessibility, ct),
                        GetEquivalenceKey(CompilerDiagnosticIdentifiers.CS0262_PartialDeclarationsHaveConflictingAccessibilityModifiers, accessibility.ToString()));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }
            }
        }
Example #6
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.SynchronizeAccessibility))
            {
                return;
            }

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

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

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

            if (memberDeclaration == null)
            {
                return;
            }

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

            var symbol = (INamedTypeSymbol)semanticModel.GetDeclaredSymbol(memberDeclaration, context.CancellationToken);

            ImmutableArray <MemberDeclarationSyntax> memberDeclarations = ImmutableArray.CreateRange(
                symbol.DeclaringSyntaxReferences,
                f => (MemberDeclarationSyntax)f.GetSyntax(context.CancellationToken));

            foreach (Accessibility accessibility in memberDeclarations
                     .Select(f => f.GetModifiers().GetAccessibility())
                     .Where(f => f != Accessibility.NotApplicable))
            {
                if (AccessibilityHelper.IsAllowedAccessibility(memberDeclaration, accessibility))
                {
                    CodeAction codeAction = CodeAction.Create(
                        $"Change accessibility to '{AccessibilityHelper.GetAccessibilityName(accessibility)}'",
                        cancellationToken => ChangeAccessibilityRefactoring.RefactorAsync(context.Solution(), memberDeclarations, accessibility, cancellationToken),
                        GetEquivalenceKey(CompilerDiagnosticIdentifiers.PartialDeclarationsHaveConfictingAccessibilityModifiers, accessibility.ToString()));

                    context.RegisterCodeFix(codeAction, context.Diagnostics);
                }
            }
        }
Example #7
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

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

            if (methodDeclaration == null)
            {
                return;
            }

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

            IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken);

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

            if (methodSymbol != null)
            {
                foreach (Diagnostic diagnostic in context.Diagnostics)
                {
                    switch (diagnostic.Id)
                    {
                    case DiagnosticIdentifiers.AsynchronousMethodNameShouldEndWithAsync:
                    {
                        string oldName = methodDeclaration.Identifier.ValueText;

                        string newName = await NameGenerators.AsyncMethod.EnsureUniqueMemberNameAsync(
                            oldName,
                            methodSymbol,
                            context.Solution(),
                            cancellationToken : context.CancellationToken).ConfigureAwait(false);

                        CodeAction codeAction = CodeAction.Create(
                            $"Rename '{oldName}' to '{newName}'",
                            c => Renamer.RenameSymbolAsync(context.Solution(), methodSymbol, newName, default(OptionSet), c),
                            diagnostic.Id + EquivalenceKeySuffix);

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

                    case DiagnosticIdentifiers.AddReturnStatementThatReturnsDefaultValue:
                    {
                        CodeAction codeAction = CodeAction.Create(
                            "Add return statement that returns default value",
                            c => AddReturnStatementThatReturnsDefaultValueRefactoring.RefactorAsync(context.Document, methodDeclaration, c),
                            diagnostic.Id + EquivalenceKeySuffix);

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

                    case DiagnosticIdentifiers.NonAsynchronousMethodNameShouldNotEndWithAsync:
                    {
                        string name    = methodDeclaration.Identifier.ValueText;
                        string newName = name.Remove(name.Length - AsyncSuffix.Length);

                        newName = await NameGenerator.Default.EnsureUniqueMemberNameAsync(
                            newName,
                            methodSymbol,
                            context.Solution(),
                            cancellationToken : context.CancellationToken).ConfigureAwait(false);

                        CodeAction codeAction = CodeAction.Create(
                            $"Rename '{name}' to '{newName}'",
                            c => Renamer.RenameSymbolAsync(context.Solution(), methodSymbol, newName, default(OptionSet), c),
                            diagnostic.Id + EquivalenceKeySuffix);

                        context.RegisterCodeFix(codeAction, diagnostic);
                        break;
                    }
                    }
                }
            }
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out ClassDeclarationSyntax classDeclaration))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case DiagnosticIdentifiers.MakeClassStatic:
                {
                    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(
                            $"Make '{classDeclaration.Identifier.ValueText}' static",
                            cancellationToken =>
                            {
                                return(MakeClassStaticRefactoring.RefactorAsync(
                                           context.Document,
                                           classDeclaration,
                                           cancellationToken));
                            },
                            GetEquivalenceKey(diagnostic));
                    }
                    else
                    {
                        ImmutableArray <ClassDeclarationSyntax> classDeclarations = syntaxReferences
                                                                                    .Select(f => (ClassDeclarationSyntax)f.GetSyntax(context.CancellationToken))
                                                                                    .ToImmutableArray();

                        codeAction = CodeAction.Create(
                            $"Make '{classDeclaration.Identifier.ValueText}' static",
                            cancellationToken =>
                            {
                                return(MakeClassStaticRefactoring.RefactorAsync(
                                           context.Solution(),
                                           classDeclarations,
                                           cancellationToken));
                            },
                            GetEquivalenceKey(diagnostic));
                    }

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

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

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

                case DiagnosticIdentifiers.ImplementExceptionConstructors:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Generate exception constructors",
                        cancellationToken =>
                        {
                            return(ImplementExceptionConstructorsRefactoring.RefactorAsync(
                                       context.Document,
                                       classDeclaration,
                                       cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

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

                case DiagnosticIdentifiers.UseAttributeUsageAttribute:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Use AttributeUsageAttribute",
                        cancellationToken =>
                        {
                            return(UseAttributeUsageAttributeRefactoring.RefactorAsync(
                                       context.Document,
                                       classDeclaration,
                                       cancellationToken));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }
                }
            }
        }
Example #9
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;
                }
                }
            }
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out MethodDeclarationSyntax methodDeclaration))
            {
                return;
            }

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

            IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken);

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

            if (methodSymbol != null)
            {
                foreach (Diagnostic diagnostic in context.Diagnostics)
                {
                    switch (diagnostic.Id)
                    {
                    case DiagnosticIdentifiers.AsynchronousMethodNameShouldEndWithAsync:
                    {
                        string oldName = methodDeclaration.Identifier.ValueText;

                        string newName = await WorkspaceNameGenerator.EnsureUniqueMemberNameAsync(
                            oldName,
                            methodSymbol,
                            context.Solution(),
                            NameGenerators.AsyncMethod,
                            cancellationToken : context.CancellationToken).ConfigureAwait(false);

                        CodeAction codeAction = CodeAction.Create(
                            $"Rename '{oldName}' to '{newName}'",
                            c => Renamer.RenameSymbolAsync(context.Solution(), methodSymbol, newName, default(OptionSet), c),
                            GetEquivalenceKey(diagnostic));

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

                    case DiagnosticIdentifiers.NonAsynchronousMethodNameShouldNotEndWithAsync:
                    {
                        string name    = methodDeclaration.Identifier.ValueText;
                        string newName = name.Remove(name.Length - AsyncSuffix.Length);

                        newName = await WorkspaceNameGenerator.EnsureUniqueMemberNameAsync(
                            newName,
                            methodSymbol,
                            context.Solution(),
                            NameGenerator.Default,
                            cancellationToken : context.CancellationToken).ConfigureAwait(false);

                        CodeAction codeAction = CodeAction.Create(
                            $"Rename '{name}' to '{newName}'",
                            c => Renamer.RenameSymbolAsync(context.Solution(), methodSymbol, newName, default(OptionSet), c),
                            GetEquivalenceKey(diagnostic));

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