diff --git a/src/Meziantou.Analyzer.CodeFixers/Rules/UseConfigureAwaitFixer.cs b/src/Meziantou.Analyzer.CodeFixers/Rules/UseConfigureAwaitFixer.cs index 7bc6e3a2b..8d9ff8237 100644 --- a/src/Meziantou.Analyzer.CodeFixers/Rules/UseConfigureAwaitFixer.cs +++ b/src/Meziantou.Analyzer.CodeFixers/Rules/UseConfigureAwaitFixer.cs @@ -107,7 +107,13 @@ private static async Task AddConfigureAwait(CodeFixContext context, Sy { // await using (var a = expr); // var a = expr; await using (a.ConfigureAwait(false)); - var usingBlock = nodeToFix.Ancestors(ascendOutOfTrivia: true).OfType().FirstOrDefault(); + var usingBlock = nodeToFix.Ancestors(ascendOutOfTrivia: true).OfType().FirstOrDefault(usingStatement => + { + if (usingStatement.Declaration is not null) + return usingStatement.Declaration.Span.Contains(nodeToFix.Span); + + return usingStatement.Expression?.Span.Contains(nodeToFix.Span) == true; + }); if (usingBlock is not null) { if (usingBlock.Declaration is not null && usingBlock.Declaration.Variables.Count == 1) @@ -198,7 +204,10 @@ private static async Task AddConfigureAwait(CodeFixContext context, Sy } } - editor.ReplaceNode(nodeToFix, AppendConfigureAwait(nodeToFix)); + if (nodeToFix is not ExpressionSyntax expression) + return context.Document; + + editor.ReplaceNode(nodeToFix, AppendConfigureAwait(expression)); return editor.GetChangedDocument(); } @@ -229,7 +238,7 @@ bool TryInsertVariableStatementBeforeUsing(LocalDeclarationStatementSyntax varia return false; } - ExpressionSyntax AppendConfigureAwait(SyntaxNode expressionSyntax) + ExpressionSyntax AppendConfigureAwait(ExpressionSyntax expressionSyntax) { return (ExpressionSyntax)generator.InvocationExpression( generator.MemberAccessExpression(expressionSyntax, nameof(Task.ConfigureAwait)), diff --git a/tests/Meziantou.Analyzer.Test/Rules/UseConfigureAwaitAnalyzerTests.cs b/tests/Meziantou.Analyzer.Test/Rules/UseConfigureAwaitAnalyzerTests.cs index dd695339f..d84a413a2 100644 --- a/tests/Meziantou.Analyzer.Test/Rules/UseConfigureAwaitAnalyzerTests.cs +++ b/tests/Meziantou.Analyzer.Test/Rules/UseConfigureAwaitAnalyzerTests.cs @@ -787,6 +787,58 @@ await CreateProjectBuilder() .ValidateAsync(); } + [Fact] + public async Task AwaitUsingVar_InsideConfiguredUsing_ShouldNotThrow() + { + const string SourceCode = """ + using System; + using System.Threading.Tasks; + class ClassTest + { + async Task Test() + { + var connection = new AsyncDisposable(); + await using (connection.ConfigureAwait(false)) + { + await using var [|command = new AsyncDisposable()|]; + } + } + } + class AsyncDisposable : IAsyncDisposable + { + public ValueTask DisposeAsync() => throw null; + } + """; + + const string CodeFix = """ + using System; + using System.Threading.Tasks; + class ClassTest + { + async Task Test() + { + var connection = new AsyncDisposable(); + await using (connection.ConfigureAwait(false)) + { + var command = new AsyncDisposable(); + await using (command.ConfigureAwait(false)) + { + } + } + } + } + class AsyncDisposable : IAsyncDisposable + { + public ValueTask DisposeAsync() => throw null; + } + """; + + await CreateProjectBuilder() + .WithSourceCode(SourceCode) + .ShouldFixCodeWith(CodeFix) + .ValidateAsync(); + } + [Fact] public async Task AwaitUsingAwait_NoVariable() {