builder, P
if (tagMode == MarkupTagMode.SelfClosing || tagMode == MarkupTagMode.Invalid || tagMode == MarkupTagMode.Void)
{
// For cases like , or invalid cases like |<|
- var element = SyntaxFactory.MarkupElement(startTag, EmptySyntaxList, endTag: null);
+ var element = SyntaxFactory.MarkupElement(startTag, EmptySyntaxList, markupEndTag: null);
builder.Add(element);
return;
}
@@ -532,7 +532,7 @@ private void ParseMarkupElement(in SyntaxListBuilder builder, P
if (!TryRecoverStartTag(builder, endTagName, endTag))
{
// Could not recover.
- var element = SyntaxFactory.MarkupElement(startTag: null, body: EmptySyntaxList, endTag: endTag);
+ var element = SyntaxFactory.MarkupElement(markupStartTag: null, body: EmptySyntaxList, markupEndTag: endTag);
builder.Add(element);
if (mode == ParseMode.MarkupInCodeBlock)
@@ -563,7 +563,7 @@ private void CompleteEndTag(
while (_tagTracker.Count > 0)
{
var tracker = _tagTracker.Pop();
- var unclosedElement = SyntaxFactory.MarkupElement(tracker.StartTag, builder.Consume(), endTag: null);
+ var unclosedElement = SyntaxFactory.MarkupElement(tracker.StartTag, builder.Consume(), markupEndTag: null);
builder.AddRange(tracker.PreviousNodes);
builder.Add(unclosedElement);
@@ -589,7 +589,7 @@ private bool TryRecoverStartTag(in SyntaxListBuilder builder, s
{
var tracker = _tagTracker.Pop();
var children = builder.Consume();
- var voidElement = SyntaxFactory.MarkupElement(tracker.StartTag, EmptySyntaxList, endTag: null);
+ var voidElement = SyntaxFactory.MarkupElement(tracker.StartTag, EmptySyntaxList, markupEndTag: null);
builder.AddRange(tracker.PreviousNodes);
builder.Add(voidElement);
builder.AddRange(children);
@@ -612,7 +612,7 @@ private bool TryRecoverStartTag(in SyntaxListBuilder builder, s
for (var i = 0; i < malformedTagCount; i++)
{
var tracker = _tagTracker.Pop();
- var malformedElement = SyntaxFactory.MarkupElement(tracker.StartTag, builder.Consume(), endTag: null);
+ var malformedElement = SyntaxFactory.MarkupElement(tracker.StartTag, builder.Consume(), markupEndTag: null);
builder.AddRange(tracker.PreviousNodes);
builder.Add(malformedElement);
}
@@ -2149,7 +2149,7 @@ private void NestingBlock(in SyntaxListBuilder builder, Tuple 0)
{
var tracker = _tagTracker.Pop();
- var element = SyntaxFactory.MarkupElement(tracker.StartTag, builder.Consume(), endTag: null);
+ var element = SyntaxFactory.MarkupElement(tracker.StartTag, builder.Consume(), markupEndTag: null);
builder.AddRange(tracker.PreviousNodes);
builder.Add(element);
}
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Legacy/TagHelperParseTreeRewriter.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Legacy/TagHelperParseTreeRewriter.cs
index 7706ba59913..cc59d2ae3c5 100644
--- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Legacy/TagHelperParseTreeRewriter.cs
+++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Legacy/TagHelperParseTreeRewriter.cs
@@ -115,14 +115,14 @@ public override SyntaxNode VisitMarkupElement(MarkupElementSyntax node)
if (startTag != null)
{
var tagName = startTag.GetTagNameWithOptionalBang();
- if (TryRewriteTagHelperStart(startTag, node.EndTag, out tagHelperStart, out tagHelperInfo))
+ if (TryRewriteTagHelperStart(startTag, node.MarkupEndTag, out tagHelperStart, out tagHelperInfo))
{
// This is a tag helper.
if (tagHelperInfo.TagMode == TagMode.SelfClosing || tagHelperInfo.TagMode == TagMode.StartTagOnly)
{
- var tagHelperElement = SyntaxFactory.MarkupTagHelperElement(tagHelperStart, body: default, endTag: null, tagHelperInfo);
+ var tagHelperElement = SyntaxFactory.MarkupTagHelperElement(tagHelperStart, body: default, tagHelperEndTag: null, tagHelperInfo);
- if (node.Body.Count == 0 && node.EndTag == null)
+ if (node.Body.Count == 0 && node.MarkupEndTag == null)
{
return tagHelperElement;
}
@@ -134,14 +134,14 @@ public override SyntaxNode VisitMarkupElement(MarkupElementSyntax node)
var rewrittenBody = VisitList(node.Body);
rewrittenNodes.AddRange(rewrittenBody);
- return SyntaxFactory.MarkupElement(startTag: null, body: rewrittenNodes.ToList(), endTag: node.EndTag);
+ return SyntaxFactory.MarkupElement(markupStartTag: null, body: rewrittenNodes.ToList(), markupEndTag: node.MarkupEndTag);
}
else if (node.EndTag == null)
{
// Start tag helper with no corresponding end tag.
var source = new SourceSpan(SourceLocationTracker.Advance(startTag.GetSourceLocation(_source), "<"), tagName.Length);
_errorSink.OnError(
- node.StartTag.IsVoidElement()
+ startTag.IsVoidElement()
? RazorDiagnosticFactory.CreateParsing_VoidElement(source, tagName)
: RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(source, tagName));
}
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/BaseMarkupEndTagSyntax.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/BaseMarkupEndTagSyntax.cs
index 981cf77bb86..7d014f0dee8 100644
--- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/BaseMarkupEndTagSyntax.cs
+++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/BaseMarkupEndTagSyntax.cs
@@ -101,5 +101,6 @@ static bool IsValidToken(SyntaxToken token, out SyntaxToken validToken)
}
}
- public abstract BaseMarkupStartTagSyntax? GetStartTag();
+ public BaseMarkupStartTagSyntax? GetStartTag()
+ => (Parent as BaseMarkupElementSyntax)?.StartTag;
}
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/BaseMarkupStartTagSyntax.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/BaseMarkupStartTagSyntax.cs
index fced98fe7a1..32fff8333c4 100644
--- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/BaseMarkupStartTagSyntax.cs
+++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/BaseMarkupStartTagSyntax.cs
@@ -10,6 +10,8 @@ internal abstract partial class BaseMarkupStartTagSyntax
{
private SyntaxNode? _lazyChildren;
+ public BaseMarkupElementSyntax ParentElement => (BaseMarkupElementSyntax)Parent;
+
public SyntaxList LegacyChildren
{
get
@@ -130,5 +132,6 @@ static bool IsValidToken(SyntaxToken token, out SyntaxToken validToken)
}
}
- public abstract BaseMarkupEndTagSyntax? GetEndTag();
+ public BaseMarkupEndTagSyntax? GetEndTag()
+ => (Parent as BaseMarkupElementSyntax)?.EndTag;
}
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Generated/Syntax.xml.Internal.Generated.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Generated/Syntax.xml.Internal.Generated.cs
index 06e8864573d..70acc04f72b 100644
--- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Generated/Syntax.xml.Internal.Generated.cs
+++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Generated/Syntax.xml.Internal.Generated.cs
@@ -1082,64 +1082,81 @@ internal BaseMarkupEndTagSyntax(SyntaxKind kind)
public abstract SpanEditHandler EditHandler { get; }
}
-internal sealed partial class MarkupElementSyntax : MarkupSyntaxNode
+internal abstract partial class BaseMarkupElementSyntax : MarkupSyntaxNode
{
- internal readonly MarkupStartTagSyntax _startTag;
+ internal BaseMarkupElementSyntax(SyntaxKind kind, RazorDiagnostic[] diagnostics)
+ : base(kind, diagnostics)
+ {
+ }
+
+ internal BaseMarkupElementSyntax(SyntaxKind kind)
+ : base(kind)
+ {
+ }
+
+ public abstract BaseMarkupStartTagSyntax StartTag { get; }
+
+ public abstract BaseMarkupEndTagSyntax EndTag { get; }
+}
+
+internal sealed partial class MarkupElementSyntax : BaseMarkupElementSyntax
+{
+ internal readonly MarkupStartTagSyntax _markupStartTag;
internal readonly GreenNode _body;
- internal readonly MarkupEndTagSyntax _endTag;
+ internal readonly MarkupEndTagSyntax _markupEndTag;
- internal MarkupElementSyntax(SyntaxKind kind, MarkupStartTagSyntax startTag, GreenNode body, MarkupEndTagSyntax endTag, RazorDiagnostic[] diagnostics)
+ internal MarkupElementSyntax(SyntaxKind kind, MarkupStartTagSyntax markupStartTag, GreenNode body, MarkupEndTagSyntax markupEndTag, RazorDiagnostic[] diagnostics)
: base(kind, diagnostics)
{
SlotCount = 3;
- if (startTag != null)
+ if (markupStartTag != null)
{
- AdjustFlagsAndWidth(startTag);
- _startTag = startTag;
+ AdjustFlagsAndWidth(markupStartTag);
+ _markupStartTag = markupStartTag;
}
if (body != null)
{
AdjustFlagsAndWidth(body);
_body = body;
}
- if (endTag != null)
+ if (markupEndTag != null)
{
- AdjustFlagsAndWidth(endTag);
- _endTag = endTag;
+ AdjustFlagsAndWidth(markupEndTag);
+ _markupEndTag = markupEndTag;
}
}
- internal MarkupElementSyntax(SyntaxKind kind, MarkupStartTagSyntax startTag, GreenNode body, MarkupEndTagSyntax endTag)
+ internal MarkupElementSyntax(SyntaxKind kind, MarkupStartTagSyntax markupStartTag, GreenNode body, MarkupEndTagSyntax markupEndTag)
: base(kind)
{
SlotCount = 3;
- if (startTag != null)
+ if (markupStartTag != null)
{
- AdjustFlagsAndWidth(startTag);
- _startTag = startTag;
+ AdjustFlagsAndWidth(markupStartTag);
+ _markupStartTag = markupStartTag;
}
if (body != null)
{
AdjustFlagsAndWidth(body);
_body = body;
}
- if (endTag != null)
+ if (markupEndTag != null)
{
- AdjustFlagsAndWidth(endTag);
- _endTag = endTag;
+ AdjustFlagsAndWidth(markupEndTag);
+ _markupEndTag = markupEndTag;
}
}
- public MarkupStartTagSyntax StartTag => _startTag;
+ public MarkupStartTagSyntax MarkupStartTag => _markupStartTag;
public SyntaxList Body => new SyntaxList(_body);
- public MarkupEndTagSyntax EndTag => _endTag;
+ public MarkupEndTagSyntax MarkupEndTag => _markupEndTag;
internal override GreenNode GetSlot(int index)
=> index switch
{
- 0 => _startTag,
+ 0 => _markupStartTag,
1 => _body,
- 2 => _endTag,
+ 2 => _markupEndTag,
_ => null
};
@@ -1148,11 +1165,11 @@ internal override GreenNode GetSlot(int index)
public override TResult Accept(SyntaxVisitor visitor) => visitor.VisitMarkupElement(this);
public override void Accept(SyntaxVisitor visitor) => visitor.VisitMarkupElement(this);
- public MarkupElementSyntax Update(MarkupStartTagSyntax startTag, InternalSyntax.SyntaxList body, MarkupEndTagSyntax endTag)
+ public MarkupElementSyntax Update(MarkupStartTagSyntax markupStartTag, InternalSyntax.SyntaxList body, MarkupEndTagSyntax markupEndTag)
{
- if (startTag != StartTag || body != Body || endTag != EndTag)
+ if (markupStartTag != MarkupStartTag || body != Body || markupEndTag != MarkupEndTag)
{
- var newNode = SyntaxFactory.MarkupElement(startTag, body, endTag);
+ var newNode = SyntaxFactory.MarkupElement(markupStartTag, body, markupEndTag);
var diags = GetDiagnostics();
if (diags != null && diags.Length > 0)
newNode = newNode.WithDiagnosticsGreen(diags);
@@ -1163,7 +1180,7 @@ public MarkupElementSyntax Update(MarkupStartTagSyntax startTag, InternalSyntax.
}
internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics)
- => new MarkupElementSyntax(Kind, _startTag, _body, _endTag, diagnostics);
+ => new MarkupElementSyntax(Kind, _markupStartTag, _body, _markupEndTag, diagnostics);
}
internal sealed partial class MarkupStartTagSyntax : BaseMarkupStartTagSyntax
@@ -1394,62 +1411,68 @@ internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics)
=> new MarkupEndTagSyntax(Kind, _openAngle, _forwardSlash, _bang, _name, _miscAttributeContent, _closeAngle, _isMarkupTransition, _chunkGenerator, _editHandler, diagnostics);
}
-internal sealed partial class MarkupTagHelperElementSyntax : MarkupSyntaxNode
+internal sealed partial class MarkupTagHelperElementSyntax : BaseMarkupElementSyntax
{
- internal readonly MarkupTagHelperStartTagSyntax _startTag;
+ internal readonly MarkupTagHelperStartTagSyntax _tagHelperStartTag;
internal readonly GreenNode _body;
- internal readonly MarkupTagHelperEndTagSyntax _endTag;
+ internal readonly MarkupTagHelperEndTagSyntax _tagHelperEndTag;
internal readonly TagHelperInfo _tagHelperInfo;
- internal MarkupTagHelperElementSyntax(SyntaxKind kind, MarkupTagHelperStartTagSyntax startTag, GreenNode body, MarkupTagHelperEndTagSyntax endTag, TagHelperInfo tagHelperInfo, RazorDiagnostic[] diagnostics)
+ internal MarkupTagHelperElementSyntax(SyntaxKind kind, MarkupTagHelperStartTagSyntax tagHelperStartTag, GreenNode body, MarkupTagHelperEndTagSyntax tagHelperEndTag, TagHelperInfo tagHelperInfo, RazorDiagnostic[] diagnostics)
: base(kind, diagnostics)
{
SlotCount = 3;
- AdjustFlagsAndWidth(startTag);
- _startTag = startTag;
+ if (tagHelperStartTag != null)
+ {
+ AdjustFlagsAndWidth(tagHelperStartTag);
+ _tagHelperStartTag = tagHelperStartTag;
+ }
if (body != null)
{
AdjustFlagsAndWidth(body);
_body = body;
}
- if (endTag != null)
+ if (tagHelperEndTag != null)
{
- AdjustFlagsAndWidth(endTag);
- _endTag = endTag;
+ AdjustFlagsAndWidth(tagHelperEndTag);
+ _tagHelperEndTag = tagHelperEndTag;
}
_tagHelperInfo = tagHelperInfo;
}
- internal MarkupTagHelperElementSyntax(SyntaxKind kind, MarkupTagHelperStartTagSyntax startTag, GreenNode body, MarkupTagHelperEndTagSyntax endTag, TagHelperInfo tagHelperInfo)
+ internal MarkupTagHelperElementSyntax(SyntaxKind kind, MarkupTagHelperStartTagSyntax tagHelperStartTag, GreenNode body, MarkupTagHelperEndTagSyntax tagHelperEndTag, TagHelperInfo tagHelperInfo)
: base(kind)
{
SlotCount = 3;
- AdjustFlagsAndWidth(startTag);
- _startTag = startTag;
+ if (tagHelperStartTag != null)
+ {
+ AdjustFlagsAndWidth(tagHelperStartTag);
+ _tagHelperStartTag = tagHelperStartTag;
+ }
if (body != null)
{
AdjustFlagsAndWidth(body);
_body = body;
}
- if (endTag != null)
+ if (tagHelperEndTag != null)
{
- AdjustFlagsAndWidth(endTag);
- _endTag = endTag;
+ AdjustFlagsAndWidth(tagHelperEndTag);
+ _tagHelperEndTag = tagHelperEndTag;
}
_tagHelperInfo = tagHelperInfo;
}
- public MarkupTagHelperStartTagSyntax StartTag => _startTag;
+ public MarkupTagHelperStartTagSyntax TagHelperStartTag => _tagHelperStartTag;
public SyntaxList Body => new SyntaxList(_body);
- public MarkupTagHelperEndTagSyntax EndTag => _endTag;
+ public MarkupTagHelperEndTagSyntax TagHelperEndTag => _tagHelperEndTag;
public TagHelperInfo TagHelperInfo => _tagHelperInfo;
internal override GreenNode GetSlot(int index)
=> index switch
{
- 0 => _startTag,
+ 0 => _tagHelperStartTag,
1 => _body,
- 2 => _endTag,
+ 2 => _tagHelperEndTag,
_ => null
};
@@ -1458,11 +1481,11 @@ internal override GreenNode GetSlot(int index)
public override TResult Accept(SyntaxVisitor visitor) => visitor.VisitMarkupTagHelperElement(this);
public override void Accept(SyntaxVisitor visitor) => visitor.VisitMarkupTagHelperElement(this);
- public MarkupTagHelperElementSyntax Update(MarkupTagHelperStartTagSyntax startTag, InternalSyntax.SyntaxList body, MarkupTagHelperEndTagSyntax endTag, TagHelperInfo tagHelperInfo)
+ public MarkupTagHelperElementSyntax Update(MarkupTagHelperStartTagSyntax tagHelperStartTag, InternalSyntax.SyntaxList body, MarkupTagHelperEndTagSyntax tagHelperEndTag, TagHelperInfo tagHelperInfo)
{
- if (startTag != StartTag || body != Body || endTag != EndTag)
+ if (tagHelperStartTag != TagHelperStartTag || body != Body || tagHelperEndTag != TagHelperEndTag)
{
- var newNode = SyntaxFactory.MarkupTagHelperElement(startTag, body, endTag, tagHelperInfo);
+ var newNode = SyntaxFactory.MarkupTagHelperElement(tagHelperStartTag, body, tagHelperEndTag, tagHelperInfo);
var diags = GetDiagnostics();
if (diags != null && diags.Length > 0)
newNode = newNode.WithDiagnosticsGreen(diags);
@@ -1473,7 +1496,7 @@ public MarkupTagHelperElementSyntax Update(MarkupTagHelperStartTagSyntax startTa
}
internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics)
- => new MarkupTagHelperElementSyntax(Kind, _startTag, _body, _endTag, _tagHelperInfo, diagnostics);
+ => new MarkupTagHelperElementSyntax(Kind, _tagHelperStartTag, _body, _tagHelperEndTag, _tagHelperInfo, diagnostics);
}
internal sealed partial class MarkupTagHelperStartTagSyntax : BaseMarkupStartTagSyntax
@@ -3277,7 +3300,7 @@ public override GreenNode VisitMarkupDynamicAttributeValue(MarkupDynamicAttribut
=> node.Update((MarkupTextLiteralSyntax)Visit(node.Prefix), (RazorBlockSyntax)Visit(node.Value));
public override GreenNode VisitMarkupElement(MarkupElementSyntax node)
- => node.Update((MarkupStartTagSyntax)Visit(node.StartTag), VisitList(node.Body), (MarkupEndTagSyntax)Visit(node.EndTag));
+ => node.Update((MarkupStartTagSyntax)Visit(node.MarkupStartTag), VisitList(node.Body), (MarkupEndTagSyntax)Visit(node.MarkupEndTag));
public override GreenNode VisitMarkupStartTag(MarkupStartTagSyntax node)
=> node.Update((SyntaxToken)Visit(node.OpenAngle), (SyntaxToken)Visit(node.Bang), (SyntaxToken)Visit(node.Name), VisitList(node.Attributes), (SyntaxToken)Visit(node.ForwardSlash), (SyntaxToken)Visit(node.CloseAngle), node.IsMarkupTransition, node.ChunkGenerator, node.EditHandler);
@@ -3286,7 +3309,7 @@ public override GreenNode VisitMarkupEndTag(MarkupEndTagSyntax node)
=> node.Update((SyntaxToken)Visit(node.OpenAngle), (SyntaxToken)Visit(node.ForwardSlash), (SyntaxToken)Visit(node.Bang), (SyntaxToken)Visit(node.Name), (MarkupMiscAttributeContentSyntax)Visit(node.MiscAttributeContent), (SyntaxToken)Visit(node.CloseAngle), node.IsMarkupTransition, node.ChunkGenerator, node.EditHandler);
public override GreenNode VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node)
- => node.Update((MarkupTagHelperStartTagSyntax)Visit(node.StartTag), VisitList(node.Body), (MarkupTagHelperEndTagSyntax)Visit(node.EndTag), node.TagHelperInfo);
+ => node.Update((MarkupTagHelperStartTagSyntax)Visit(node.TagHelperStartTag), VisitList(node.Body), (MarkupTagHelperEndTagSyntax)Visit(node.TagHelperEndTag), node.TagHelperInfo);
public override GreenNode VisitMarkupTagHelperStartTag(MarkupTagHelperStartTagSyntax node)
=> node.Update((SyntaxToken)Visit(node.OpenAngle), (SyntaxToken)Visit(node.Bang), (SyntaxToken)Visit(node.Name), VisitList(node.Attributes), (SyntaxToken)Visit(node.ForwardSlash), (SyntaxToken)Visit(node.CloseAngle), node.ChunkGenerator, node.EditHandler);
@@ -3488,9 +3511,9 @@ public static MarkupDynamicAttributeValueSyntax MarkupDynamicAttributeValue(Mark
return result;
}
- public static MarkupElementSyntax MarkupElement(MarkupStartTagSyntax startTag, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList body, MarkupEndTagSyntax endTag)
+ public static MarkupElementSyntax MarkupElement(MarkupStartTagSyntax markupStartTag, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList body, MarkupEndTagSyntax markupEndTag)
{
- var result = new MarkupElementSyntax(SyntaxKind.MarkupElement, startTag, body.Node, endTag);
+ var result = new MarkupElementSyntax(SyntaxKind.MarkupElement, markupStartTag, body.Node, markupEndTag);
return result;
}
@@ -3534,11 +3557,9 @@ public static MarkupEndTagSyntax MarkupEndTag(SyntaxToken openAngle, SyntaxToken
return new MarkupEndTagSyntax(SyntaxKind.MarkupEndTag, openAngle, forwardSlash, bang, name, miscAttributeContent, closeAngle, isMarkupTransition, chunkGenerator, editHandler);
}
- public static MarkupTagHelperElementSyntax MarkupTagHelperElement(MarkupTagHelperStartTagSyntax startTag, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList body, MarkupTagHelperEndTagSyntax endTag, TagHelperInfo tagHelperInfo)
+ public static MarkupTagHelperElementSyntax MarkupTagHelperElement(MarkupTagHelperStartTagSyntax tagHelperStartTag, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList body, MarkupTagHelperEndTagSyntax tagHelperEndTag, TagHelperInfo tagHelperInfo)
{
- ArgHelper.ThrowIfNull(startTag);
-
- return new MarkupTagHelperElementSyntax(SyntaxKind.MarkupTagHelperElement, startTag, body.Node, endTag, tagHelperInfo);
+ return new MarkupTagHelperElementSyntax(SyntaxKind.MarkupTagHelperElement, tagHelperStartTag, body.Node, tagHelperEndTag, tagHelperInfo);
}
public static MarkupTagHelperStartTagSyntax MarkupTagHelperStartTag(SyntaxToken openAngle, SyntaxToken bang, SyntaxToken name, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList attributes, SyntaxToken forwardSlash, SyntaxToken closeAngle, ISpanChunkGenerator chunkGenerator, SpanEditHandler editHandler)
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Generated/Syntax.xml.Main.Generated.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Generated/Syntax.xml.Main.Generated.cs
index 92681edad34..1d6e7973ba5 100644
--- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Generated/Syntax.xml.Main.Generated.cs
+++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Generated/Syntax.xml.Main.Generated.cs
@@ -306,7 +306,7 @@ public override SyntaxNode VisitMarkupDynamicAttributeValue(MarkupDynamicAttribu
=> node.Update((MarkupTextLiteralSyntax)Visit(node.Prefix), (RazorBlockSyntax)Visit(node.Value));
public override SyntaxNode VisitMarkupElement(MarkupElementSyntax node)
- => node.Update((MarkupStartTagSyntax)Visit(node.StartTag), VisitList(node.Body), (MarkupEndTagSyntax)Visit(node.EndTag));
+ => node.Update((MarkupStartTagSyntax)Visit(node.MarkupStartTag), VisitList(node.Body), (MarkupEndTagSyntax)Visit(node.MarkupEndTag));
public override SyntaxNode VisitMarkupStartTag(MarkupStartTagSyntax node)
=> node.Update((SyntaxToken)VisitToken(node.OpenAngle), (SyntaxToken)VisitToken(node.Bang), (SyntaxToken)VisitToken(node.Name), VisitList(node.Attributes), (SyntaxToken)VisitToken(node.ForwardSlash), (SyntaxToken)VisitToken(node.CloseAngle), node.IsMarkupTransition, node.ChunkGenerator, node.EditHandler);
@@ -315,7 +315,7 @@ public override SyntaxNode VisitMarkupEndTag(MarkupEndTagSyntax node)
=> node.Update((SyntaxToken)VisitToken(node.OpenAngle), (SyntaxToken)VisitToken(node.ForwardSlash), (SyntaxToken)VisitToken(node.Bang), (SyntaxToken)VisitToken(node.Name), (MarkupMiscAttributeContentSyntax)Visit(node.MiscAttributeContent), (SyntaxToken)VisitToken(node.CloseAngle), node.IsMarkupTransition, node.ChunkGenerator, node.EditHandler);
public override SyntaxNode VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node)
- => node.Update((MarkupTagHelperStartTagSyntax)Visit(node.StartTag), VisitList(node.Body), (MarkupTagHelperEndTagSyntax)Visit(node.EndTag), node.TagHelperInfo);
+ => node.Update((MarkupTagHelperStartTagSyntax)Visit(node.TagHelperStartTag), VisitList(node.Body), (MarkupTagHelperEndTagSyntax)Visit(node.TagHelperEndTag), node.TagHelperInfo);
public override SyntaxNode VisitMarkupTagHelperStartTag(MarkupTagHelperStartTagSyntax node)
=> node.Update((SyntaxToken)VisitToken(node.OpenAngle), (SyntaxToken)VisitToken(node.Bang), (SyntaxToken)VisitToken(node.Name), VisitList(node.Attributes), (SyntaxToken)VisitToken(node.ForwardSlash), (SyntaxToken)VisitToken(node.CloseAngle), node.ChunkGenerator, node.EditHandler);
@@ -532,8 +532,8 @@ public static MarkupDynamicAttributeValueSyntax MarkupDynamicAttributeValue(Razo
=> SyntaxFactory.MarkupDynamicAttributeValue(default(MarkupTextLiteralSyntax), value);
/// Creates a new MarkupElementSyntax instance.
- public static MarkupElementSyntax MarkupElement(MarkupStartTagSyntax startTag, SyntaxList body, MarkupEndTagSyntax endTag)
- => (MarkupElementSyntax)InternalSyntax.SyntaxFactory.MarkupElement(startTag == null ? null : (InternalSyntax.MarkupStartTagSyntax)startTag.Green, body.Node.ToGreenList(), endTag == null ? null : (InternalSyntax.MarkupEndTagSyntax)endTag.Green).CreateRed();
+ public static MarkupElementSyntax MarkupElement(MarkupStartTagSyntax markupStartTag, SyntaxList body, MarkupEndTagSyntax markupEndTag)
+ => (MarkupElementSyntax)InternalSyntax.SyntaxFactory.MarkupElement(markupStartTag == null ? null : (InternalSyntax.MarkupStartTagSyntax)markupStartTag.Green, body.Node.ToGreenList(), markupEndTag == null ? null : (InternalSyntax.MarkupEndTagSyntax)markupEndTag.Green).CreateRed();
/// Creates a new MarkupElementSyntax instance.
public static MarkupElementSyntax MarkupElement(SyntaxList body = default(SyntaxList))
@@ -578,15 +578,12 @@ public static MarkupEndTagSyntax MarkupEndTag(bool isMarkupTransition, ISpanChun
=> SyntaxFactory.MarkupEndTag(SyntaxFactory.Token(SyntaxKind.OpenAngle), SyntaxFactory.Token(SyntaxKind.ForwardSlash), default(SyntaxToken), SyntaxFactory.Token(SyntaxKind.Text), default(MarkupMiscAttributeContentSyntax), SyntaxFactory.Token(SyntaxKind.CloseAngle), isMarkupTransition, chunkGenerator, editHandler);
/// Creates a new MarkupTagHelperElementSyntax instance.
- public static MarkupTagHelperElementSyntax MarkupTagHelperElement(MarkupTagHelperStartTagSyntax startTag, SyntaxList body, MarkupTagHelperEndTagSyntax endTag, TagHelperInfo tagHelperInfo)
- {
- ArgHelper.ThrowIfNull(startTag);
- return (MarkupTagHelperElementSyntax)InternalSyntax.SyntaxFactory.MarkupTagHelperElement(startTag == null ? null : (InternalSyntax.MarkupTagHelperStartTagSyntax)startTag.Green, body.Node.ToGreenList(), endTag == null ? null : (InternalSyntax.MarkupTagHelperEndTagSyntax)endTag.Green, tagHelperInfo).CreateRed();
- }
+ public static MarkupTagHelperElementSyntax MarkupTagHelperElement(MarkupTagHelperStartTagSyntax tagHelperStartTag, SyntaxList body, MarkupTagHelperEndTagSyntax tagHelperEndTag, TagHelperInfo tagHelperInfo)
+ => (MarkupTagHelperElementSyntax)InternalSyntax.SyntaxFactory.MarkupTagHelperElement(tagHelperStartTag == null ? null : (InternalSyntax.MarkupTagHelperStartTagSyntax)tagHelperStartTag.Green, body.Node.ToGreenList(), tagHelperEndTag == null ? null : (InternalSyntax.MarkupTagHelperEndTagSyntax)tagHelperEndTag.Green, tagHelperInfo).CreateRed();
/// Creates a new MarkupTagHelperElementSyntax instance.
- public static MarkupTagHelperElementSyntax MarkupTagHelperElement(MarkupTagHelperStartTagSyntax startTag, TagHelperInfo tagHelperInfo)
- => SyntaxFactory.MarkupTagHelperElement(startTag, default(SyntaxList), default(MarkupTagHelperEndTagSyntax), tagHelperInfo);
+ public static MarkupTagHelperElementSyntax MarkupTagHelperElement(TagHelperInfo tagHelperInfo)
+ => SyntaxFactory.MarkupTagHelperElement(default(MarkupTagHelperStartTagSyntax), default(SyntaxList), default(MarkupTagHelperEndTagSyntax), tagHelperInfo);
/// Creates a new MarkupTagHelperStartTagSyntax instance.
public static MarkupTagHelperStartTagSyntax MarkupTagHelperStartTag(SyntaxToken openAngle, SyntaxToken bang, SyntaxToken name, SyntaxList attributes, SyntaxToken forwardSlash, SyntaxToken closeAngle, ISpanChunkGenerator chunkGenerator, SpanEditHandler editHandler)
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Generated/Syntax.xml.Syntax.Generated.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Generated/Syntax.xml.Syntax.Generated.cs
index 0696c0dd066..b09a3a135a9 100644
--- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Generated/Syntax.xml.Syntax.Generated.cs
+++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Generated/Syntax.xml.Syntax.Generated.cs
@@ -795,47 +795,63 @@ internal BaseMarkupEndTagSyntax(GreenNode green, SyntaxNode parent, int position
public abstract SpanEditHandler EditHandler { get; }
}
-internal sealed partial class MarkupElementSyntax : MarkupSyntaxNode
+internal abstract partial class BaseMarkupElementSyntax : MarkupSyntaxNode
{
- private MarkupStartTagSyntax _startTag;
+ internal BaseMarkupElementSyntax(GreenNode green, SyntaxNode parent, int position)
+ : base(green, parent, position)
+ {
+ }
+
+ public abstract BaseMarkupStartTagSyntax StartTag { get; }
+ public BaseMarkupElementSyntax WithStartTag(BaseMarkupStartTagSyntax startTag) => WithStartTagCore(startTag);
+ internal abstract BaseMarkupElementSyntax WithStartTagCore(BaseMarkupStartTagSyntax startTag);
+
+ public abstract BaseMarkupEndTagSyntax EndTag { get; }
+ public BaseMarkupElementSyntax WithEndTag(BaseMarkupEndTagSyntax endTag) => WithEndTagCore(endTag);
+ internal abstract BaseMarkupElementSyntax WithEndTagCore(BaseMarkupEndTagSyntax endTag);
+}
+
+internal sealed partial class MarkupElementSyntax : BaseMarkupElementSyntax
+{
+ private MarkupStartTagSyntax _markupStartTag;
private SyntaxNode _body;
- private MarkupEndTagSyntax _endTag;
+ private MarkupEndTagSyntax _markupEndTag;
internal MarkupElementSyntax(GreenNode green, SyntaxNode parent, int position)
: base(green, parent, position)
{
}
- public MarkupStartTagSyntax StartTag => GetRedAtZero(ref _startTag);
+ public MarkupStartTagSyntax MarkupStartTag => GetRedAtZero(ref _markupStartTag);
public SyntaxList Body => new SyntaxList(GetRed(ref _body, 1));
- public MarkupEndTagSyntax EndTag => GetRed(ref _endTag, 2);
+ public MarkupEndTagSyntax MarkupEndTag => GetRed(ref _markupEndTag, 2);
internal override SyntaxNode GetNodeSlot(int index)
=> index switch
{
- 0 => GetRedAtZero(ref _startTag),
+ 0 => GetRedAtZero(ref _markupStartTag),
1 => GetRed(ref _body, 1),
- 2 => GetRed(ref _endTag, 2),
+ 2 => GetRed(ref _markupEndTag, 2),
_ => null
};
internal override SyntaxNode GetCachedSlot(int index)
=> index switch
{
- 0 => this._startTag,
+ 0 => this._markupStartTag,
1 => this._body,
- 2 => this._endTag,
+ 2 => this._markupEndTag,
_ => null
};
public override TResult Accept(SyntaxVisitor visitor) => visitor.VisitMarkupElement(this);
public override void Accept(SyntaxVisitor visitor) => visitor.VisitMarkupElement(this);
- public MarkupElementSyntax Update(MarkupStartTagSyntax startTag, SyntaxList body, MarkupEndTagSyntax endTag)
+ public MarkupElementSyntax Update(MarkupStartTagSyntax markupStartTag, SyntaxList body, MarkupEndTagSyntax markupEndTag)
{
- if (startTag != StartTag || body != Body || endTag != EndTag)
+ if (markupStartTag != MarkupStartTag || body != Body || markupEndTag != MarkupEndTag)
{
- var newNode = SyntaxFactory.MarkupElement(startTag, body, endTag);
+ var newNode = SyntaxFactory.MarkupElement(markupStartTag, body, markupEndTag);
var diagnostics = GetDiagnostics();
if (diagnostics != null && diagnostics.Length > 0)
newNode = newNode.WithDiagnostics(diagnostics);
@@ -845,9 +861,9 @@ public MarkupElementSyntax Update(MarkupStartTagSyntax startTag, SyntaxList Update(startTag, Body, EndTag);
- public MarkupElementSyntax WithBody(SyntaxList body) => Update(StartTag, body, EndTag);
- public MarkupElementSyntax WithEndTag(MarkupEndTagSyntax endTag) => Update(StartTag, Body, endTag);
+ public MarkupElementSyntax WithMarkupStartTag(MarkupStartTagSyntax markupStartTag) => Update(markupStartTag, Body, MarkupEndTag);
+ public MarkupElementSyntax WithBody(SyntaxList body) => Update(MarkupStartTag, body, MarkupEndTag);
+ public MarkupElementSyntax WithMarkupEndTag(MarkupEndTagSyntax markupEndTag) => Update(MarkupStartTag, Body, markupEndTag);
public MarkupElementSyntax AddBody(params RazorSyntaxNode[] items) => WithBody(this.Body.AddRange(items));
}
@@ -997,48 +1013,48 @@ public MarkupEndTagSyntax Update(SyntaxToken openAngle, SyntaxToken forwardSlash
}
}
-internal sealed partial class MarkupTagHelperElementSyntax : MarkupSyntaxNode
+internal sealed partial class MarkupTagHelperElementSyntax : BaseMarkupElementSyntax
{
- private MarkupTagHelperStartTagSyntax _startTag;
+ private MarkupTagHelperStartTagSyntax _tagHelperStartTag;
private SyntaxNode _body;
- private MarkupTagHelperEndTagSyntax _endTag;
+ private MarkupTagHelperEndTagSyntax _tagHelperEndTag;
internal MarkupTagHelperElementSyntax(GreenNode green, SyntaxNode parent, int position)
: base(green, parent, position)
{
}
- public MarkupTagHelperStartTagSyntax StartTag => GetRedAtZero(ref _startTag);
+ public MarkupTagHelperStartTagSyntax TagHelperStartTag => GetRedAtZero(ref _tagHelperStartTag);
public SyntaxList Body => new SyntaxList(GetRed(ref _body, 1));
- public MarkupTagHelperEndTagSyntax EndTag => GetRed(ref _endTag, 2);
+ public MarkupTagHelperEndTagSyntax TagHelperEndTag => GetRed(ref _tagHelperEndTag, 2);
public TagHelperInfo TagHelperInfo => ((InternalSyntax.MarkupTagHelperElementSyntax)Green).TagHelperInfo;
internal override SyntaxNode GetNodeSlot(int index)
=> index switch
{
- 0 => GetRedAtZero(ref _startTag),
+ 0 => GetRedAtZero(ref _tagHelperStartTag),
1 => GetRed(ref _body, 1),
- 2 => GetRed(ref _endTag, 2),
+ 2 => GetRed(ref _tagHelperEndTag, 2),
_ => null
};
internal override SyntaxNode GetCachedSlot(int index)
=> index switch
{
- 0 => this._startTag,
+ 0 => this._tagHelperStartTag,
1 => this._body,
- 2 => this._endTag,
+ 2 => this._tagHelperEndTag,
_ => null
};
public override TResult Accept(SyntaxVisitor visitor) => visitor.VisitMarkupTagHelperElement(this);
public override void Accept(SyntaxVisitor visitor) => visitor.VisitMarkupTagHelperElement(this);
- public MarkupTagHelperElementSyntax Update(MarkupTagHelperStartTagSyntax startTag, SyntaxList body, MarkupTagHelperEndTagSyntax endTag, TagHelperInfo tagHelperInfo)
+ public MarkupTagHelperElementSyntax Update(MarkupTagHelperStartTagSyntax tagHelperStartTag, SyntaxList body, MarkupTagHelperEndTagSyntax tagHelperEndTag, TagHelperInfo tagHelperInfo)
{
- if (startTag != StartTag || body != Body || endTag != EndTag)
+ if (tagHelperStartTag != TagHelperStartTag || body != Body || tagHelperEndTag != TagHelperEndTag)
{
- var newNode = SyntaxFactory.MarkupTagHelperElement(startTag, body, endTag, tagHelperInfo);
+ var newNode = SyntaxFactory.MarkupTagHelperElement(tagHelperStartTag, body, tagHelperEndTag, tagHelperInfo);
var diagnostics = GetDiagnostics();
if (diagnostics != null && diagnostics.Length > 0)
newNode = newNode.WithDiagnostics(diagnostics);
@@ -1048,12 +1064,10 @@ public MarkupTagHelperElementSyntax Update(MarkupTagHelperStartTagSyntax startTa
return this;
}
- public MarkupTagHelperElementSyntax WithStartTag(MarkupTagHelperStartTagSyntax startTag) => Update(startTag, Body, EndTag, TagHelperInfo);
- public MarkupTagHelperElementSyntax WithBody(SyntaxList body) => Update(StartTag, body, EndTag, TagHelperInfo);
- public MarkupTagHelperElementSyntax WithEndTag(MarkupTagHelperEndTagSyntax endTag) => Update(StartTag, Body, endTag, TagHelperInfo);
- public MarkupTagHelperElementSyntax WithTagHelperInfo(TagHelperInfo tagHelperInfo) => Update(StartTag, Body, EndTag, tagHelperInfo);
-
- public MarkupTagHelperElementSyntax AddStartTagAttributes(params RazorSyntaxNode[] items) => WithStartTag(this.StartTag.WithAttributes(this.StartTag.Attributes.AddRange(items)));
+ public MarkupTagHelperElementSyntax WithTagHelperStartTag(MarkupTagHelperStartTagSyntax tagHelperStartTag) => Update(tagHelperStartTag, Body, TagHelperEndTag, TagHelperInfo);
+ public MarkupTagHelperElementSyntax WithBody(SyntaxList body) => Update(TagHelperStartTag, body, TagHelperEndTag, TagHelperInfo);
+ public MarkupTagHelperElementSyntax WithTagHelperEndTag(MarkupTagHelperEndTagSyntax tagHelperEndTag) => Update(TagHelperStartTag, Body, tagHelperEndTag, TagHelperInfo);
+ public MarkupTagHelperElementSyntax WithTagHelperInfo(TagHelperInfo tagHelperInfo) => Update(TagHelperStartTag, Body, TagHelperEndTag, tagHelperInfo);
public MarkupTagHelperElementSyntax AddBody(params RazorSyntaxNode[] items) => WithBody(this.Body.AddRange(items));
}
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/InternalSyntax/MarkupElementSyntax.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/InternalSyntax/MarkupElementSyntax.cs
new file mode 100644
index 00000000000..3e591e91e5b
--- /dev/null
+++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/InternalSyntax/MarkupElementSyntax.cs
@@ -0,0 +1,13 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax;
+
+internal sealed partial class MarkupElementSyntax
+{
+ public override BaseMarkupStartTagSyntax StartTag
+ => MarkupStartTag;
+
+ public override BaseMarkupEndTagSyntax EndTag
+ => MarkupEndTag;
+}
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/InternalSyntax/MarkupTagHelperElementSyntax.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/InternalSyntax/MarkupTagHelperElementSyntax.cs
new file mode 100644
index 00000000000..b5c33af2880
--- /dev/null
+++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/InternalSyntax/MarkupTagHelperElementSyntax.cs
@@ -0,0 +1,13 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax;
+
+internal sealed partial class MarkupTagHelperElementSyntax
+{
+ public override BaseMarkupStartTagSyntax StartTag
+ => TagHelperStartTag;
+
+ public override BaseMarkupEndTagSyntax EndTag
+ => TagHelperEndTag;
+}
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupElementSyntax.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupElementSyntax.cs
new file mode 100644
index 00000000000..450b3125e59
--- /dev/null
+++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupElementSyntax.cs
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.AspNetCore.Razor.Language.Syntax;
+
+internal partial class MarkupElementSyntax
+{
+ public override BaseMarkupStartTagSyntax? StartTag
+ => MarkupStartTag;
+
+ internal override BaseMarkupElementSyntax WithStartTagCore(BaseMarkupStartTagSyntax startTag)
+ => WithMarkupStartTag((MarkupStartTagSyntax?)startTag);
+
+ public override BaseMarkupEndTagSyntax? EndTag
+ => MarkupEndTag;
+
+ internal override BaseMarkupElementSyntax WithEndTagCore(BaseMarkupEndTagSyntax endTag)
+ => WithMarkupEndTag((MarkupEndTagSyntax?)endTag);
+}
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupEndTagSyntax.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupEndTagSyntax.cs
index 4a67861b292..de4233c7801 100644
--- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupEndTagSyntax.cs
+++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupEndTagSyntax.cs
@@ -9,7 +9,4 @@ public string GetTagNameWithOptionalBang()
{
return Name.IsMissing ? string.Empty : Bang.Content + Name.Content;
}
-
- public override BaseMarkupStartTagSyntax? GetStartTag()
- => (Parent as MarkupElementSyntax)?.StartTag;
}
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupStartTagSyntax.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupStartTagSyntax.cs
index cdbfda38533..626e74e1680 100644
--- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupStartTagSyntax.cs
+++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupStartTagSyntax.cs
@@ -9,9 +9,4 @@ public string GetTagNameWithOptionalBang()
{
return Name.IsMissing ? string.Empty : Bang.Content + Name.Content;
}
-
- public override BaseMarkupEndTagSyntax? GetEndTag()
- {
- return (Parent as MarkupElementSyntax)?.EndTag;
- }
}
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupTagHelperElementSyntax.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupTagHelperElementSyntax.cs
new file mode 100644
index 00000000000..1320510f855
--- /dev/null
+++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupTagHelperElementSyntax.cs
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.AspNetCore.Razor.Language.Syntax;
+
+internal partial class MarkupTagHelperElementSyntax
+{
+ public override BaseMarkupStartTagSyntax? StartTag
+ => TagHelperStartTag;
+
+ internal override BaseMarkupElementSyntax WithStartTagCore(BaseMarkupStartTagSyntax startTag)
+ => WithTagHelperStartTag((MarkupTagHelperStartTagSyntax)startTag);
+
+ public override BaseMarkupEndTagSyntax? EndTag
+ => TagHelperEndTag;
+
+ internal override BaseMarkupElementSyntax WithEndTagCore(BaseMarkupEndTagSyntax endTag)
+ => WithTagHelperEndTag((MarkupTagHelperEndTagSyntax?)endTag);
+}
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupTagHelperEndTagSyntax.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupTagHelperEndTagSyntax.cs
deleted file mode 100644
index 60963eede1c..00000000000
--- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupTagHelperEndTagSyntax.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace Microsoft.AspNetCore.Razor.Language.Syntax;
-
-internal partial class MarkupTagHelperEndTagSyntax
-{
- public override BaseMarkupStartTagSyntax? GetStartTag()
- => (Parent as MarkupTagHelperElementSyntax)?.StartTag;
-}
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupTagHelperStartTagSyntax.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupTagHelperStartTagSyntax.cs
deleted file mode 100644
index 27f99eebe71..00000000000
--- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/MarkupTagHelperStartTagSyntax.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace Microsoft.AspNetCore.Razor.Language.Syntax;
-
-internal partial class MarkupTagHelperStartTagSyntax
-{
- public override BaseMarkupEndTagSyntax? GetEndTag()
- {
- return (Parent as MarkupTagHelperElementSyntax)?.EndTag;
- }
-}
diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Syntax.xml b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Syntax.xml
index 4aaf621fbf6..a59f3b8e54b 100644
--- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Syntax.xml
+++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Syntax/Syntax.xml
@@ -149,11 +149,15 @@
-
+
+
+
+
+
-
+
-
+
@@ -199,11 +203,11 @@
-
+
-
+
-
+
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/AutoInsert/AutoClosingTagOnAutoInsertProvider.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/AutoInsert/AutoClosingTagOnAutoInsertProvider.cs
index 9668fed1272..7edbb96be6e 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/AutoInsert/AutoClosingTagOnAutoInsertProvider.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/AutoInsert/AutoClosingTagOnAutoInsertProvider.cs
@@ -196,15 +196,10 @@ private static bool CouldAutoCloseParentOrSelf(string currentTagName, RazorSynta
{
string? potentialStartTagName = null;
RazorSyntaxNode? endTag = null;
- if (node is MarkupTagHelperElementSyntax parentTagHelper)
+ if (node is BaseMarkupElementSyntax element)
{
- potentialStartTagName = parentTagHelper.StartTag?.Name.Content ?? parentTagHelper.EndTag?.Name.Content;
- endTag = parentTagHelper.EndTag;
- }
- else if (node is MarkupElementSyntax parentElement)
- {
- potentialStartTagName = parentElement.StartTag?.Name.Content ?? parentElement.EndTag?.Name.Content;
- endTag = parentElement.EndTag;
+ potentialStartTagName = element.StartTag?.Name.Content ?? element.EndTag?.Name.Content;
+ endTag = element.EndTag;
}
// Note - potentialStartTagName can be null for cases when markup element is contained in markup
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/Razor/ComponentAccessibilityCodeActionProvider.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/Razor/ComponentAccessibilityCodeActionProvider.cs
index ee690b6d1e9..f2e37f32a12 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/Razor/ComponentAccessibilityCodeActionProvider.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/Razor/ComponentAccessibilityCodeActionProvider.cs
@@ -206,14 +206,10 @@ private static async Task> FindMatchingTagHelpersA
// Get all data necessary for matching
var tagName = startTag.Name.Content;
string? parentTagName = null;
- if (startTag.Parent?.Parent is MarkupElementSyntax parentElement)
+ if (startTag.Parent?.Parent is BaseMarkupElementSyntax parentElement)
{
parentTagName = parentElement.StartTag?.Name.Content ?? parentElement.EndTag?.Name.Content;
}
- else if (startTag.Parent?.Parent is MarkupTagHelperElementSyntax parentTagHelperElement)
- {
- parentTagName = parentTagHelperElement.StartTag?.Name.Content ?? parentTagHelperElement.EndTag?.Name.Content;
- }
var attributes = TagHelperFacts.StringifyAttributes(startTag.Attributes);
@@ -297,7 +293,7 @@ private static WorkspaceEdit CreateRenameTagEdit(
textEdits.Add(startTagTextEdit);
- var endTag = (startTag.Parent as MarkupElementSyntax)?.EndTag;
+ var endTag = startTag.GetEndTag();
if (endTag != null)
{
var endTagTextEdit = LspFactory.CreateTextEdit(endTag.Name.GetRange(context.CodeDocument.Source), newTagName);
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/Razor/SimplifyFullyQualifiedComponentCodeActionProvider.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/Razor/SimplifyFullyQualifiedComponentCodeActionProvider.cs
index 7aeabc4e1c0..a1a738157a1 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/Razor/SimplifyFullyQualifiedComponentCodeActionProvider.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/Razor/SimplifyFullyQualifiedComponentCodeActionProvider.cs
@@ -41,12 +41,13 @@ public Task> ProvideAsync(RazorCodeAct
// Find the tag at the cursor position, if it's on the start tag (name portion) or end tag only.
var owner = syntaxRoot.FindInnermostNode(context.StartAbsoluteIndex, includeWhitespace: true) switch
{
- MarkupTagHelperStartTagSyntax startTag when startTag.Name.Span.Contains(context.StartAbsoluteIndex) => startTag.Parent,
+ MarkupTagHelperStartTagSyntax ownerStartTag when ownerStartTag.Name.Span.Contains(context.StartAbsoluteIndex) => ownerStartTag.Parent,
MarkupTagHelperEndTagSyntax endTag => endTag.Parent,
_ => null
};
- if (owner is not MarkupTagHelperElementSyntax markupElementSyntax)
+ if (owner is not MarkupTagHelperElementSyntax markupElementSyntax ||
+ markupElementSyntax.TagHelperStartTag is not { } startTag)
{
return SpecializedTasks.EmptyImmutableArray();
}
@@ -68,10 +69,10 @@ MarkupTagHelperStartTagSyntax startTag when startTag.Name.Span.Contains(context.
{
Namespace = @namespace,
ComponentName = componentName,
- StartTagSpanStart = markupElementSyntax.StartTag.Name.SpanStart,
- StartTagSpanEnd = markupElementSyntax.StartTag.Name.Span.End,
- EndTagSpanStart = markupElementSyntax.EndTag?.Name.SpanStart ?? -1,
- EndTagSpanEnd = markupElementSyntax.EndTag?.Name.Span.End ?? -1,
+ StartTagSpanStart = startTag.Name.SpanStart,
+ StartTagSpanEnd = startTag.Name.Span.End,
+ EndTagSpanStart = markupElementSyntax.TagHelperEndTag?.Name.SpanStart ?? -1,
+ EndTagSpanEnd = markupElementSyntax.TagHelperEndTag?.Name.Span.End ?? -1,
};
var resolutionParams = new RazorCodeActionResolutionParams()
@@ -94,7 +95,12 @@ private static bool HasDiagnosticsOnStartTag(MarkupTagHelperElementSyntax elemen
return false;
}
- var startTagSpan = element.StartTag.Span;
+ if (element.TagHelperStartTag is not { } startTag)
+ {
+ return false;
+ }
+
+ var startTagSpan = startTag.Span;
foreach (var diagnostic in context.Request.Context.Diagnostics)
{
if (diagnostic.Range is null)
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/Razor/SimplifyTagToSelfClosingCodeActionProvider.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/Razor/SimplifyTagToSelfClosingCodeActionProvider.cs
index 5afe590e988..4f7490ce536 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/Razor/SimplifyTagToSelfClosingCodeActionProvider.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/CodeActions/Razor/SimplifyTagToSelfClosingCodeActionProvider.cs
@@ -50,7 +50,9 @@ public Task> ProvideAsync(RazorCodeAct
}
var owner = syntaxTree.Root.FindInnermostNode(context.StartAbsoluteIndex, includeWhitespace: false)?.FirstAncestorOrSelf();
- if (owner is not MarkupTagHelperElementSyntax markupElementSyntax)
+ if (owner is not MarkupTagHelperElementSyntax markupElementSyntax ||
+ markupElementSyntax.TagHelperStartTag is not { } startTag ||
+ markupElementSyntax.TagHelperEndTag is not { } endTag)
{
return SpecializedTasks.EmptyImmutableArray();
}
@@ -64,8 +66,8 @@ public Task> ProvideAsync(RazorCodeAct
// Provide code action to simplify
var actionParams = new SimplifyTagToSelfClosingCodeActionParams
{
- StartTagCloseAngleIndex = markupElementSyntax.StartTag.CloseAngle.SpanStart,
- EndTagCloseAngleIndex = markupElementSyntax.EndTag.CloseAngle.EndPosition,
+ StartTagCloseAngleIndex = startTag.CloseAngle.SpanStart,
+ EndTagCloseAngleIndex = endTag.CloseAngle.EndPosition,
};
var resolutionParams = new RazorCodeActionResolutionParams()
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/Delegation/DelegatedCompletionHelper.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/Delegation/DelegatedCompletionHelper.cs
index 33932af8231..d0c384f02f4 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/Delegation/DelegatedCompletionHelper.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Completion/Delegation/DelegatedCompletionHelper.cs
@@ -253,7 +253,7 @@ static bool IsInScriptOrStyleOrHtmlComment(AspNetCore.Razor.Language.Syntax.Synt
{
for (var node = initialNode; node != null; node = node.Parent)
{
- if (node is MarkupElementSyntax elementNode)
+ if (node is BaseMarkupElementSyntax elementNode)
{
if (RazorSyntaxFacts.IsScriptOrStyleBlock(elementNode))
{
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Diagnostics/RazorTranslateDiagnosticsService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Diagnostics/RazorTranslateDiagnosticsService.cs
index ac2ece1272b..f733380b229 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Diagnostics/RazorTranslateDiagnosticsService.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Diagnostics/RazorTranslateDiagnosticsService.cs
@@ -291,7 +291,7 @@ static bool IsAtCSharpTransitionInStyleBlock(LspDiagnostic diagnostic, SourceTex
return false;
}
- return owner.FirstAncestorOrSelf(static n => n.StartTag?.Name.Content == "style") is not null;
+ return owner.FirstAncestorOrSelf(static n => n.StartTag?.Name.Content == "style") is not null;
}
// Ideally this would be solved instead by not emitting the "!" at the HTML backing file,
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingVisitor.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingVisitor.cs
index 0c9ccdd2600..5a392347cbb 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingVisitor.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/FormattingVisitor.cs
@@ -289,6 +289,11 @@ static bool ParentHasProperty(MarkupTagHelperElementSyntax parentComponent, stri
static bool HasUnspecifiedCascadingTypeParameter(MarkupTagHelperElementSyntax node)
{
+ if (node.TagHelperStartTag is not { } startTag)
+ {
+ return false;
+ }
+
if (node.TagHelperInfo.BindingResult.TagHelpers is not { Count: > 0 } descriptors)
{
return false;
@@ -308,7 +313,7 @@ static bool HasUnspecifiedCascadingTypeParameter(MarkupTagHelperElementSyntax no
// Get all type parameters for later use. Array is fine to use as the list should be tiny (I hope!!)
var typeParameterNames = descriptors.SelectMany(d => d.GetTypeParameters().Select(p => p.Name)).ToArray();
- var attributes = node.StartTag.Attributes.OfType();
+ var attributes = startTag.Attributes.OfType();
foreach (var attribute in attributes)
{
if (attribute.TagHelperAttributeInfo.Bound)
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs
index 4810ce22df5..5270996e5f1 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/CSharpFormattingPass.CSharpDocumentGenerator.cs
@@ -561,31 +561,42 @@ private LineInfo VisitCSharpLiteral(RazorSyntaxNode node, RazorSyntaxToken lastT
public override LineInfo VisitMarkupStartTag(MarkupStartTagSyntax node)
{
- var element = (MarkupElementSyntax)node.Parent;
+ return VisitStartTag(node);
+ }
+ public override LineInfo VisitMarkupTagHelperStartTag(MarkupTagHelperStartTagSyntax node)
+ {
+ return VisitStartTag(node);
+ }
+
+ private LineInfo VisitStartTag(BaseMarkupStartTagSyntax node)
+ {
+ var closeAngle = node.GetEndTag()?.CloseAngle ?? node.CloseAngle;
if (ElementHasSignificantWhitespace(node))
{
// The contents of some html tags is significant, so we never want any formatting to happen in their contents
if (GetLineNumber(node) == GetLineNumber(node.CloseAngle))
{
- _ignoreUntilLine = GetLineNumber(element.EndTag?.CloseAngle ?? element.StartTag.CloseAngle);
+ _ignoreUntilLine = GetLineNumber(closeAngle);
}
return EmitCurrentLineAsComment();
}
- var result = VisitStartTag(node);
+ var lineInfo = ElementCausesIndentation(node)
+ ? EmitOpenBraceLine() // When an element causes indentation, we emit an open brace to tell the C# formatter to indent.
+ : EmitCurrentLineAsComment(); // This is a single line element, so it doesn't cause indentation
- if (RazorSyntaxFacts.IsScriptOrStyleBlock(element) &&
+ if (RazorSyntaxFacts.IsScriptOrStyleBlock(node.ParentElement) &&
_honourHtmlFormattingUntilLine is null)
{
// If this is an element at the root level, we want to record where it ends. We can't rely on the Visit method
// for it, because it might not be at the start of a line. We only care about contents though, so thats why
// we are doing this after emitting this line, and subtracting one from the end element line number.
- _honourHtmlFormattingUntilLine = GetLineNumber(element.EndTag?.CloseAngle ?? element.StartTag.CloseAngle) - 1;
+ _honourHtmlFormattingUntilLine = GetLineNumber(closeAngle) - 1;
}
- return result;
+ return lineInfo;
}
public override LineInfo VisitMarkupEndTag(MarkupEndTagSyntax node)
@@ -593,6 +604,11 @@ public override LineInfo VisitMarkupEndTag(MarkupEndTagSyntax node)
return VisitEndTag(node);
}
+ public override LineInfo VisitMarkupTagHelperEndTag(MarkupTagHelperEndTagSyntax node)
+ {
+ return VisitEndTag(node);
+ }
+
private LineInfo VisitEndTag(BaseMarkupEndTagSyntax node)
{
// End tags are emited as close braces, to remove the indent their start tag caused. We don't need to worry
@@ -616,23 +632,6 @@ private LineInfo VisitEndTag(BaseMarkupEndTagSyntax node)
return CreateLineInfo();
}
- public override LineInfo VisitMarkupTagHelperStartTag(MarkupTagHelperStartTagSyntax node)
- {
- return VisitStartTag(node);
- }
-
- private LineInfo VisitStartTag(BaseMarkupStartTagSyntax node)
- {
- if (ElementCausesIndentation(node))
- {
- // When an element causes indentation, we emit an open brace to tell the C# formatter to indent.
- return EmitOpenBraceLine();
- }
-
- // This is a single line element, so it doesn't cause indentation
- return EmitCurrentLineAsComment();
- }
-
private bool ElementCausesIndentation(BaseMarkupStartTagSyntax node)
{
if (node.Name.Content.Equals("html", StringComparison.OrdinalIgnoreCase))
@@ -796,11 +795,6 @@ private void GetAttributeIndentation(BaseMarkupStartTagSyntax startTag, out int
}
}
- public override LineInfo VisitMarkupTagHelperEndTag(MarkupTagHelperEndTagSyntax node)
- {
- return VisitEndTag(node);
- }
-
public override LineInfo VisitMarkupTransition(MarkupTransitionSyntax node)
{
// A transition to Html means the start of a RenderFragment. These are challenging because conceptually
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/HtmlFormattingPass.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/HtmlFormattingPass.cs
index af8ad21b570..7f667d39e8f 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/HtmlFormattingPass.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Formatting/Passes/HtmlFormattingPass.cs
@@ -268,7 +268,9 @@ private static (ImmutableArray ScriptAndStyleSpans, ImmutableArray ScriptAndStyleSpans, ImmutableArray", then the contents end at the start of the line, so
// we are free to modify the whitespace in front of the end tag. If the last line is " foo();"
// however, then we want the Html formatter to be in charge of the whitespace, so the contents end at the "f";
- var endTagLine = sourceText.Lines.GetLineFromPosition(element.EndTag.SpanStart);
+ var endTagLine = sourceText.Lines.GetLineFromPosition(endTag.SpanStart);
var firstNonWhitespace = endTagLine.GetFirstNonWhitespacePosition();
- var end = firstNonWhitespace == element.EndTag.SpanStart
+ var end = firstNonWhitespace == endTag.SpanStart
? endTagLine.Start
: firstNonWhitespace.GetValueOrDefault() + 1;
- scriptStyleBuilder.Add(TextSpan.FromBounds(element.StartTag.EndPosition, end));
+ scriptStyleBuilder.Add(TextSpan.FromBounds(startTag.EndPosition, end));
}
else if (node is RazorCommentBlockSyntax comment &&
comment.GetLinePositionSpan(codeDocument.Source).SpansMultipleLines())
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/LinkedEditingRange/LinkedEditingRangeHelper.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/LinkedEditingRange/LinkedEditingRangeHelper.cs
index 655729f714b..74d344cd27b 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/LinkedEditingRange/LinkedEditingRangeHelper.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/LinkedEditingRange/LinkedEditingRangeHelper.cs
@@ -57,24 +57,14 @@ private static bool TryGetNearestMarkupNameTokens(
return false;
}
- switch (element)
+ if (element is BaseMarkupElementSyntax { StartTag: var startTag, EndTag: var endTag })
{
- // Tag helper
- case MarkupTagHelperElementSyntax { StartTag: var startTag, EndTag: var endTag }:
- startTagNameToken = startTag?.Name ?? default;
- endTagNameToken = endTag?.Name ?? default;
+ startTagNameToken = startTag?.Name ?? default;
+ endTagNameToken = endTag?.Name ?? default;
- return startTagNameToken.IsValid() && endTagNameToken.IsValid();
-
- // HTML
- case MarkupElementSyntax { StartTag: var startTag, EndTag: var endTag }:
- startTagNameToken = startTag?.Name ?? default;
- endTagNameToken = endTag?.Name ?? default;
-
- return startTagNameToken.IsValid() && endTagNameToken.IsValid();
-
- default:
- throw new InvalidOperationException("Element is expected to be a MarkupTagHelperElement or MarkupElement.");
+ return startTagNameToken.IsValid() && endTagNameToken.IsValid();
}
+
+ throw new InvalidOperationException("Element is expected to be a MarkupTagHelperElement or MarkupElement.");
}
}
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/RazorSyntaxFacts.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/RazorSyntaxFacts.cs
index ed90d0f6bda..81f037ae994 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/RazorSyntaxFacts.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/RazorSyntaxFacts.cs
@@ -198,7 +198,7 @@ internal static bool IsInUsingDirective(RazorSyntaxNode node)
return node.AncestorsAndSelf().OfType().Any();
}
- internal static bool IsScriptOrStyleBlock(MarkupElementSyntax? element)
+ internal static bool IsScriptOrStyleBlock(BaseMarkupElementSyntax? element)
{
// StartTag is annotated as not nullable, but on invalid documents it can be. The 'Format_DocumentWithDiagnostics' test
// illustrates this.
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SpellCheck/SpellCheckService.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SpellCheck/SpellCheckService.cs
index d09ba4722d4..6cd7c0b99fa 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SpellCheck/SpellCheckService.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/SpellCheck/SpellCheckService.cs
@@ -49,7 +49,7 @@ private static void AddRazorSpellCheckRanges(ref PooledArrayBuilder n is not MarkupElementSyntax { StartTag.Name.Content: "script" or "style" }))
+ foreach (var node in syntaxTree.Root.DescendantNodes(static n => n is not BaseMarkupElementSyntax element || !RazorSyntaxFacts.IsScriptOrStyleBlock(element)))
{
if (node is RazorCommentBlockSyntax commentBlockSyntax)
{
diff --git a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperFacts.cs b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperFacts.cs
index 1c3b53a4363..bb25e25d17f 100644
--- a/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperFacts.cs
+++ b/src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/TagHelperFacts.cs
@@ -196,21 +196,11 @@ public static (string? ancestorTagName, bool ancestorIsTagHelper) GetNearestAnce
{
foreach (var ancestor in ancestors)
{
- switch (ancestor)
+ if (ancestor is BaseMarkupElementSyntax { StartTag: var startTag })
{
- case MarkupElementSyntax { StartTag: var startTag }:
- {
- // It's possible for start tag to be null in malformed cases.
- var name = startTag?.Name.Content ?? string.Empty;
- return (name, ancestorIsTagHelper: false);
- }
-
- case MarkupTagHelperElementSyntax { StartTag: var startTag }:
- {
- // It's possible for start tag to be null in malformed cases.
- var name = startTag?.Name.Content ?? string.Empty;
- return (name, ancestorIsTagHelper: true);
- }
+ // It's possible for start tag to be null in malformed cases.
+ var name = startTag?.Name.Content ?? string.Empty;
+ return (name, ancestorIsTagHelper: ancestor is MarkupTagHelperElementSyntax);
}
}
diff --git a/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.Test/Formatting/DocumentFormattingTest.cs b/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.Test/Formatting/DocumentFormattingTest.cs
index 64f6a2f29f0..f97c2a89696 100644
--- a/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.Test/Formatting/DocumentFormattingTest.cs
+++ b/src/Razor/test/Microsoft.CodeAnalysis.Razor.CohostingShared.Test/Formatting/DocumentFormattingTest.cs
@@ -12242,6 +12242,151 @@ @using System
""",
validateHtmlFormattedMatchesWebTools: false);
+ [Theory]
+ [CombinatorialData]
+ public Task ScriptTagTagHelper(bool scriptTagHelper)
+ {
+ var directive = scriptTagHelper
+ ? "@addTagHelper *, SomeProject"
+ : "";
+ return RunFormattingTestAsync(
+ input: $$"""
+ {{directive}}
+
+
+ """,
+ htmlFormatted: $$"""
+ {{directive}}
+
+
+ """,
+ expected: $$"""
+ {{directive}}
+
+
+ """,
+ validateHtmlFormattedMatchesWebTools: false, // We don't have JS formatting in tests, so the method param wouldn't really move
+ fileKind: RazorFileKind.Legacy,
+ additionalFiles:
+ [
+ (FilePath("ScriptTagHelper.cs"), """
+ using Microsoft.AspNetCore.Razor.TagHelpers;
+
+ [HtmlTargetElement("script")]
+ public class ScriptTagHelper : TagHelper
+ {
+ }
+ """)
+ ]);
+ }
+
+ [Theory]
+ [CombinatorialData]
+ public Task VoidTagTagHelper(bool useTagHelper)
+ {
+ var directive = useTagHelper
+ ? "@addTagHelper *, SomeProject"
+ : "";
+ return RunFormattingTestAsync(
+ input: $$"""
+ {{directive}}
+
+
+
+ This shouldn't be indented.
+
+
+ Neither should this
+
+ """,
+ htmlFormatted: $$"""
+ {{directive}}
+
+
+
+ This shouldn't be indented.
+
+
+ Neither should this
+
+ """,
+ expected: $$"""
+ {{directive}}
+
+
+
+ This shouldn't be indented.
+
+
+ Neither should this
+
+ """,
+ validateHtmlFormattedMatchesWebTools: false,
+ fileKind: RazorFileKind.Legacy,
+ additionalFiles:
+ [
+ (FilePath("InputTagHelper.cs"), """
+ using Microsoft.AspNetCore.Razor.TagHelpers;
+
+ [HtmlTargetElement("input")]
+ public class InputTagHelper : TagHelper
+ {
+ }
+ """)
+ ]);
+ }
+
private static RazorCSharpSyntaxFormattingOptions GetNewLineBeforeBraceInLambdaExpressionOptions(bool newLineBeforeBraceInLambda)
=> RazorCSharpSyntaxFormattingOptions.Default with
{