Skip to content

Commit 29002d4

Browse files
authored
Don't offer to remove directives when not on a single line directive (#12862)
Noticed today while demoing at the showcase. I always forget that `@code` is a directive :(
2 parents 4631b49 + 4448378 commit 29002d4

3 files changed

Lines changed: 42 additions & 3 deletions

File tree

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/RazorCodeDocumentExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Diagnostics.CodeAnalysis;
77
using System.IO;
88
using Microsoft.AspNetCore.Mvc.Razor.Extensions;
9+
using Microsoft.AspNetCore.Razor.Language.Legacy;
910
using Microsoft.AspNetCore.Razor.Language.Syntax;
1011

1112
namespace Microsoft.AspNetCore.Razor.Language;
@@ -51,7 +52,7 @@ internal static bool IsImportsFile(this RazorCodeDocument codeDocument)
5152
/// </remarks>
5253
internal static bool IsDirectiveUsed(this RazorCodeDocument codeDocument, BaseRazorDirectiveSyntax directive)
5354
{
54-
Debug.Assert(directive is RazorUsingDirectiveSyntax || directive.DirectiveBody.Keyword.GetContent() == "addTagHelper");
55+
Debug.Assert(directive is RazorUsingDirectiveSyntax || directive.DirectiveBody.Keyword.GetContent() == SyntaxConstants.CSharp.AddTagHelperKeyword);
5556

5657
// In imports files, all directives are considered used as usage tracking is only for source documents.
5758
if (codeDocument.IsImportsFile())

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/Razor/RemoveUnnecessaryDirectivesCodeActionProvider.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections.Immutable;
66
using System.Threading;
77
using System.Threading.Tasks;
8+
using Microsoft.AspNetCore.Razor.Language.Legacy;
89
using Microsoft.AspNetCore.Razor.Language.Syntax;
910
using Microsoft.AspNetCore.Razor.Threading;
1011
using Microsoft.CodeAnalysis.Razor.CodeActions.Models;
@@ -30,7 +31,7 @@ public Task<ImmutableArray<RazorVSInternalCodeAction>> ProvideAsync(RazorCodeAct
3031
return SpecializedTasks.EmptyImmutableArray<RazorVSInternalCodeAction>();
3132
}
3233

33-
// Trigger if the selection start or end is inside any directive
34+
// Trigger if the selection start or end is inside any single line directive
3435
var root = tree.Root;
3536
var startToken = root.FindToken(context.StartAbsoluteIndex);
3637
var endToken = context.StartAbsoluteIndex != context.EndAbsoluteIndex
@@ -40,7 +41,7 @@ public Task<ImmutableArray<RazorVSInternalCodeAction>> ProvideAsync(RazorCodeAct
4041
var startDirective = startToken.Parent?.FirstAncestorOrSelf<BaseRazorDirectiveSyntax>();
4142
var endDirective = endToken.Parent?.FirstAncestorOrSelf<BaseRazorDirectiveSyntax>();
4243

43-
if (startDirective is null && endDirective is null)
44+
if (!ShouldOffer(startDirective) && !ShouldOffer(endDirective))
4445
{
4546
return SpecializedTasks.EmptyImmutableArray<RazorVSInternalCodeAction>();
4647
}
@@ -62,4 +63,21 @@ public Task<ImmutableArray<RazorVSInternalCodeAction>> ProvideAsync(RazorCodeAct
6263
var action = RazorCodeActionFactory.CreateRemoveUnnecessaryDirectives(resolutionParams);
6364
return Task.FromResult<ImmutableArray<RazorVSInternalCodeAction>>([action]);
6465
}
66+
67+
private static bool ShouldOffer(BaseRazorDirectiveSyntax? directive)
68+
{
69+
if (directive is null)
70+
{
71+
return false;
72+
}
73+
74+
if (directive is RazorUsingDirectiveSyntax)
75+
{
76+
return true;
77+
}
78+
79+
// We offer for any single line directive on the assumption that the user has a block of directives
80+
// at the top of their file that they want to clear up.
81+
return directive.DirectiveBody.Keyword.GetContent() == SyntaxConstants.CSharp.AddTagHelperKeyword;
82+
}
6583
}

src/Razor/test/Microsoft.VisualStudioCode.RazorExtension.Test/Endpoints/Shared/CodeActions/RemoveUnnecessaryDirectiveTests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,26 @@ Hello [||]World
6767
makeDiagnosticsRequest: true);
6868
}
6969

70+
[Fact]
71+
public async Task NotOfferedWhenCursorIsInCodeBlock()
72+
{
73+
await VerifyCodeActionAsync(
74+
input: """
75+
@using System.Text
76+
77+
<div>
78+
Hello World
79+
</div>
80+
81+
@code {
82+
private [||]int _x;
83+
}
84+
""",
85+
expected: null,
86+
codeActionName: LanguageServerConstants.CodeActions.RemoveUnnecessaryDirectives,
87+
makeDiagnosticsRequest: true);
88+
}
89+
7090
[Fact]
7191
public async Task MultipleUnusedDirectives_RemovesAll()
7292
{

0 commit comments

Comments
 (0)