semihokur / AsyncFixer

Advanced async/await Diagnostics and CodeFixes for C#
Apache License 2.0
165 stars 11 forks source link

Incorrect AsyncFixer01 violation when await is needed for inner method call parameter #7

Closed Piedone closed 3 years ago

Piedone commented 3 years ago

Consider the following code:

    public class Test
    {
        public async Task<bool> OuterAsync() => await InnerAsync(await Task.FromResult(true));

        public Task<bool> InnerAsync(bool parameter) => Task.FromResult(parameter);
    }

This causes an AsyncFixer01 violation for OuterAsync() though due to parameter an await and thus async on the method are needed.

Furthermore, if I hit Ctrl+. on OuterAsync() then I get this: image

Stack trace:

System.InvalidCastException : Unable to cast object of type 'Microsoft.CodeAnalysis.CSharp.Syntax.ReturnStatementSyntax' to type 'Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentSyntax'.
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitListElement[TNode](TNode node)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitList[TNode](SeparatedSyntaxList`1 list)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitArgumentList(ArgumentListSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.Visit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.SyntaxReplacer.Replacer`1.Visit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitInvocationExpression(InvocationExpressionSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.Visit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.SyntaxReplacer.Replacer`1.Visit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitAwaitExpression(AwaitExpressionSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.AwaitExpressionSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.Visit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.SyntaxReplacer.Replacer`1.Visit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitArrowExpressionClause(ArrowExpressionClauseSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.Visit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.SyntaxReplacer.Replacer`1.Visit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitMethodDeclaration(MethodDeclarationSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax.Accept[TResult](CSharpSyntaxVisitor`1 visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.Visit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.SyntaxReplacer.Replacer`1.Visit(SyntaxNode node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.SyntaxReplacer.Replace[TNode](SyntaxNode root,IEnumerable`1 nodes,Func`3 computeReplacementNode,IEnumerable`1 tokens,Func`3 computeReplacementToken,IEnumerable`1 trivia,Func`3 computeReplacementTrivia)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode.ReplaceCore[TNode](IEnumerable`1 nodes,Func`3 computeReplacementNode,IEnumerable`1 tokens,Func`3 computeReplacementToken,IEnumerable`1 trivia,Func`3 computeReplacementTrivia)
   at Microsoft.CodeAnalysis.SyntaxNodeExtensions.ReplaceNodes[TRoot,TNode](TRoot root,IEnumerable`1 nodes,Func`3 computeReplacementNode)
   at AsyncFixer.Helpers.ReplaceAll[T](T node,IEnumerable`1 replacementPairs)
   at async AsyncFixer.UnnecessaryAsync.UnnecessaryAsyncFixer.RemoveAsyncAwait(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.CodeActions.CodeAction.GetChangedSolutionAsync(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.CodeActions.CodeAction.ComputeOperationsAsync(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.CodeActions.CodeAction.GetPreviewOperationsAsync(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.Editor.Implementation.Suggestions.SuggestedAction.GetPreviewResultAsync(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.Editor.Implementation.Suggestions.SuggestedActionWithNestedFlavors.<>c__DisplayClass11_0.<GetPreviewAsync>b__0(<Unknown Parameters>)
   at async Microsoft.CodeAnalysis.Extensions.IExtensionManagerExtensions.PerformFunctionAsync[T](<Unknown Parameters>)
semihokur commented 3 years ago

Thanks for finding it! Yes, It is indeed a false-positive.

I did a lot of changes for AsyncFixer01. Some of my changes fix that case as well. Let me know if you need a new release soon. I can have v1.4.2 ready by tomorrow.

Piedone commented 3 years ago

Thank you for being so quick with this! Looks good to me. If you could release it sometime soon, even if not tomorrow, that would be awesome.

semihokur commented 3 years ago

Sounds good!

Piedone commented 3 years ago

1.5.0 fixed this and everything else too, thank you!