diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDiagnosticFactory.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDiagnosticFactory.cs index 7d83745575..06902eb7e2 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDiagnosticFactory.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDiagnosticFactory.cs @@ -50,16 +50,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Components return RazorDiagnostic.Create(UnexpectedClosingTag, span ?? SourceSpan.Undefined, tagName); } - public static readonly RazorDiagnosticDescriptor MismatchedClosingTag = new RazorDiagnosticDescriptor( - "BL9982", - () => "Mismatching closing tag. Found '{0}' but expected '{1}'.", - RazorDiagnosticSeverity.Error); - - public static RazorDiagnostic Create_MismatchedClosingTag(SourceSpan? span, string expectedTagName, string tagName) - { - return RazorDiagnostic.Create(MismatchedClosingTag, span ?? SourceSpan.Undefined, expectedTagName, tagName); - } - public static readonly RazorDiagnosticDescriptor UnexpectedClosingTagForVoidElement = new RazorDiagnosticDescriptor( "BL9983", () => "Unexpected closing tag '{0}'. The element '{0}' is a void element, and should be used without a closing tag.", diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorIntermediateNodeLoweringPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorIntermediateNodeLoweringPhase.cs index dd0d281f34..38f05d593b 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorIntermediateNodeLoweringPhase.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorIntermediateNodeLoweringPhase.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using Microsoft.AspNetCore.Razor.Language.Components; using Microsoft.AspNetCore.Razor.Language.Extensions; using Microsoft.AspNetCore.Razor.Language.Intermediate; using Microsoft.AspNetCore.Razor.Language.Legacy; @@ -1137,13 +1138,34 @@ namespace Microsoft.AspNetCore.Razor.Language public override void VisitMarkupElement(MarkupElementSyntax node) { - _builder.Push(new MarkupElementIntermediateNode() + var element = new MarkupElementIntermediateNode() { Source = BuildSourceSpanFromNode(node), // Could be empty while the tag is being typed in. - TagName = node.StartTag?.GetTagNameWithOptionalBang() ?? node.EndTag?.GetTagName() ?? string.Empty, - }); + TagName = node.StartTag?.GetTagNameWithOptionalBang() ?? node.EndTag?.GetTagNameWithOptionalBang() ?? string.Empty, + }; + + if (node.StartTag != null && node.EndTag != null && node.StartTag.IsVoidElement()) + { + element.Diagnostics.Add( + ComponentDiagnosticFactory.Create_UnexpectedClosingTagForVoidElement( + BuildSourceSpanFromNode(node.EndTag), node.EndTag.GetTagNameWithOptionalBang())); + } + else if (node.StartTag != null && node.EndTag == null && !node.StartTag.IsVoidElement() && !node.StartTag.IsSelfClosing()) + { + element.Diagnostics.Add( + ComponentDiagnosticFactory.Create_UnclosedTag( + BuildSourceSpanFromNode(node.StartTag), node.StartTag.GetTagNameWithOptionalBang())); + } + else if (node.StartTag == null && node.EndTag != null) + { + element.Diagnostics.Add( + ComponentDiagnosticFactory.Create_UnexpectedClosingTag( + BuildSourceSpanFromNode(node.EndTag), node.EndTag.GetTagNameWithOptionalBang())); + } + + _builder.Push(element); base.VisitMarkupElement(node); diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs index 4b1d8355f5..0af7a34363 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs @@ -162,7 +162,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var endTag = (MarkupEndTagSyntax)Visit(node.EndTag); if (endTag != null) { - var tagName = endTag.GetTagName(); + var tagName = endTag.GetTagNameWithOptionalBang(); if (TryRewriteTagHelperEnd(endTag, out tagHelperEnd)) { // This is a tag helper @@ -288,7 +288,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy private bool TryRewriteTagHelperEnd(MarkupEndTagSyntax tagBlock, out MarkupTagHelperEndTagSyntax rewritten) { rewritten = null; - var tagName = tagBlock.GetTagName(); + var tagName = tagBlock.GetTagNameWithOptionalBang(); // Could not determine tag name, it can't be a TagHelper, continue on and track the element. if (string.IsNullOrEmpty(tagName) || tagName.StartsWith("!")) { @@ -599,7 +599,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy private void ValidateParentAllowsPlainEndTag(MarkupEndTagSyntax tagBlock) { - var tagName = tagBlock.GetTagName(); + var tagName = tagBlock.GetTagNameWithOptionalBang(); // Treat partial tags such as ' Children => GetLegacyChildren(); - public string GetTagName() + public string GetTagNameWithOptionalBang() { return Name.IsMissing ? string.Empty : Bang?.Content + Name.Content; }