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); }
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); } } }
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); } } }
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; } } } }
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; } } } } }