static void AnalyzeStatement(SyntaxNodeAnalysisContext context) { var switchStatement = (SwitchStatementSyntax)context.Node; var semanticModel = context.SemanticModel; if (!SwitchAnalysis.TryAnalyze(switchStatement, semanticModel, out var analysis)) { return; } if (analysis.IsAllFound) { return; } context.ReportDiagnostic( Diagnostic.Create( Rule, switchStatement.SwitchKeyword.GetLocation(), string.Join(", ", analysis.MissingEnumMembers.Select(c => $"'{c.Name}'")) )); }
public static bool TryAnalyze(SwitchStatementSyntax switchStatement, SemanticModel semanticModel, out SwitchAnalysis analysis) { analysis = default; if (switchStatement.Expression == null) { return(false); } var typeSymbol = semanticModel.GetTypeInfo(switchStatement.Expression).Type; if (typeSymbol == null || typeSymbol.TypeKind != TypeKind.Enum) { return(false); } AnalyzeSections(switchStatement, semanticModel, out var foundEnumMembers, out var defaultSectionOrNull); var enumMembers = typeSymbol .GetMembers() .OfType <IFieldSymbol>() .Where(symbol => symbol.IsConst) .OrderBy(symbol => symbol.ConstantValue) .Select(symbol => new EnumMember(symbol, foundEnumMembers.Contains(symbol))) .ToImmutableArray(); analysis = new SwitchAnalysis( switchStatement, semanticModel, defaultSectionOrNull, typeSymbol, enumMembers ); return(true); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var ct = context.CancellationToken; var diagnostic = context.Diagnostics.FirstOrDefault(); if (diagnostic == null) { return; } var diagnosticSpan = diagnostic.Location.SourceSpan; var root = await context.Document.GetSyntaxRootAsync(ct).ConfigureAwait(false); if (root == null) { return; } var switchStatement = root .FindToken(diagnosticSpan.Start) .Parent .AncestorsAndSelf() .OfType <SwitchStatementSyntax>() .FirstOrDefault(); if (switchStatement == null) { return; } var semanticModel = await context.Document.GetSemanticModelAsync(ct); if (semanticModel == null) { return; } if (!SwitchAnalysis.TryAnalyze(switchStatement, semanticModel, out var analysis)) { return; } if (analysis.IsAllFound) { return; } context.RegisterCodeFix( CodeAction.Create( diagnostic.Descriptor.Title.ToString(), _ => Task.FromResult( context.Document.WithSyntaxRoot( root.ReplaceNode( switchStatement, analysis.Fix() ))), equivalenceKey: diagnostic.GetMessage() ), diagnostic ); }