Skip to content

Commit c23d49b

Browse files
committed
Fix wrapping attributes on self-closing input tags
1 parent 766c106 commit c23d49b

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ public Task<ImmutableArray<RazorVSInternalCodeAction>> ProvideAsync(RazorCodeAct
3131
}
3232

3333
var owner = syntaxTree.Root.FindNode(TextSpan.FromBounds(context.StartAbsoluteIndex, context.EndAbsoluteIndex));
34-
if (owner is null)
35-
{
36-
return SpecializedTasks.EmptyImmutableArray<RazorVSInternalCodeAction>();
37-
}
38-
3934
var attributes = FindAttributes(owner);
4035
if (attributes.Count == 0)
4136
{
@@ -100,8 +95,24 @@ public Task<ImmutableArray<RazorVSInternalCodeAction>> ProvideAsync(RazorCodeAct
10095
return Task.FromResult<ImmutableArray<RazorVSInternalCodeAction>>([action]);
10196
}
10297

103-
private AspNetCore.Razor.Language.Syntax.SyntaxList<RazorSyntaxNode> FindAttributes(AspNetCore.Razor.Language.Syntax.SyntaxNode owner)
98+
private static AspNetCore.Razor.Language.Syntax.SyntaxList<RazorSyntaxNode> FindAttributes(AspNetCore.Razor.Language.Syntax.SyntaxNode? owner)
10499
{
100+
// Sometimes FindNode will find the start tag, sometimes the element. We always start from the start tag to make searching
101+
// easier, and since we are concerned with attributes, things without start tags wouldn't be applicalbe anyway
102+
if (owner is MarkupElementSyntax element)
103+
{
104+
owner = element.StartTag;
105+
}
106+
else if (owner is MarkupTagHelperElementSyntax tagHelperElement)
107+
{
108+
owner = tagHelperElement.StartTag;
109+
}
110+
111+
if (owner is null)
112+
{
113+
return [];
114+
}
115+
105116
foreach (var node in owner.AncestorsAndSelf())
106117
{
107118
if (node is MarkupStartTagSyntax startTag)

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,14 @@ private protected async Task VerifyCodeActionAsync(TestCode input, string? expec
8989
}
9090
}
9191

92+
var range = input.HasSpans
93+
? inputText.GetRange(input.Span)
94+
: inputText.GetRange(input.Position, input.Position);
95+
9296
var request = new VSCodeActionParams
9397
{
9498
TextDocument = new VSTextDocumentIdentifier { Uri = document.CreateUri() },
95-
Range = inputText.GetRange(input.Span),
99+
Range = range,
96100
Context = new VSInternalCodeActionContext() { Diagnostics = diagnostics.ToArray() }
97101
};
98102

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,31 @@ await VerifyCodeActionAsync(
101101
expected: null,
102102
codeActionName: LanguageServerConstants.CodeActions.WrapAttributes);
103103
}
104+
105+
[Fact]
106+
public async Task SelfClosing()
107+
{
108+
await VerifyCodeActionAsync(
109+
input: """
110+
@if (true)
111+
{
112+
<div>
113+
<in[||]put bar="Baz" Zip="Zap" checked @onclick="foo" Pop="Pap" />
114+
</div>
115+
}
116+
""",
117+
expected: """
118+
@if (true)
119+
{
120+
<div>
121+
<input bar="Baz"
122+
Zip="Zap"
123+
checked
124+
@onclick="foo"
125+
Pop="Pap" />
126+
</div>
127+
}
128+
""",
129+
codeActionName: LanguageServerConstants.CodeActions.WrapAttributes);
130+
}
104131
}

0 commit comments

Comments
 (0)