public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out DestructorDeclarationSyntax destructor)) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case DiagnosticIdentifiers.RemoveEmptyDestructor: { CodeAction codeAction = CodeActionFactory.RemoveMemberDeclaration( context.Document, destructor, title: "Remove empty destructor", equivalenceKey: GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } } } }
public static void RemoveMemberDeclaration( CodeFixContext context, Diagnostic diagnostic, MemberDeclarationSyntax memberDeclaration, string additionalKey = null) { CodeAction codeAction = CodeActionFactory.RemoveMemberDeclaration(context.Document, memberDeclaration, equivalenceKey: EquivalenceKey.Create(diagnostic, additionalKey)); context.RegisterCodeFix(codeAction, diagnostic); }
public override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out ConstructorDeclarationSyntax constructor)) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case DiagnosticIdentifiers.RemoveRedundantBaseConstructorCall: { CodeAction codeAction = CodeAction.Create( "Remove redundant base constructor call", cancellationToken => RemoveRedundantBaseConstructorCallRefactoring.RefactorAsync(context.Document, constructor, cancellationToken), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case DiagnosticIdentifiers.RemoveRedundantConstructor: { CodeAction codeAction = CodeActionFactory.RemoveMemberDeclaration( context.Document, constructor, title: "Remove redundant constructor", equivalenceKey: GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case DiagnosticIdentifiers.AbstractTypeShouldNotHavePublicConstructors: { CodeAction codeAction = CodeAction.Create( "Change accessibility to 'protected'", cancellationToken => AbstractTypeShouldNotHavePublicConstructorsRefactoring.RefactorAsync(context.Document, constructor, cancellationToken), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, MemberDeclarationSyntax member) { SyntaxKind kind = member.Kind(); switch (kind) { case SyntaxKind.MethodDeclaration: case SyntaxKind.IndexerDeclaration: case SyntaxKind.PropertyDeclaration: case SyntaxKind.OperatorDeclaration: case SyntaxKind.ConversionOperatorDeclaration: case SyntaxKind.ConstructorDeclaration: case SyntaxKind.EventDeclaration: case SyntaxKind.NamespaceDeclaration: case SyntaxKind.ClassDeclaration: case SyntaxKind.StructDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.EnumDeclaration: { if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.RemoveMember, RefactoringIdentifiers.DuplicateMember, RefactoringIdentifiers.CommentOutMember) && BraceContainsSpan(member, context.Span)) { if (member.IsParentKind( SyntaxKind.NamespaceDeclaration, SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration, SyntaxKind.CompilationUnit)) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveMember)) { context.RegisterRefactoring(CodeActionFactory.RemoveMemberDeclaration(context.Document, member, equivalenceKey: RefactoringIdentifiers.RemoveMember)); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.DuplicateMember)) { context.RegisterRefactoring( $"Duplicate {CSharpFacts.GetTitle(member)}", cancellationToken => DuplicateMemberDeclarationRefactoring.RefactorAsync(context.Document, member, cancellationToken), RefactoringIdentifiers.DuplicateMember); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.CommentOutMember)) { CommentOutRefactoring.RegisterRefactoring(context, member); } } break; } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveAllStatements)) { RemoveAllStatementsRefactoring.ComputeRefactoring(context, member); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveAllMemberDeclarations)) { RemoveAllMemberDeclarationsRefactoring.ComputeRefactoring(context, member); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.SwapMemberDeclarations, RefactoringIdentifiers.RemoveMemberDeclarations) && !member.Span.IntersectsWith(context.Span)) { MemberDeclarationsRefactoring.ComputeRefactoring(context, member); } switch (kind) { case SyntaxKind.NamespaceDeclaration: { var namespaceDeclaration = (NamespaceDeclarationSyntax)member; NamespaceDeclarationRefactoring.ComputeRefactorings(context, namespaceDeclaration); if (MemberDeclarationListSelection.TryCreate(namespaceDeclaration, context.Span, out MemberDeclarationListSelection selectedMembers)) { await SelectedMemberDeclarationsRefactoring.ComputeRefactoringAsync(context, selectedMembers).ConfigureAwait(false); } break; } case SyntaxKind.ClassDeclaration: { var classDeclaration = (ClassDeclarationSyntax)member; await ClassDeclarationRefactoring.ComputeRefactoringsAsync(context, classDeclaration).ConfigureAwait(false); if (MemberDeclarationListSelection.TryCreate(classDeclaration, context.Span, out MemberDeclarationListSelection selectedMembers)) { await SelectedMemberDeclarationsRefactoring.ComputeRefactoringAsync(context, selectedMembers).ConfigureAwait(false); } break; } case SyntaxKind.StructDeclaration: { var structDeclaration = (StructDeclarationSyntax)member; await StructDeclarationRefactoring.ComputeRefactoringsAsync(context, structDeclaration).ConfigureAwait(false); if (MemberDeclarationListSelection.TryCreate(structDeclaration, context.Span, out MemberDeclarationListSelection selectedMembers)) { await SelectedMemberDeclarationsRefactoring.ComputeRefactoringAsync(context, selectedMembers).ConfigureAwait(false); } break; } case SyntaxKind.InterfaceDeclaration: { var interfaceDeclaration = (InterfaceDeclarationSyntax)member; InterfaceDeclarationRefactoring.ComputeRefactorings(context, interfaceDeclaration); if (MemberDeclarationListSelection.TryCreate(interfaceDeclaration, context.Span, out MemberDeclarationListSelection selectedMembers)) { await SelectedMemberDeclarationsRefactoring.ComputeRefactoringAsync(context, selectedMembers).ConfigureAwait(false); } break; } case SyntaxKind.EnumDeclaration: { await EnumDeclarationRefactoring.ComputeRefactoringAsync(context, (EnumDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.EnumMemberDeclaration: { await EnumMemberDeclarationRefactoring.ComputeRefactoringAsync(context, (EnumMemberDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.DelegateDeclaration: { DelegateDeclarationRefactoring.ComputeRefactorings(context, (DelegateDeclarationSyntax)member); break; } case SyntaxKind.MethodDeclaration: { await MethodDeclarationRefactoring.ComputeRefactoringsAsync(context, (MethodDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.ConstructorDeclaration: { await ConstructorDeclarationRefactoring.ComputeRefactoringsAsync(context, (ConstructorDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.DestructorDeclaration: { DestructorDeclarationRefactoring.ComputeRefactorings(context, (DestructorDeclarationSyntax)member); break; } case SyntaxKind.IndexerDeclaration: { await IndexerDeclarationRefactoring.ComputeRefactoringsAsync(context, (IndexerDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.PropertyDeclaration: { await PropertyDeclarationRefactoring.ComputeRefactoringsAsync(context, (PropertyDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.OperatorDeclaration: { ComputeRefactorings(context, (OperatorDeclarationSyntax)member); break; } case SyntaxKind.ConversionOperatorDeclaration: { ComputeRefactorings(context, (ConversionOperatorDeclarationSyntax)member); break; } case SyntaxKind.FieldDeclaration: { await FieldDeclarationRefactoring.ComputeRefactoringsAsync(context, (FieldDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.EventDeclaration: { await EventDeclarationRefactoring.ComputeRefactoringsAsync(context, (EventDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.EventFieldDeclaration: { await EventFieldDeclarationRefactoring.ComputeRefactoringsAsync(context, (EventFieldDeclarationSyntax)member).ConfigureAwait(false); break; } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.MoveUnsafeContextToContainingDeclaration)) { MoveUnsafeContextToContainingDeclarationRefactoring.ComputeRefactoring(context, member); } }
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; } } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, MemberDeclarationSyntax member) { SyntaxKind kind = member.Kind(); switch (kind) { case SyntaxKind.MethodDeclaration: case SyntaxKind.IndexerDeclaration: case SyntaxKind.PropertyDeclaration: case SyntaxKind.OperatorDeclaration: case SyntaxKind.ConversionOperatorDeclaration: case SyntaxKind.ConstructorDeclaration: case SyntaxKind.EventDeclaration: case SyntaxKind.NamespaceDeclaration: case SyntaxKind.ClassDeclaration: case SyntaxKind.RecordDeclaration: case SyntaxKind.StructDeclaration: case SyntaxKind.RecordStructDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.EnumDeclaration: { if (context.IsAnyRefactoringEnabled( RefactoringDescriptors.RemoveMemberDeclaration, RefactoringDescriptors.CopyMemberDeclaration, RefactoringDescriptors.CommentOutMemberDeclaration)) { (SyntaxToken openBrace, SyntaxToken closeBrace) = GetBraces(member); if ((!openBrace.IsKind(SyntaxKind.None) && openBrace.Span.Contains(context.Span)) || (!closeBrace.IsKind(SyntaxKind.None) && closeBrace.Span.Contains(context.Span))) { if (member.Parent != null && CSharpFacts.CanHaveMembers(member.Parent.Kind())) { if (context.IsRefactoringEnabled(RefactoringDescriptors.RemoveMemberDeclaration)) { context.RegisterRefactoring(CodeActionFactory.RemoveMemberDeclaration(context.Document, member, equivalenceKey: EquivalenceKey.Create(RefactoringDescriptors.RemoveMemberDeclaration))); } if (context.IsRefactoringEnabled(RefactoringDescriptors.CopyMemberDeclaration)) { context.RegisterRefactoring( $"Copy {CSharpFacts.GetTitle(member)}", ct => CopyMemberDeclarationRefactoring.RefactorAsync( context.Document, member, copyAfter: closeBrace.Span.Contains(context.Span), ct), RefactoringDescriptors.CopyMemberDeclaration); } } if (context.IsRefactoringEnabled(RefactoringDescriptors.CommentOutMemberDeclaration)) { CommentOutRefactoring.RegisterRefactoring(context, member); } } } break; } } if (context.IsRefactoringEnabled(RefactoringDescriptors.RemoveAllStatements)) { RemoveAllStatementsRefactoring.ComputeRefactoring(context, member); } if (context.IsRefactoringEnabled(RefactoringDescriptors.RemoveAllMemberDeclarations)) { RemoveAllMemberDeclarationsRefactoring.ComputeRefactoring(context, member); } if (context.IsAnyRefactoringEnabled( RefactoringDescriptors.SwapMemberDeclarations, RefactoringDescriptors.RemoveMemberDeclarations) && !member.Span.IntersectsWith(context.Span)) { MemberDeclarationsRefactoring.ComputeRefactoring(context, member); } switch (kind) { case SyntaxKind.NamespaceDeclaration: { var namespaceDeclaration = (NamespaceDeclarationSyntax)member; NamespaceDeclarationRefactoring.ComputeRefactorings(context, namespaceDeclaration); if (MemberDeclarationListSelection.TryCreate(namespaceDeclaration, context.Span, out MemberDeclarationListSelection selectedMembers)) { await SelectedMemberDeclarationsRefactoring.ComputeRefactoringAsync(context, selectedMembers).ConfigureAwait(false); } break; } case SyntaxKind.ClassDeclaration: { var classDeclaration = (ClassDeclarationSyntax)member; await ClassDeclarationRefactoring.ComputeRefactoringsAsync(context, classDeclaration).ConfigureAwait(false); if (MemberDeclarationListSelection.TryCreate(classDeclaration, context.Span, out MemberDeclarationListSelection selectedMembers)) { await SelectedMemberDeclarationsRefactoring.ComputeRefactoringAsync(context, selectedMembers).ConfigureAwait(false); } break; } case SyntaxKind.RecordDeclaration: case SyntaxKind.RecordStructDeclaration: { var recordDeclaration = (RecordDeclarationSyntax)member; await RecordDeclarationRefactoring.ComputeRefactoringsAsync(context, recordDeclaration).ConfigureAwait(false); if (MemberDeclarationListSelection.TryCreate(recordDeclaration, context.Span, out MemberDeclarationListSelection selectedMembers)) { await SelectedMemberDeclarationsRefactoring.ComputeRefactoringAsync(context, selectedMembers).ConfigureAwait(false); } break; } case SyntaxKind.StructDeclaration: { var structDeclaration = (StructDeclarationSyntax)member; await StructDeclarationRefactoring.ComputeRefactoringsAsync(context, structDeclaration).ConfigureAwait(false); if (MemberDeclarationListSelection.TryCreate(structDeclaration, context.Span, out MemberDeclarationListSelection selectedMembers)) { await SelectedMemberDeclarationsRefactoring.ComputeRefactoringAsync(context, selectedMembers).ConfigureAwait(false); } break; } case SyntaxKind.InterfaceDeclaration: { var interfaceDeclaration = (InterfaceDeclarationSyntax)member; InterfaceDeclarationRefactoring.ComputeRefactorings(context, interfaceDeclaration); if (MemberDeclarationListSelection.TryCreate(interfaceDeclaration, context.Span, out MemberDeclarationListSelection selectedMembers)) { await SelectedMemberDeclarationsRefactoring.ComputeRefactoringAsync(context, selectedMembers).ConfigureAwait(false); } break; } case SyntaxKind.EnumDeclaration: { await EnumDeclarationRefactoring.ComputeRefactoringAsync(context, (EnumDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.EnumMemberDeclaration: { await EnumMemberDeclarationRefactoring.ComputeRefactoringAsync(context, (EnumMemberDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.DelegateDeclaration: { DelegateDeclarationRefactoring.ComputeRefactorings(context, (DelegateDeclarationSyntax)member); break; } case SyntaxKind.MethodDeclaration: { await MethodDeclarationRefactoring.ComputeRefactoringsAsync(context, (MethodDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.ConstructorDeclaration: { await ConstructorDeclarationRefactoring.ComputeRefactoringsAsync(context, (ConstructorDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.DestructorDeclaration: { DestructorDeclarationRefactoring.ComputeRefactorings(context, (DestructorDeclarationSyntax)member); break; } case SyntaxKind.IndexerDeclaration: { await IndexerDeclarationRefactoring.ComputeRefactoringsAsync(context, (IndexerDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.PropertyDeclaration: { await PropertyDeclarationRefactoring.ComputeRefactoringsAsync(context, (PropertyDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.OperatorDeclaration: { ComputeRefactorings(context, (OperatorDeclarationSyntax)member); break; } case SyntaxKind.ConversionOperatorDeclaration: { ComputeRefactorings(context, (ConversionOperatorDeclarationSyntax)member); break; } case SyntaxKind.FieldDeclaration: { await FieldDeclarationRefactoring.ComputeRefactoringsAsync(context, (FieldDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.EventDeclaration: { await EventDeclarationRefactoring.ComputeRefactoringsAsync(context, (EventDeclarationSyntax)member).ConfigureAwait(false); break; } case SyntaxKind.EventFieldDeclaration: { await EventFieldDeclarationRefactoring.ComputeRefactoringsAsync(context, (EventFieldDeclarationSyntax)member).ConfigureAwait(false); break; } } if (context.IsRefactoringEnabled(RefactoringDescriptors.MoveUnsafeContextToContainingDeclaration)) { MoveUnsafeContextToContainingDeclarationRefactoring.ComputeRefactoring(context, member); } }