private bool TryHandleAwait(AwaitExpressionSyntax @await) { if (@await == null) { return(false); } if (AsyncAwait.TryGetAwaitedInvocation(@await, this.semanticModel, this.cancellationToken, out InvocationExpressionSyntax invocation)) { this.awaits = true; var symbol = this.semanticModel.GetSymbolSafe(invocation, this.cancellationToken); if (symbol != null) { if (symbol.DeclaringSyntaxReferences.Length == 0) { this.AddReturnValue(invocation); } else { return(this.TryHandleInvocation(invocation)); } } return(true); } return(false); }
private bool TryHandleAwait(AwaitExpressionSyntax awaitExpression) { if (AsyncAwait.TryGetAwaitedInvocation(awaitExpression, this.semanticModel, this.cancellationToken, out var invocation) && this.semanticModel.GetSymbolSafe(invocation, this.cancellationToken) is ISymbol symbol) { if (symbol.TrySingleDeclaration(this.cancellationToken, out MemberDeclarationSyntax declaration) && declaration is MethodDeclarationSyntax methodDeclaration) { if (methodDeclaration.Modifiers.Any(SyntaxKind.AsyncKeyword)) { return(this.TryHandleInvocation(invocation, out _)); } if (this.TryGetRecursive(awaitExpression, declaration, out var walker)) { foreach (var value in walker.returnValues) { AwaitValue(value); } } } else { AwaitValue(invocation); } this.returnValues.RemoveAll(x => IsParameter(x)); return(true); } return(false); void AwaitValue(ExpressionSyntax expression) { if (AsyncAwait.TryAwaitTaskFromResult(expression, this.semanticModel, this.cancellationToken, out var awaited)) { if (awaited is IdentifierNameSyntax identifierName && symbol is IMethodSymbol method && method.Parameters.TryFirst(x => x.Name == identifierName.Identifier.ValueText, out var parameter)) { if (this.search != ReturnValueSearch.RecursiveInside && invocation.TryFindArgument(parameter, out var argument)) { this.AddReturnValue(argument.Expression); } else if (parameter.HasExplicitDefaultValue && parameter.TrySingleDeclaration(this.cancellationToken, out var parameterDeclaration)) { this.returnValues.Add(parameterDeclaration.Default?.Value); } } this.AddReturnValue(awaited); } else if (AsyncAwait.TryAwaitTaskRun(expression, this.semanticModel, this.cancellationToken, out awaited)) { if (this.TryGetRecursive(awaited, awaited, out var walker)) { foreach (var value in walker.returnValues) { AwaitValue(value); } } } else { this.AddReturnValue(expression); } } bool IsParameter(ExpressionSyntax value) { return(value is IdentifierNameSyntax id && symbol is IMethodSymbol method && method.Parameters.TryFirst(x => x.Name == id.Identifier.ValueText, out _)); } }