private static bool ContainsAwaitExpression(SyntaxNode node) { RemoveRedundantAsyncAwaitWalker walker = RemoveRedundantAsyncAwaitWalkerCache.GetInstance(node.Span, stopOnFirstAwaitExpression: true); walker.Visit(node); bool result = walker.AwaitExpressions.Count == 1; RemoveRedundantAsyncAwaitWalkerCache.Free(walker); return(result); }
public static RemoveRedundantAsyncAwaitWalker GetInstance() { RemoveRedundantAsyncAwaitWalker walker = _cachedInstance; if (walker != null) { _cachedInstance = null; walker.Reset(); return(walker); } else { return(new RemoveRedundantAsyncAwaitWalker()); } }
public static RemoveRedundantAsyncAwaitWalker GetInstance(TextSpan span, bool stopOnFirstAwaitExpression = false) { RemoveRedundantAsyncAwaitWalker walker = _cachedInstance; if (walker != null) { _cachedInstance = null; walker.Clear(); } else { walker = new RemoveRedundantAsyncAwaitWalker(); } walker.SetValues(span: span, stopOnFirstAwaitExpression: stopOnFirstAwaitExpression); return(walker); }
private static void Analyze(SyntaxNodeAnalysisContext context, SyntaxNode node, SyntaxToken asyncKeyword, BlockSyntax body) { SyntaxList <StatementSyntax> statements = body.Statements; StatementSyntax statement = statements.LastOrDefault(f => !f.IsKind(SyntaxKind.LocalFunctionStatement)); if (statement == null) { return; } switch (statement.Kind()) { case SyntaxKind.ReturnStatement: { var returnStatement = (ReturnStatementSyntax)statement; AwaitExpressionSyntax awaitExpression = GetAwaitExpression(returnStatement); if (awaitExpression == null) { return; } RemoveRedundantAsyncAwaitWalker walker = VisitStatements(); HashSet <AwaitExpressionSyntax> awaitExpressions = walker.AwaitExpressions; if (awaitExpressions.Count == 1) { if (VerifyTypes(node, awaitExpression, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, asyncKeyword, awaitExpression); } } else if (awaitExpressions.Count > 1) { StatementSyntax prevStatement = statements[statements.IndexOf(returnStatement) - 1]; switch (prevStatement.Kind()) { case SyntaxKind.IfStatement: { if (VerifyIfStatement((IfStatementSyntax)prevStatement, awaitExpressions.Count - 1, endsWithElse: false) && VerifyTypes(node, awaitExpressions, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, asyncKeyword, awaitExpressions); } break; } case SyntaxKind.SwitchStatement: { if (VerifySwitchStatement((SwitchStatementSyntax)prevStatement, awaitExpressions.Count - 1, containsDefaultSection: false) && VerifyTypes(node, awaitExpressions, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, asyncKeyword, awaitExpressions); } break; } } } RemoveRedundantAsyncAwaitWalkerCache.Free(walker); break; } case SyntaxKind.IfStatement: { RemoveRedundantAsyncAwaitWalker walker = VisitStatements(); HashSet <AwaitExpressionSyntax> awaitExpressions = walker.AwaitExpressions; if (awaitExpressions.Count > 0 && VerifyIfStatement((IfStatementSyntax)statement, awaitExpressions.Count, endsWithElse: true) && VerifyTypes(node, awaitExpressions, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, asyncKeyword, awaitExpressions); } RemoveRedundantAsyncAwaitWalkerCache.Free(walker); break; } case SyntaxKind.SwitchStatement: { RemoveRedundantAsyncAwaitWalker walker = VisitStatements(); HashSet <AwaitExpressionSyntax> awaitExpressions = walker.AwaitExpressions; if (awaitExpressions.Count > 0 && VerifySwitchStatement((SwitchStatementSyntax)statement, awaitExpressions.Count, containsDefaultSection: true) && VerifyTypes(node, awaitExpressions, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, asyncKeyword, awaitExpressions); } RemoveRedundantAsyncAwaitWalkerCache.Free(walker); break; } } RemoveRedundantAsyncAwaitWalker VisitStatements() { RemoveRedundantAsyncAwaitWalker walker = RemoveRedundantAsyncAwaitWalkerCache.GetInstance(); foreach (StatementSyntax s in statements) { walker.Visit(s); if (walker.ShouldStop) { return(walker); } if (s == statement) { return(walker); } } return(walker); } }
public static void Free(RemoveRedundantAsyncAwaitWalker walker) { walker.Clear(); _cachedInstance = walker; }