public override void Initialize(AnalysisContext analysisContext) { analysisContext.RegisterCompilationStartAction(compilationStartContext => { // By doing the symbol analysis here, we ensure that the symbols are only retrieved once per compilation var xUnitSymbolContext = new XUnitSymbolContext { FactSymbol = compilationStartContext.Compilation.GetTypeByMetadataName(FactAttributeTypeFullName), TheorySymbol = compilationStartContext.Compilation.GetTypeByMetadataName(TheoryAttributeTypeFullName), DataSymbol = compilationStartContext.Compilation.GetTypeByMetadataName(DataAttributeTypeFullName), InlineDataSymbol = compilationStartContext.Compilation.GetTypeByMetadataName(InlineDataAttributeTypeFullName) }; compilationStartContext.RegisterSymbolAction(symbolContext => { xUnitSymbolContext.MethodSymbol = (IMethodSymbol)symbolContext.Symbol; xUnitSymbolContext.FactDerivedAttributes = xUnitSymbolContext.MethodSymbol .GetAttributes() .Where(a => a.AttributeClass.EqualsOrInheritsFrom(xUnitSymbolContext.FactSymbol)) .ToImmutableArray(); if (!xUnitSymbolContext.FactDerivedAttributes.Any() && InlineDataWithoutTheory(xUnitSymbolContext)) { symbolContext.ReportDiagnostic(CreateInlineDataWithoutTheoryDiagnostic(xUnitSymbolContext)); } if (!xUnitSymbolContext.FactDerivedAttributes.Any()) { return; } if (MultipleFactDerivedAttributes(xUnitSymbolContext)) { symbolContext.ReportDiagnostic(CreateMultipleFactDerivedAttributesDiagnostic(xUnitSymbolContext)); } else if (FactWithParameters(xUnitSymbolContext)) { symbolContext.ReportDiagnostic(CreateFactWithParametersDiagnostic(xUnitSymbolContext)); } else if (TheoryWithoutParameters(xUnitSymbolContext)) { symbolContext.ReportDiagnostic(CreateTheoryWithoutParametersDiagnostic(xUnitSymbolContext)); } else if (TheoryWithoutData(xUnitSymbolContext)) { symbolContext.ReportDiagnostic(CreateTheoryWithoutDataDiagnostic(xUnitSymbolContext)); } }, SymbolKind.Method); }); }
private static Diagnostic CreateInlineDataWithoutTheoryDiagnostic(XUnitSymbolContext context) => CreateDiagnostic(InlineDataWithoutTheoryRule, context);
private static bool InlineDataWithoutTheory(XUnitSymbolContext context) => context.HasInlineDataAttribute && !context.HasTheoryAttribute;
private static Diagnostic CreateTheoryWithoutParametersDiagnostic(XUnitSymbolContext context) => CreateDiagnostic(TheoryWithoutParametersRule, context);
private static bool TheoryWithoutParameters(XUnitSymbolContext context) => !context.HasParameters && context.HasTheoryAttribute;
private static Diagnostic CreateTheoryWithoutDataDiagnostic(XUnitSymbolContext context) => CreateDiagnostic(TheoryWithoutDataRule, context);
private static bool TheoryWithoutData(XUnitSymbolContext context) => context.HasParameters && context.HasTheoryAttribute && !context.HasDataAttribute;
private static Diagnostic CreateMultipleFactDerivedAttributesDiagnostic(XUnitSymbolContext context) => CreateDiagnostic(MultipleFactDerivedAttributesRule, context);
private static bool MultipleFactDerivedAttributes(XUnitSymbolContext context) => context.FactDerivedAttributes.Length > 1;
private static Diagnostic CreateDiagnostic(DiagnosticDescriptor diagnostic, XUnitSymbolContext context) => Diagnostic.Create(diagnostic, context.MethodSymbol.Locations[0], context.MethodSymbol.Name);
private static Diagnostic CreateFactWithParametersDiagnostic(XUnitSymbolContext context) => CreateDiagnostic(FactWithParametersRule, context);
private static bool FactWithParameters(XUnitSymbolContext context) => context.HasParameters && context.HasFactAttribute;