diff --git a/src/EditorFeatures/CSharpTest/RemoveUnusedParametersAndValues/RemoveUnusedValueAssignmentTests.cs b/src/EditorFeatures/CSharpTest/RemoveUnusedParametersAndValues/RemoveUnusedValueAssignmentTests.cs
index 202e2d2ae0a2d5ecf877bb467039702132bf1efd..66d8b2677d10426e5817d971979d9f6219b073b8 100644
--- a/src/EditorFeatures/CSharpTest/RemoveUnusedParametersAndValues/RemoveUnusedValueAssignmentTests.cs
+++ b/src/EditorFeatures/CSharpTest/RemoveUnusedParametersAndValues/RemoveUnusedValueAssignmentTests.cs
@@ -5,6 +5,7 @@
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
+using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
@@ -7487,5 +7488,58 @@ void M(int i)
}
}", options: PreferDiscard);
}
+
+ [WorkItem(38507, "https://github.com/dotnet/roslyn/issues/38507")]
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedValues)]
+ public async Task TestCodeFixTitleForBlockBodyRedundantCompoundAssignmentReturn()
+ {
+ var source =
+@"
+
+
+
+class C
+{
+ C M(C x)
+ {
+ return [|x ??= M2()|];
+ }
+
+ C M2() => new C();
+}
+
+
+
+";
+
+ using var testWorkspace = TestWorkspace.Create(source);
+ var (_, action) = await GetCodeActionsAsync(testWorkspace, parameters: default);
+ Assert.Equal(FeaturesResources.Remove_redundant_assignment, action.Title);
+ }
+
+ [WorkItem(38507, "https://github.com/dotnet/roslyn/issues/38507")]
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedValues)]
+ public async Task TestCodeFixTitleForExpressionBodyRedundantCompoundAssignmentReturn()
+ {
+ var source =
+@"
+
+
+
+class C
+{
+ C M(C x) => [|x ??= M2()|];
+
+ C M2() => new C();
+}
+
+
+
+";
+
+ using var testWorkspace = TestWorkspace.Create(source);
+ var (_, action) = await GetCodeActionsAsync(testWorkspace, parameters: default);
+ Assert.Equal(FeaturesResources.Remove_redundant_assignment, action.Title);
+ }
}
}
diff --git a/src/Features/Core/Portable/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs b/src/Features/Core/Portable/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs
index 4ba723fc9e653fe3da8ef943fa3801a68f83ad00..0d6f5c5c07acb2b3d9493bcc9e9e7a15a2dcd6e0 100644
--- a/src/Features/Core/Portable/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs
+++ b/src/Features/Core/Portable/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs
@@ -100,12 +100,12 @@ internal abstract class AbstractRemoveUnusedValuesCodeFixProvider x ??= new C();"
+ // If so, we will be replacing this compound assignment with the underlying binary operation.
+ // For the above examples, it will be "return x + M();" AND "=> x ?? new C();" respectively.
+ // For these cases, we want to show the title as "Remove redundant assignment" instead of "Use discard _".
+
+ var syntaxFacts = context.Document.GetLanguageService();
+ var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
+ var node = root.FindNode(context.Span, getInnermostNodeForTie: true);
+ if (syntaxFacts.IsLeftSideOfAnyAssignment(node) &&
+ !syntaxFacts.IsLeftSideOfAssignment(node) &&
+ !syntaxFacts.IsExpressionStatement(node.Parent))
+ {
+ title = FeaturesResources.Remove_redundant_assignment;
+ }
+
break;
case UnusedValuePreference.UnusedLocalVariable:
@@ -137,7 +154,7 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context)
break;
default:
- return Task.CompletedTask;
+ return;
}
}
@@ -148,7 +165,7 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context)
equivalenceKey: GetEquivalenceKey(preference, isRemovableAssignment)),
diagnostic);
- return Task.CompletedTask;
+ return;
}
private static bool IsForEachIterationVariableDiagnostic(Diagnostic diagnostic, Document document, CancellationToken cancellationToken)