namespace Spectre.Console.Analyzer;
///
/// Analyzer to enforce the use of AnsiConsole over System.Console for known methods.
///
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class UseSpectreInsteadOfSystemConsoleAnalyzer : SpectreAnalyzer
{
private static readonly DiagnosticDescriptor _diagnosticDescriptor =
Descriptors.S1000_UseAnsiConsoleOverSystemConsole;
private static readonly string[] _methods = { "WriteLine", "Write" };
///
public override ImmutableArray SupportedDiagnostics =>
ImmutableArray.Create(_diagnosticDescriptor);
///
protected override void AnalyzeCompilation(CompilationStartAnalysisContext compilationStartContext)
{
compilationStartContext.RegisterOperationAction(
context =>
{
// if this operation isn't an invocation against one of the System.Console methods
// defined in _methods then we can safely stop analyzing and return;
var invocationOperation = (IInvocationOperation)context.Operation;
var methodName = System.Array.Find(_methods, i => i.Equals(invocationOperation.TargetMethod.Name));
if (methodName == null)
{
return;
}
var systemConsoleType = context.Compilation.GetTypeByMetadataName("System.Console");
if (!SymbolEqualityComparer.Default.Equals(invocationOperation.TargetMethod.ContainingType, systemConsoleType))
{
return;
}
var methodSymbol = invocationOperation.TargetMethod;
var displayString = SymbolDisplay.ToDisplayString(
methodSymbol,
SymbolDisplayFormat.CSharpShortErrorMessageFormat
.WithParameterOptions(SymbolDisplayParameterOptions.None)
.WithGenericsOptions(SymbolDisplayGenericsOptions.None));
context.ReportDiagnostic(
Diagnostic.Create(
_diagnosticDescriptor,
invocationOperation.Syntax.GetLocation(),
displayString));
}, OperationKind.Invocation);
}
}