public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.Document .GetSyntaxRootAsync(context.CancellationToken) .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 = CodeAction.Create( "Mark class as static", cancellationToken => { return(MarkClassAsStaticRefactoring.RefactorAsync( context.Document, classDeclaration, cancellationToken)); }, diagnostic.Id + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, diagnostic); break; } case DiagnosticIdentifiers.AddStaticModifierToAllPartialClassDeclarations: { CodeAction codeAction = CodeAction.Create( "Add static modifier", cancellationToken => { return(AddModifierRefactoring.RefactorAsync( context.Document, classDeclaration, SyntaxKind.StaticKeyword, cancellationToken)); }, diagnostic.Id + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, diagnostic); break; } } } }
private void AnalyzeNamedType(SymbolAnalysisContext context) { var symbol = (INamedTypeSymbol)context.Symbol; RemovePartialModifierFromTypeWithSinglePartRefactoring.Analyze(context, symbol); MarkClassAsStaticRefactoring.Analyze(context, symbol); AddStaticModifierToAllPartialClassDeclarationsRefactoring.Analyze(context, symbol); DeclareTypeInsideNamespaceRefactoring.Analyze(context, symbol); }
private void AnalyzeNamedType(SymbolAnalysisContext context) { if (GeneratedCodeAnalyzer?.IsGeneratedCode(context) == true) { return; } var symbol = (INamedTypeSymbol)context.Symbol; TypeKind kind = symbol.TypeKind; if (kind == TypeKind.Class || kind == TypeKind.Struct || kind == TypeKind.Interface) { ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences; if (syntaxReferences.Length == 1) { var declaration = syntaxReferences[0].GetSyntax(context.CancellationToken) as MemberDeclarationSyntax; if (declaration != null) { SyntaxToken partialToken = declaration.GetModifiers() .FirstOrDefault(f => f.IsKind(SyntaxKind.PartialKeyword)); if (partialToken.IsKind(SyntaxKind.PartialKeyword)) { context.ReportDiagnostic( DiagnosticDescriptors.RemovePartialModifierFromTypeWithSinglePart, partialToken.GetLocation()); } } } } if (MarkClassAsStaticRefactoring.CanRefactor(symbol)) { foreach (SyntaxReference syntaxReference in symbol.DeclaringSyntaxReferences) { var classDeclaration = syntaxReference.GetSyntax(context.CancellationToken) as ClassDeclarationSyntax; if (classDeclaration?.Modifiers.Contains(SyntaxKind.StaticKeyword) == false) { context.ReportDiagnostic( DiagnosticDescriptors.MarkClassAsStatic, classDeclaration.Identifier.GetLocation()); break; } } } if (kind == TypeKind.Class && symbol.IsStatic && !symbol.IsImplicitClass && !symbol.IsImplicitlyDeclared) { ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences; if (syntaxReferences.Length > 1) { bool isStatic = false; List <ClassDeclarationSyntax> classDeclarations = null; foreach (SyntaxReference syntaxReference in syntaxReferences) { SyntaxNode node = syntaxReference.GetSyntax(context.CancellationToken); Debug.Assert(node.IsKind(SyntaxKind.ClassDeclaration), node.Kind().ToString()); if (node.IsKind(SyntaxKind.ClassDeclaration)) { var classDeclaration = (ClassDeclarationSyntax)node; SyntaxTokenList modifiers = classDeclaration.Modifiers; if (modifiers.Contains(SyntaxKind.StaticKeyword)) { isStatic = true; } else if (!classDeclaration.ContainsDirectives(modifiers.Span)) { if (classDeclarations == null) { classDeclarations = new List <ClassDeclarationSyntax>(); } classDeclarations.Add(classDeclaration); } } } if (isStatic && classDeclarations != null) { foreach (ClassDeclarationSyntax classDeclaration in classDeclarations) { context.ReportDiagnostic( DiagnosticDescriptors.AddStaticModifierToAllPartialClassDeclarations, classDeclaration.Identifier.GetLocation()); } } } } if (symbol.ContainingNamespace?.IsGlobalNamespace == true) { ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences; foreach (SyntaxReference syntaxReference in syntaxReferences) { SyntaxNode node = syntaxReference.GetSyntax(context.CancellationToken); if (node != null) { SyntaxToken identifier = GetDeclarationIdentifier(kind, node); if (!identifier.IsKind(SyntaxKind.None)) { context.ReportDiagnostic( DiagnosticDescriptors.DeclareTypeInsideNamespace, identifier.GetLocation(), identifier.ValueText); } } } } }
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; } } } }