Cleanup analyzers

This commit is contained in:
Tyrrrz
2020-10-23 18:23:58 +03:00
parent d52a205f13
commit c06f2810b9

View File

@@ -18,55 +18,49 @@ namespace CliFx.Analyzers
SyntaxNodeAnalysisContext context, SyntaxNodeAnalysisContext context,
InvocationExpressionSyntax invocationSyntax) InvocationExpressionSyntax invocationSyntax)
{ {
// Get the method member access (Console.WriteLine or Console.Error.WriteLine) if (invocationSyntax.Expression is MemberAccessExpressionSyntax memberAccessSyntax &&
if (!(invocationSyntax.Expression is MemberAccessExpressionSyntax memberAccessSyntax)) context.SemanticModel.GetSymbolInfo(memberAccessSyntax).Symbol is IMethodSymbol methodSymbol)
return false; {
// Direct call to System.Console (e.g. System.Console.WriteLine())
if (KnownSymbols.IsSystemConsole(methodSymbol.ContainingType))
{
return true;
}
// Get the semantic model for the invoked method // Indirect call to System.Console (e.g. System.Console.Error.WriteLine())
if (!(context.SemanticModel.GetSymbolInfo(memberAccessSyntax).Symbol is IMethodSymbol methodSymbol)) if (memberAccessSyntax.Expression is MemberAccessExpressionSyntax parentMemberAccessSyntax &&
return false; context.SemanticModel.GetSymbolInfo(parentMemberAccessSyntax).Symbol is IPropertySymbol propertySymbol)
{
// Check if contained within System.Console return KnownSymbols.IsSystemConsole(propertySymbol.ContainingType);
if (KnownSymbols.IsSystemConsole(methodSymbol.ContainingType)) }
return true; }
// In case with Console.Error.WriteLine that wouldn't work, we need to check parent member access too
if (!(memberAccessSyntax.Expression is MemberAccessExpressionSyntax parentMemberAccessSyntax))
return false;
// Get the semantic model for the parent member
if (!(context.SemanticModel.GetSymbolInfo(parentMemberAccessSyntax).Symbol is IPropertySymbol propertySymbol))
return false;
// Check if contained within System.Console
if (KnownSymbols.IsSystemConsole(propertySymbol.ContainingType))
return true;
return false; return false;
} }
private static void CheckSystemConsoleUsage(SyntaxNodeAnalysisContext context) private static void CheckSystemConsoleUsage(SyntaxNodeAnalysisContext context)
{ {
if (!(context.Node is InvocationExpressionSyntax invocationSyntax)) if (context.Node is InvocationExpressionSyntax invocationSyntax &&
return; IsSystemConsoleInvocation(context, invocationSyntax))
{
// Check if IConsole is available in scope as alternative to System.Console
var isConsoleInterfaceAvailable = invocationSyntax
.Ancestors()
.OfType<MethodDeclarationSyntax>()
.SelectMany(m => m.ParameterList.Parameters)
.Select(p => p.Type)
.Select(t => context.SemanticModel.GetSymbolInfo(t).Symbol)
.Where(s => s != null)
.Any(KnownSymbols.IsConsoleInterface!);
if (!IsSystemConsoleInvocation(context, invocationSyntax)) if (isConsoleInterfaceAvailable)
return; {
context.ReportDiagnostic(Diagnostic.Create(
// Check if IConsole is available in the scope as a viable alternative DiagnosticDescriptors.CliFx0100,
var isConsoleInterfaceAvailable = invocationSyntax invocationSyntax.GetLocation()
.Ancestors() ));
.OfType<MethodDeclarationSyntax>() }
.SelectMany(m => m.ParameterList.Parameters) }
.Select(p => p.Type)
.Select(t => context.SemanticModel.GetSymbolInfo(t).Symbol)
.Where(s => s != null)
.Any(KnownSymbols.IsConsoleInterface!);
if (!isConsoleInterfaceAvailable)
return;
context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.CliFx0100, invocationSyntax.GetLocation()));
} }
public override void Initialize(AnalysisContext context) public override void Initialize(AnalysisContext context)