Skip to content

Commit 766c106

Browse files
committed
Don't offer to extract to a component if the cursor is on an un-known component
1 parent b7956b2 commit 766c106

File tree

4 files changed

+49
-5
lines changed

4 files changed

+49
-5
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Threading;
77
using System.Threading.Tasks;
88
using Microsoft.AspNetCore.Razor.Language;
9+
using Microsoft.AspNetCore.Razor.Language.Components;
910
using Microsoft.AspNetCore.Razor.Language.Syntax;
1011
using Microsoft.AspNetCore.Razor.Threading;
1112
using Microsoft.CodeAnalysis.Razor.CodeActions.Models;
@@ -26,6 +27,14 @@ public Task<ImmutableArray<RazorVSInternalCodeAction>> ProvideAsync(RazorCodeAct
2627
return SpecializedTasks.EmptyImmutableArray<RazorVSInternalCodeAction>();
2728
}
2829

30+
if (context.ContainsDiagnostic(ComponentDiagnosticFactory.UnexpectedMarkupElement.Id) &&
31+
!context.HasSelection)
32+
{
33+
// If we are telling the user that a component doesn't exist, and they just have their cursor in the tag, they
34+
// won't get any benefit from extracting a non-existing component to a new component.
35+
return SpecializedTasks.EmptyImmutableArray<RazorVSInternalCodeAction>();
36+
}
37+
2938
if (!FileKinds.IsComponent(context.CodeDocument.FileKind))
3039
{
3140
return SpecializedTasks.EmptyImmutableArray<RazorVSInternalCodeAction>();

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
// Licensed under the MIT license. See License.txt in the project root for license information.
33

44
using System;
5-
using System.Collections.Generic;
65
using System.Collections.Immutable;
76
using System.Diagnostics.CodeAnalysis;
8-
using System.Linq;
97
using System.Threading;
108
using System.Threading.Tasks;
119
using Microsoft.AspNetCore.Razor;
@@ -14,7 +12,6 @@
1412
using Microsoft.AspNetCore.Razor.Language.Intermediate;
1513
using Microsoft.AspNetCore.Razor.Language.Syntax;
1614
using Microsoft.AspNetCore.Razor.Threading;
17-
using Microsoft.CodeAnalysis;
1815
using Microsoft.CodeAnalysis.Razor.CodeActions.Models;
1916
using SyntaxFacts = Microsoft.CodeAnalysis.CSharp.SyntaxFacts;
2017

@@ -26,8 +23,7 @@ internal class GenerateMethodCodeActionProvider : IRazorCodeActionProvider
2623
{
2724
public Task<ImmutableArray<RazorVSInternalCodeAction>> ProvideAsync(RazorCodeActionContext context, CancellationToken cancellationToken)
2825
{
29-
var nameNotExistDiagnostics = context.Request.Context.Diagnostics.Any(d => d.Code == "CS0103");
30-
if (!nameNotExistDiagnostics)
26+
if (!context.ContainsDiagnostic("CS0103"))
3127
{
3228
return SpecializedTasks.EmptyImmutableArray<RazorVSInternalCodeAction>();
3329
}

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,24 @@ internal sealed record class RazorCodeActionContext(
2222
bool SupportsCodeActionResolve)
2323
{
2424
public bool HasSelection => StartAbsoluteIndex != EndAbsoluteIndex;
25+
26+
public bool ContainsDiagnostic(string code)
27+
{
28+
if (Request.Context.Diagnostics is null)
29+
{
30+
return false;
31+
}
32+
33+
foreach (var diagnostic in Request.Context.Diagnostics)
34+
{
35+
if (diagnostic.Code is { } codeSumType &&
36+
codeSumType.TryGetSecond(out var codeString) &&
37+
codeString == code)
38+
{
39+
return true;
40+
}
41+
}
42+
43+
return false;
44+
}
2545
}

src/Razor/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Cohost/CodeActions/ExtractToComponentTests.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,23 @@ Hello World
3838
</div>
3939
""")]);
4040
}
41+
42+
[Fact]
43+
public async Task DontOfferOnNonExistentComponent()
44+
{
45+
await VerifyCodeActionAsync(
46+
input: """
47+
<div></div>
48+
49+
<div>
50+
Hello World
51+
</div>
52+
53+
<{|RZ10012:Not$$AComponent|} />
54+
55+
<div></div>
56+
""",
57+
expected: null,
58+
codeActionName: WorkspacesSR.ExtractTo_Component_Title);
59+
}
4160
}

0 commit comments

Comments
 (0)