private void OnMethodCall(AssertMetadata metadata, OperationAnalysisContext obj) { IInvocationOperation invocation = (IInvocationOperation)obj.Operation; if (!metadata.FailMethods.Contains(invocation.TargetMethod)) { //not a call to Assert.Fail return; } if (!(invocation.Parent is IExpressionStatementOperation expressionOperation)) { return; } // check if they did this: // if/else/foreach/using ( something ) // { Assert.Fail() } if (expressionOperation.Parent is IBlockOperation blockOperation) { if (CheckBlock(blockOperation, expressionOperation, invocation)) { obj.ReportDiagnostic(Diagnostic.Create(Rule, invocation.Syntax.GetLocation())); return; } } // bare if/else (IE, no block) if (expressionOperation.Parent is IConditionalOperation) { obj.ReportDiagnostic(Diagnostic.Create(Rule, invocation.Syntax.GetLocation())); } // bare foreach loop if (expressionOperation.Parent is IForEachLoopOperation) { obj.ReportDiagnostic(Diagnostic.Create(Rule, invocation.Syntax.GetLocation())); } }
public override void Initialize(AnalysisContext context) { context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.EnableConcurrentExecution(); context.RegisterCompilationStartAction(startContext => { INamedTypeSymbol assertClass = startContext.Compilation.GetTypeByMetadataName("Microsoft.VisualStudio.TestTools.UnitTesting.Assert"); if (assertClass == null) { return; } AssertMetadata metadata = new AssertMetadata() { FailMethods = assertClass.GetMembers("Fail").OfType <IMethodSymbol>().ToImmutableArray(), }; startContext.RegisterOperationAction((x) => OnMethodCall(metadata, x), OperationKind.Invocation); }); }