From d84f77ba142e1c77ef35ed7fd5997dd3e7ff4b17 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Mon, 19 Jun 2023 08:24:24 +1000 Subject: [PATCH 1/2] Don't assume indentation increases for void elements --- .../Formatting/FormattingVisitor.cs | 11 +++-- .../Formatting/CodeDirectiveFormattingTest.cs | 45 ++++++++++++++++++- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Formatting/FormattingVisitor.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Formatting/FormattingVisitor.cs index be73f528809..1cc5b30fa8e 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Formatting/FormattingVisitor.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Formatting/FormattingVisitor.cs @@ -16,8 +16,6 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Formatting; internal class FormattingVisitor : SyntaxWalker { - private const string HtmlTagName = "html"; - private readonly List _spans; private FormattingBlockKind _currentBlockKind; private SyntaxNode? _currentBlock; @@ -127,8 +125,10 @@ public override void VisitMarkupElement(MarkupElementSyntax node) { Visit(node.StartTag); - // Temporary fix to not break the default Html formatting behavior. Remove after https://github.com/dotnet/aspnetcore/issues/25475. - if (!string.Equals(node.StartTag?.Name?.Content, HtmlTagName, StringComparison.OrdinalIgnoreCase)) + // Void elements, like or which don't need an end tag don't cause indentation + var causesIndentation = node.StartTag is null || !node.StartTag.IsVoidElement(); + + if (causesIndentation) { _currentHtmlIndentationLevel++; } @@ -138,8 +138,7 @@ public override void VisitMarkupElement(MarkupElementSyntax node) Visit(child); } - // Temporary fix to not break the default Html formatting behavior. Remove after https://github.com/dotnet/aspnetcore/issues/25475. - if (!string.Equals(node.StartTag?.Name?.Content, HtmlTagName, StringComparison.OrdinalIgnoreCase)) + if (causesIndentation) { _currentHtmlIndentationLevel--; } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting/CodeDirectiveFormattingTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting/CodeDirectiveFormattingTest.cs index f372dd15e9d..24660383552 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting/CodeDirectiveFormattingTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting/CodeDirectiveFormattingTest.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See License.txt in the project root for license information. -using System.Collections.Generic; using System.Collections.Immutable; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; @@ -437,6 +436,50 @@ @section Scripts { fileKind: FileKinds.Legacy); } + [Fact] + public async Task Format_SectionDirectiveBlock6() + { + await RunFormattingTestAsync( + input: """ + @functions { + public class Foo{ + void Method() { } + } + } + + @section Scripts { + + + + + @if(true) + { +

this is a paragraph

+ } + } + """, + expected: """ + @functions { + public class Foo + { + void Method() { } + } + } + + @section Scripts { + + + + + @if (true) + { +

this is a paragraph

+ } + } + """, + fileKind: FileKinds.Legacy); + } + [Fact] public async Task Formats_CodeBlockDirectiveWithRazorComments() { From ffb687e8af58561e679d67ecf909bfd2978d80ac Mon Sep 17 00:00:00 2001 From: David Wengier Date: Wed, 21 Jun 2023 18:01:21 +1000 Subject: [PATCH 2/2] Prevent html tag formatting regression found by integration tests --- .../Formatting/FormattingVisitor.cs | 13 +++++--- .../Formatting/CodeDirectiveFormattingTest.cs | 30 +++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Formatting/FormattingVisitor.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Formatting/FormattingVisitor.cs index 1cc5b30fa8e..0f17c1d5d93 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Formatting/FormattingVisitor.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Formatting/FormattingVisitor.cs @@ -16,6 +16,8 @@ namespace Microsoft.AspNetCore.Razor.LanguageServer.Formatting; internal class FormattingVisitor : SyntaxWalker { + private const string HtmlTag = "html"; + private readonly List _spans; private FormattingBlockKind _currentBlockKind; private SyntaxNode? _currentBlock; @@ -125,10 +127,13 @@ public override void VisitMarkupElement(MarkupElementSyntax node) { Visit(node.StartTag); - // Void elements, like or which don't need an end tag don't cause indentation - var causesIndentation = node.StartTag is null || !node.StartTag.IsVoidElement(); + // Void elements, like or which don't need an end tag don't cause indentation. + // We also cheat and treat the tag as a void element, so it doesn't cause indentation, + // as that's what the Html formatter does, to avoid one level of indentation in every html file. + var voidElement = node.StartTag is { } startTag && + (startTag.IsVoidElement() || string.Equals(startTag.Name.Content, HtmlTag, StringComparison.OrdinalIgnoreCase)); - if (causesIndentation) + if (!voidElement) { _currentHtmlIndentationLevel++; } @@ -138,7 +143,7 @@ public override void VisitMarkupElement(MarkupElementSyntax node) Visit(child); } - if (causesIndentation) + if (!voidElement) { _currentHtmlIndentationLevel--; } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting/CodeDirectiveFormattingTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting/CodeDirectiveFormattingTest.cs index 24660383552..b899e463e94 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting/CodeDirectiveFormattingTest.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Formatting/CodeDirectiveFormattingTest.cs @@ -42,6 +42,36 @@ public interface Bar """); } + [Fact] + public async Task FormatCSharpInsideHtmlTag() + { + await RunFormattingTestAsync( + input: """ + + +
+ @{ + foo + foo + } +
+ + + """, + expected: """ + + +
+ @{ + foo + foo + } +
+ + + """); + } + [Fact] public async Task Format_DocumentWithDiagnostics() {