public override void Initialize(AnalysisContext context) { var cache = new WellKnownTypeCache(); context.RegisterSyntaxNodeAction(ctx => AnalyzeStatementExpression(cache, ctx), SyntaxKind.ExpressionStatement); context.RegisterSyntaxNodeAction(ctx => AnalyzeImplicitConversion(cache, ctx), SyntaxKind.MethodDeclaration); }
private void AnalyzeImplicitConversion(WellKnownTypeCache cache, SyntaxNodeAnalysisContext context) { var visitor = new ImplicitConversionWalker() { cache = cache, context = context }; visitor.Visit(context.Node); }
public void AnalyzeStatementExpression(WellKnownTypeCache cache, SyntaxNodeAnalysisContext context) { // If we encounter "await e;" where the result type of the await is a Task ... var expression = (context.Node as ExpressionStatementSyntax).Expression; if (expression == null) { return; } if (expression.Kind() != SyntaxKind.AwaitExpression) { return; } var typeInfo = context.SemanticModel.GetTypeInfo(expression); var type = typeInfo.Type as INamedTypeSymbol; if (type == null) { return; } if ((object)type != cache.GetTask(context.SemanticModel) && (object)type.ConstructedFrom != cache.GetGenericTask(context.SemanticModel)) { return; } // and if "e" didn't have the form "Task.WhenAny(...)" ... var awaitOperand = (expression as AwaitExpressionSyntax).Expression; if (awaitOperand.Kind() == SyntaxKind.InvocationExpression) { var targetNode = (awaitOperand as InvocationExpressionSyntax).Expression; if (targetNode != null) { var targetSymbol = context.SemanticModel.GetSymbolInfo(targetNode).Symbol; if (targetSymbol != null) { if ((object)targetSymbol.ContainingType == cache.GetTask(context.SemanticModel) && targetSymbol.Name == "WhenAny") { return; } } } } context.ReportDiagnostic(Diagnostic.Create(AwaitTaskTask, context.Node.GetLocation(), type.Name)); }