From e6b8c86a4832c0999d334f58f17750853a265e08 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Thu, 17 Jan 2019 13:38:17 -0800 Subject: [PATCH] Better structure for Tag helper start/end tags (dotnet/aspnetcore-tooling#132) \n\nCommit migrated from https://github.com/dotnet/aspnetcore-tooling/commit/f6ab4cc1d1883def0df35ad0ac6486c03c263941 --- .../src/ClassifiedSpanVisitor.cs | 2 +- ...faultRazorIntermediateNodeLoweringPhase.cs | 4 +- .../src/Legacy/TagHelperBlockRewriter.cs | 62 ++-- .../src/Legacy/TagHelperParseTreeRewriter.cs | 68 +---- .../Syntax.xml.Internal.Generated.cs | 288 +++++++++++++++--- .../Generated/Syntax.xml.Main.Generated.cs | 129 +++++++- .../Generated/Syntax.xml.Syntax.Generated.cs | 227 +++++++++++--- .../src/Syntax/Syntax.xml | 38 ++- .../src/Syntax/SyntaxSerializer.cs | 2 + .../Language/Legacy/SyntaxNodeWriter.cs | 2 + 10 files changed, 620 insertions(+), 202 deletions(-) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanVisitor.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanVisitor.cs index 46d69157f9..73f5d1fa11 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanVisitor.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/ClassifiedSpanVisitor.cs @@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.Razor.Language public override void VisitMarkupTagHelperStartTag(MarkupTagHelperStartTagSyntax node) { - foreach (var child in node.Children) + foreach (var child in node.Attributes) { if (child is MarkupTagHelperAttributeSyntax attribute) { diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorIntermediateNodeLoweringPhase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorIntermediateNodeLoweringPhase.cs index b92fea9890..9e0a0c0cf2 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorIntermediateNodeLoweringPhase.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/DefaultRazorIntermediateNodeLoweringPhase.cs @@ -870,7 +870,7 @@ namespace Microsoft.AspNetCore.Razor.Language public override void VisitMarkupTagHelperStartTag(MarkupTagHelperStartTagSyntax node) { - foreach (var child in node.Children) + foreach (var child in node.Attributes) { if (child is MarkupTagHelperAttributeSyntax || child is MarkupMinimizedTagHelperAttributeSyntax) { @@ -1587,7 +1587,7 @@ namespace Microsoft.AspNetCore.Razor.Language public override void VisitMarkupTagHelperStartTag(MarkupTagHelperStartTagSyntax node) { - foreach (var child in node.Children) + foreach (var child in node.Attributes) { if (child is MarkupTagHelperAttributeSyntax || child is MarkupMinimizedTagHelperAttributeSyntax) { diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperBlockRewriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperBlockRewriter.cs index 23a0a488a1..ebf32e9f70 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperBlockRewriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperBlockRewriter.cs @@ -10,21 +10,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy { internal static class TagHelperBlockRewriter { - public static MarkupTagHelperStartTagSyntax Rewrite( - string tagName, - bool validStructure, - RazorParserFeatureFlags featureFlags, - MarkupStartTagSyntax tag, - TagHelperBinding bindingResult, - ErrorSink errorSink, - RazorSourceDocument source) - { - // There will always be at least one child for the '<'. - var rewrittenChildren = GetRewrittenChildren(tagName, validStructure, tag, bindingResult, featureFlags, errorSink, source); - - return SyntaxFactory.MarkupTagHelperStartTag(rewrittenChildren); - } - public static TagMode GetTagMode( MarkupStartTagSyntax tagBlock, TagHelperBinding bindingResult, @@ -52,35 +37,23 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy return TagMode.StartTagAndEndTag; } - private static SyntaxList GetRewrittenChildren( + public static MarkupTagHelperStartTagSyntax Rewrite( string tagName, - bool validStructure, - MarkupStartTagSyntax tagBlock, - TagHelperBinding bindingResult, RazorParserFeatureFlags featureFlags, + MarkupStartTagSyntax startTag, + TagHelperBinding bindingResult, ErrorSink errorSink, RazorSourceDocument source) { - var tagHelperBuilder = SyntaxListBuilder.Create(); var processedBoundAttributeNames = new HashSet(StringComparer.OrdinalIgnoreCase); - if (tagBlock.Children.Count == 1) - { - // Tag with no attributes. We have nothing to rewrite here. - return tagBlock.Children; - } - - // Add the tag start - tagHelperBuilder.Add(tagBlock.Children.First()); - - // We skip the first child "" or "/>". - // If the tag does not have a valid structure then there's no close angle to ignore. - var tokenOffset = validStructure ? 1 : 0; - for (var i = 1; i < tagBlock.Children.Count - tokenOffset; i++) + var attributes = startTag.Attributes; + var attributeBuilder = SyntaxListBuilder.Create(); + for (var i = 0; i < startTag.Attributes.Count; i++) { var isMinimized = false; var attributeNameLocation = SourceLocation.Undefined; - var child = tagBlock.Children[i]; + var child = startTag.Attributes[i]; TryParseResult result; if (child is MarkupAttributeBlockSyntax attributeBlock) { @@ -91,7 +64,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy bindingResult.Descriptors, errorSink, processedBoundAttributeNames); - tagHelperBuilder.Add(result.RewrittenAttribute); + attributeBuilder.Add(result.RewrittenAttribute); } else if (child is MarkupMinimizedAttributeBlockSyntax minimizedAttributeBlock) { @@ -103,7 +76,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy bindingResult.Descriptors, errorSink, processedBoundAttributeNames); - tagHelperBuilder.Add(result.RewrittenAttribute); + attributeBuilder.Add(result.RewrittenAttribute); } else if (child is MarkupMiscAttributeContentSyntax miscContent) { @@ -146,12 +119,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy if (result == null) { // Error occurred while parsing the attribute. Don't try parsing the rest to avoid misleading errors. - for (var j = i; j < tagBlock.Children.Count; j++) + for (var j = i; j < startTag.Attributes.Count; j++) { - tagHelperBuilder.Add(tagBlock.Children[j]); + attributeBuilder.Add(startTag.Attributes[j]); } - return tagHelperBuilder.ToList(); + break; } // Check if it's a non-boolean bound attribute that is minimized or if it's a bound @@ -180,13 +153,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } } - if (validStructure) + if (attributeBuilder.Count > 0) { - // Add the tag end. - tagHelperBuilder.Add(tagBlock.Children[tagBlock.Children.Count - 1]); + // This means we rewrote something. Use the new set of attributes. + attributes = attributeBuilder.ToList(); } - return tagHelperBuilder.ToList(); + var tagHelperStartTag = SyntaxFactory.MarkupTagHelperStartTag( + startTag.OpenAngle, startTag.Bang, startTag.Name, attributes, startTag.ForwardSlash, startTag.CloseAngle); + + return tagHelperStartTag.WithSpanContext(startTag.GetSpanContext()); } private static TryParseResult TryParseMinimizedAttribute( 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 1619f42240..4b1d8355f5 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/TagHelperParseTreeRewriter.cs @@ -268,11 +268,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy ValidateBinding(tagHelperBinding, tagName, startTag); // We're in a start TagHelper block. - var validTagStructure = ValidateStartTagSyntax(tagName, startTag); + ValidateStartTagSyntax(tagName, startTag); var rewrittenStartTag = TagHelperBlockRewriter.Rewrite( tagName, - validTagStructure, _featureFlags, startTag, tagHelperBinding, @@ -354,7 +353,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } } - rewritten = SyntaxFactory.MarkupTagHelperEndTag(tagBlock.Children); + rewritten = SyntaxFactory.MarkupTagHelperEndTag( + tagBlock.OpenAngle, tagBlock.ForwardSlash, tagBlock.Bang, tagBlock.Name, tagBlock.MiscAttributeContent, tagBlock.CloseAngle); return true; } @@ -362,11 +362,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // Internal for testing internal IReadOnlyList> GetAttributeNameValuePairs(MarkupStartTagSyntax tagBlock) { - // Need to calculate how many children we should take that represent the attributes. - var childrenOffset = IsPartialStartTag(tagBlock) ? 0 : 1; - var childCount = tagBlock.Children.Count - childrenOffset; - - if (childCount <= 1) + if (tagBlock.Attributes.Count == 0) { return Array.Empty>(); } @@ -375,16 +371,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy var attributes = _htmlAttributeTracker; - for (var i = 1; i < childCount; i++) + for (var i = 0; i < tagBlock.Attributes.Count; i++) { - if (tagBlock.Children[i] is CSharpCodeBlockSyntax) + if (tagBlock.Attributes[i] is CSharpCodeBlockSyntax) { // Code blocks in the attribute area of tags mangles following attributes. // It's also not supported by TagHelpers, bail early to avoid creating bad attribute value pairs. break; } - if (tagBlock.Children[i] is MarkupMinimizedAttributeBlockSyntax minimizedAttributeBlock) + if (tagBlock.Attributes[i] is MarkupMinimizedAttributeBlockSyntax minimizedAttributeBlock) { if (minimizedAttributeBlock.Name == null) { @@ -397,7 +393,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy continue; } - if (!(tagBlock.Children[i] is MarkupAttributeBlockSyntax attributeBlock)) + if (!(tagBlock.Attributes[i] is MarkupAttributeBlockSyntax attributeBlock)) { // If the parser thought these aren't attributes, we don't care about them. Move on. continue; @@ -525,46 +521,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy !endTag.IsMarkupTransition; } - private static bool IsPartialStartTag(MarkupStartTagSyntax tagBlock) + private static bool IsPartialStartTag(MarkupStartTagSyntax startTag) { - // No need to validate the tag end because in order to be a tag block it must start with '<'. - var tagEnd = tagBlock.Children[tagBlock.Children.Count - 1]; - - // If our tag end is not a markup span it means it's some sort of code SyntaxTreeNode (not a valid format) - if (tagEnd != null && tagEnd is MarkupTextLiteralSyntax tagEndLiteral) - { - var endToken = tagEndLiteral.LiteralTokens.Count > 0 ? - tagEndLiteral.LiteralTokens[tagEndLiteral.LiteralTokens.Count - 1] : - null; - - if (endToken != null && endToken.Kind == SyntaxKind.CloseAngle) - { - return false; - } - } - - return true; + return startTag.CloseAngle.IsMissing; } - private static bool IsPartialEndTag(MarkupEndTagSyntax tagBlock) + private static bool IsPartialEndTag(MarkupEndTagSyntax endTag) { - // No need to validate the tag end because in order to be a tag block it must start with '<'. - var tagEnd = tagBlock.Children[tagBlock.Children.Count - 1]; - - // If our tag end is not a markup span it means it's some sort of code SyntaxTreeNode (not a valid format) - if (tagEnd != null && tagEnd is MarkupTextLiteralSyntax tagEndLiteral) - { - var endToken = tagEndLiteral.LiteralTokens.Count > 0 ? - tagEndLiteral.LiteralTokens[tagEndLiteral.LiteralTokens.Count - 1] : - null; - - if (endToken != null && endToken.Kind == SyntaxKind.CloseAngle) - { - return false; - } - } - - return true; + return endTag.CloseAngle.IsMissing; } private void ValidateParentAllowsContent(SyntaxNode child) @@ -608,9 +572,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy if (string.IsNullOrEmpty(tagName)) { var firstChild = tagBlock.Children.First(); - Debug.Assert(firstChild is MarkupTextLiteralSyntax || firstChild is MarkupTransitionSyntax); + Debug.Assert(firstChild is MarkupTextLiteralSyntax); - ValidateParentAllowsContent(tagBlock.Children.First()); + ValidateParentAllowsContent(firstChild); return; } @@ -641,9 +605,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy if (string.IsNullOrEmpty(tagName)) { var firstChild = tagBlock.Children.First(); - Debug.Assert(firstChild is MarkupTextLiteralSyntax || firstChild is MarkupTransitionSyntax); + Debug.Assert(firstChild is MarkupTextLiteralSyntax); - ValidateParentAllowsContent(tagBlock.Children.First()); + ValidateParentAllowsContent(firstChild); return; } diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Internal.Generated.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Internal.Generated.cs index 6c319e6d08..4fe3309e14 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Internal.Generated.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Internal.Generated.cs @@ -1816,40 +1816,87 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax } } - internal sealed partial class MarkupTagHelperStartTagSyntax : RazorBlockSyntax + internal sealed partial class MarkupTagHelperStartTagSyntax : MarkupSyntaxNode { - private readonly GreenNode _children; + private readonly SyntaxToken _openAngle; + private readonly SyntaxToken _bang; + private readonly SyntaxToken _name; + private readonly GreenNode _attributes; + private readonly SyntaxToken _forwardSlash; + private readonly SyntaxToken _closeAngle; - internal MarkupTagHelperStartTagSyntax(SyntaxKind kind, GreenNode children, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations) + internal MarkupTagHelperStartTagSyntax(SyntaxKind kind, SyntaxToken openAngle, SyntaxToken bang, SyntaxToken name, GreenNode attributes, SyntaxToken forwardSlash, SyntaxToken closeAngle, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations) : base(kind, diagnostics, annotations) { - SlotCount = 1; - if (children != null) + SlotCount = 6; + AdjustFlagsAndWidth(openAngle); + _openAngle = openAngle; + if (bang != null) { - AdjustFlagsAndWidth(children); - _children = children; + AdjustFlagsAndWidth(bang); + _bang = bang; } + AdjustFlagsAndWidth(name); + _name = name; + if (attributes != null) + { + AdjustFlagsAndWidth(attributes); + _attributes = attributes; + } + if (forwardSlash != null) + { + AdjustFlagsAndWidth(forwardSlash); + _forwardSlash = forwardSlash; + } + AdjustFlagsAndWidth(closeAngle); + _closeAngle = closeAngle; } - internal MarkupTagHelperStartTagSyntax(SyntaxKind kind, GreenNode children) + internal MarkupTagHelperStartTagSyntax(SyntaxKind kind, SyntaxToken openAngle, SyntaxToken bang, SyntaxToken name, GreenNode attributes, SyntaxToken forwardSlash, SyntaxToken closeAngle) : base(kind) { - SlotCount = 1; - if (children != null) + SlotCount = 6; + AdjustFlagsAndWidth(openAngle); + _openAngle = openAngle; + if (bang != null) { - AdjustFlagsAndWidth(children); - _children = children; + AdjustFlagsAndWidth(bang); + _bang = bang; } + AdjustFlagsAndWidth(name); + _name = name; + if (attributes != null) + { + AdjustFlagsAndWidth(attributes); + _attributes = attributes; + } + if (forwardSlash != null) + { + AdjustFlagsAndWidth(forwardSlash); + _forwardSlash = forwardSlash; + } + AdjustFlagsAndWidth(closeAngle); + _closeAngle = closeAngle; } - public override SyntaxList Children { get { return new SyntaxList(_children); } } + public SyntaxToken OpenAngle { get { return _openAngle; } } + public SyntaxToken Bang { get { return _bang; } } + public SyntaxToken Name { get { return _name; } } + public SyntaxList Attributes { get { return new SyntaxList(_attributes); } } + public SyntaxToken ForwardSlash { get { return _forwardSlash; } } + public SyntaxToken CloseAngle { get { return _closeAngle; } } internal override GreenNode GetSlot(int index) { switch (index) { - case 0: return _children; + case 0: return _openAngle; + case 1: return _bang; + case 2: return _name; + case 3: return _attributes; + case 4: return _forwardSlash; + case 5: return _closeAngle; default: return null; } } @@ -1869,11 +1916,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax visitor.VisitMarkupTagHelperStartTag(this); } - public MarkupTagHelperStartTagSyntax Update(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList children) + public MarkupTagHelperStartTagSyntax Update(SyntaxToken openAngle, SyntaxToken bang, SyntaxToken name, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList attributes, SyntaxToken forwardSlash, SyntaxToken closeAngle) { - if (children != Children) + if (openAngle != OpenAngle || bang != Bang || name != Name || attributes != Attributes || forwardSlash != ForwardSlash || closeAngle != CloseAngle) { - var newNode = SyntaxFactory.MarkupTagHelperStartTag(children); + var newNode = SyntaxFactory.MarkupTagHelperStartTag(openAngle, bang, name, attributes, forwardSlash, closeAngle); var diags = GetDiagnostics(); if (diags != null && diags.Length > 0) newNode = newNode.WithDiagnosticsGreen(diags); @@ -1888,49 +1935,90 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics) { - return new MarkupTagHelperStartTagSyntax(Kind, _children, diagnostics, GetAnnotations()); + return new MarkupTagHelperStartTagSyntax(Kind, _openAngle, _bang, _name, _attributes, _forwardSlash, _closeAngle, diagnostics, GetAnnotations()); } internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations) { - return new MarkupTagHelperStartTagSyntax(Kind, _children, GetDiagnostics(), annotations); + return new MarkupTagHelperStartTagSyntax(Kind, _openAngle, _bang, _name, _attributes, _forwardSlash, _closeAngle, GetDiagnostics(), annotations); } } - internal sealed partial class MarkupTagHelperEndTagSyntax : RazorBlockSyntax + internal sealed partial class MarkupTagHelperEndTagSyntax : MarkupSyntaxNode { - private readonly GreenNode _children; + private readonly SyntaxToken _openAngle; + private readonly SyntaxToken _forwardSlash; + private readonly SyntaxToken _bang; + private readonly SyntaxToken _name; + private readonly MarkupMiscAttributeContentSyntax _miscAttributeContent; + private readonly SyntaxToken _closeAngle; - internal MarkupTagHelperEndTagSyntax(SyntaxKind kind, GreenNode children, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations) + internal MarkupTagHelperEndTagSyntax(SyntaxKind kind, SyntaxToken openAngle, SyntaxToken forwardSlash, SyntaxToken bang, SyntaxToken name, MarkupMiscAttributeContentSyntax miscAttributeContent, SyntaxToken closeAngle, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations) : base(kind, diagnostics, annotations) { - SlotCount = 1; - if (children != null) + SlotCount = 6; + AdjustFlagsAndWidth(openAngle); + _openAngle = openAngle; + AdjustFlagsAndWidth(forwardSlash); + _forwardSlash = forwardSlash; + if (bang != null) { - AdjustFlagsAndWidth(children); - _children = children; + AdjustFlagsAndWidth(bang); + _bang = bang; } + AdjustFlagsAndWidth(name); + _name = name; + if (miscAttributeContent != null) + { + AdjustFlagsAndWidth(miscAttributeContent); + _miscAttributeContent = miscAttributeContent; + } + AdjustFlagsAndWidth(closeAngle); + _closeAngle = closeAngle; } - internal MarkupTagHelperEndTagSyntax(SyntaxKind kind, GreenNode children) + internal MarkupTagHelperEndTagSyntax(SyntaxKind kind, SyntaxToken openAngle, SyntaxToken forwardSlash, SyntaxToken bang, SyntaxToken name, MarkupMiscAttributeContentSyntax miscAttributeContent, SyntaxToken closeAngle) : base(kind) { - SlotCount = 1; - if (children != null) + SlotCount = 6; + AdjustFlagsAndWidth(openAngle); + _openAngle = openAngle; + AdjustFlagsAndWidth(forwardSlash); + _forwardSlash = forwardSlash; + if (bang != null) { - AdjustFlagsAndWidth(children); - _children = children; + AdjustFlagsAndWidth(bang); + _bang = bang; } + AdjustFlagsAndWidth(name); + _name = name; + if (miscAttributeContent != null) + { + AdjustFlagsAndWidth(miscAttributeContent); + _miscAttributeContent = miscAttributeContent; + } + AdjustFlagsAndWidth(closeAngle); + _closeAngle = closeAngle; } - public override SyntaxList Children { get { return new SyntaxList(_children); } } + public SyntaxToken OpenAngle { get { return _openAngle; } } + public SyntaxToken ForwardSlash { get { return _forwardSlash; } } + public SyntaxToken Bang { get { return _bang; } } + public SyntaxToken Name { get { return _name; } } + public MarkupMiscAttributeContentSyntax MiscAttributeContent { get { return _miscAttributeContent; } } + public SyntaxToken CloseAngle { get { return _closeAngle; } } internal override GreenNode GetSlot(int index) { switch (index) { - case 0: return _children; + case 0: return _openAngle; + case 1: return _forwardSlash; + case 2: return _bang; + case 3: return _name; + case 4: return _miscAttributeContent; + case 5: return _closeAngle; default: return null; } } @@ -1950,11 +2038,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax visitor.VisitMarkupTagHelperEndTag(this); } - public MarkupTagHelperEndTagSyntax Update(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList children) + public MarkupTagHelperEndTagSyntax Update(SyntaxToken openAngle, SyntaxToken forwardSlash, SyntaxToken bang, SyntaxToken name, MarkupMiscAttributeContentSyntax miscAttributeContent, SyntaxToken closeAngle) { - if (children != Children) + if (openAngle != OpenAngle || forwardSlash != ForwardSlash || bang != Bang || name != Name || miscAttributeContent != MiscAttributeContent || closeAngle != CloseAngle) { - var newNode = SyntaxFactory.MarkupTagHelperEndTag(children); + var newNode = SyntaxFactory.MarkupTagHelperEndTag(openAngle, forwardSlash, bang, name, miscAttributeContent, closeAngle); var diags = GetDiagnostics(); if (diags != null && diags.Length > 0) newNode = newNode.WithDiagnosticsGreen(diags); @@ -1969,12 +2057,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics) { - return new MarkupTagHelperEndTagSyntax(Kind, _children, diagnostics, GetAnnotations()); + return new MarkupTagHelperEndTagSyntax(Kind, _openAngle, _forwardSlash, _bang, _name, _miscAttributeContent, _closeAngle, diagnostics, GetAnnotations()); } internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations) { - return new MarkupTagHelperEndTagSyntax(Kind, _children, GetDiagnostics(), annotations); + return new MarkupTagHelperEndTagSyntax(Kind, _openAngle, _forwardSlash, _bang, _name, _miscAttributeContent, _closeAngle, GetDiagnostics(), annotations); } } @@ -3997,14 +4085,24 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax public override GreenNode VisitMarkupTagHelperStartTag(MarkupTagHelperStartTagSyntax node) { - var children = VisitList(node.Children); - return node.Update(children); + var openAngle = (SyntaxToken)Visit(node.OpenAngle); + var bang = (SyntaxToken)Visit(node.Bang); + var name = (SyntaxToken)Visit(node.Name); + var attributes = VisitList(node.Attributes); + var forwardSlash = (SyntaxToken)Visit(node.ForwardSlash); + var closeAngle = (SyntaxToken)Visit(node.CloseAngle); + return node.Update(openAngle, bang, name, attributes, forwardSlash, closeAngle); } public override GreenNode VisitMarkupTagHelperEndTag(MarkupTagHelperEndTagSyntax node) { - var children = VisitList(node.Children); - return node.Update(children); + var openAngle = (SyntaxToken)Visit(node.OpenAngle); + var forwardSlash = (SyntaxToken)Visit(node.ForwardSlash); + var bang = (SyntaxToken)Visit(node.Bang); + var name = (SyntaxToken)Visit(node.Name); + var miscAttributeContent = (MarkupMiscAttributeContentSyntax)Visit(node.MiscAttributeContent); + var closeAngle = (SyntaxToken)Visit(node.CloseAngle); + return node.Update(openAngle, forwardSlash, bang, name, miscAttributeContent, closeAngle); } public override GreenNode VisitMarkupTagHelperAttribute(MarkupTagHelperAttributeSyntax node) @@ -4421,18 +4519,112 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax return result; } - public static MarkupTagHelperStartTagSyntax MarkupTagHelperStartTag(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList children) + public static MarkupTagHelperStartTagSyntax MarkupTagHelperStartTag(SyntaxToken openAngle, SyntaxToken bang, SyntaxToken name, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList attributes, SyntaxToken forwardSlash, SyntaxToken closeAngle) { - var result = new MarkupTagHelperStartTagSyntax(SyntaxKind.MarkupTagHelperStartTag, children.Node); + if (openAngle == null) + throw new ArgumentNullException(nameof(openAngle)); + switch (openAngle.Kind) + { + case SyntaxKind.OpenAngle: + break; + default: + throw new ArgumentException("openAngle"); + } + if (bang != null) + { + switch (bang.Kind) + { + case SyntaxKind.Bang: + case SyntaxKind.None: + break; + default: + throw new ArgumentException("bang"); + } + } + if (name == null) + throw new ArgumentNullException(nameof(name)); + switch (name.Kind) + { + case SyntaxKind.Text: + break; + default: + throw new ArgumentException("name"); + } + if (forwardSlash != null) + { + switch (forwardSlash.Kind) + { + case SyntaxKind.ForwardSlash: + case SyntaxKind.None: + break; + default: + throw new ArgumentException("forwardSlash"); + } + } + if (closeAngle == null) + throw new ArgumentNullException(nameof(closeAngle)); + switch (closeAngle.Kind) + { + case SyntaxKind.CloseAngle: + break; + default: + throw new ArgumentException("closeAngle"); + } - return result; + return new MarkupTagHelperStartTagSyntax(SyntaxKind.MarkupTagHelperStartTag, openAngle, bang, name, attributes.Node, forwardSlash, closeAngle); } - public static MarkupTagHelperEndTagSyntax MarkupTagHelperEndTag(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList children) + public static MarkupTagHelperEndTagSyntax MarkupTagHelperEndTag(SyntaxToken openAngle, SyntaxToken forwardSlash, SyntaxToken bang, SyntaxToken name, MarkupMiscAttributeContentSyntax miscAttributeContent, SyntaxToken closeAngle) { - var result = new MarkupTagHelperEndTagSyntax(SyntaxKind.MarkupTagHelperEndTag, children.Node); + if (openAngle == null) + throw new ArgumentNullException(nameof(openAngle)); + switch (openAngle.Kind) + { + case SyntaxKind.OpenAngle: + break; + default: + throw new ArgumentException("openAngle"); + } + if (forwardSlash == null) + throw new ArgumentNullException(nameof(forwardSlash)); + switch (forwardSlash.Kind) + { + case SyntaxKind.ForwardSlash: + break; + default: + throw new ArgumentException("forwardSlash"); + } + if (bang != null) + { + switch (bang.Kind) + { + case SyntaxKind.Bang: + case SyntaxKind.None: + break; + default: + throw new ArgumentException("bang"); + } + } + if (name == null) + throw new ArgumentNullException(nameof(name)); + switch (name.Kind) + { + case SyntaxKind.Text: + break; + default: + throw new ArgumentException("name"); + } + if (closeAngle == null) + throw new ArgumentNullException(nameof(closeAngle)); + switch (closeAngle.Kind) + { + case SyntaxKind.CloseAngle: + break; + default: + throw new ArgumentException("closeAngle"); + } - return result; + return new MarkupTagHelperEndTagSyntax(SyntaxKind.MarkupTagHelperEndTag, openAngle, forwardSlash, bang, name, miscAttributeContent, closeAngle); } public static MarkupTagHelperAttributeSyntax MarkupTagHelperAttribute(MarkupTextLiteralSyntax namePrefix, MarkupTextLiteralSyntax name, MarkupTextLiteralSyntax nameSuffix, SyntaxToken equalsToken, MarkupTextLiteralSyntax valuePrefix, MarkupTagHelperAttributeValueSyntax value, MarkupTextLiteralSyntax valueSuffix) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Main.Generated.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Main.Generated.cs index c33baf1f06..cf1c0aa0a8 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Main.Generated.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Main.Generated.cs @@ -616,14 +616,24 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax public override SyntaxNode VisitMarkupTagHelperStartTag(MarkupTagHelperStartTagSyntax node) { - var children = VisitList(node.Children); - return node.Update(children); + var openAngle = (SyntaxToken)VisitToken(node.OpenAngle); + var bang = (SyntaxToken)VisitToken(node.Bang); + var name = (SyntaxToken)VisitToken(node.Name); + var attributes = VisitList(node.Attributes); + var forwardSlash = (SyntaxToken)VisitToken(node.ForwardSlash); + var closeAngle = (SyntaxToken)VisitToken(node.CloseAngle); + return node.Update(openAngle, bang, name, attributes, forwardSlash, closeAngle); } public override SyntaxNode VisitMarkupTagHelperEndTag(MarkupTagHelperEndTagSyntax node) { - var children = VisitList(node.Children); - return node.Update(children); + var openAngle = (SyntaxToken)VisitToken(node.OpenAngle); + var forwardSlash = (SyntaxToken)VisitToken(node.ForwardSlash); + var bang = (SyntaxToken)VisitToken(node.Bang); + var name = (SyntaxToken)VisitToken(node.Name); + var miscAttributeContent = (MarkupMiscAttributeContentSyntax)Visit(node.MiscAttributeContent); + var closeAngle = (SyntaxToken)VisitToken(node.CloseAngle); + return node.Update(openAngle, forwardSlash, bang, name, miscAttributeContent, closeAngle); } public override SyntaxNode VisitMarkupTagHelperAttribute(MarkupTagHelperAttributeSyntax node) @@ -999,6 +1009,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax default: throw new ArgumentException("openAngle"); } + if (bang != null) + { switch (bang.Kind) { case SyntaxKind.Bang: @@ -1007,6 +1019,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax default: throw new ArgumentException("bang"); } + } switch (name.Kind) { case SyntaxKind.Text: @@ -1014,6 +1027,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax default: throw new ArgumentException("name"); } + if (forwardSlash != null) + { switch (forwardSlash.Kind) { case SyntaxKind.ForwardSlash: @@ -1022,6 +1037,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax default: throw new ArgumentException("forwardSlash"); } + } switch (closeAngle.Kind) { case SyntaxKind.CloseAngle: @@ -1029,7 +1045,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax default: throw new ArgumentException("closeAngle"); } - return (MarkupStartTagSyntax)InternalSyntax.SyntaxFactory.MarkupStartTag((Syntax.InternalSyntax.SyntaxToken)openAngle.Green, (Syntax.InternalSyntax.SyntaxToken)bang.Green, (Syntax.InternalSyntax.SyntaxToken)name.Green, attributes.Node.ToGreenList(), (Syntax.InternalSyntax.SyntaxToken)forwardSlash.Green, (Syntax.InternalSyntax.SyntaxToken)closeAngle.Green).CreateRed(); + return (MarkupStartTagSyntax)InternalSyntax.SyntaxFactory.MarkupStartTag((Syntax.InternalSyntax.SyntaxToken)openAngle.Green, (Syntax.InternalSyntax.SyntaxToken)bang?.Green, (Syntax.InternalSyntax.SyntaxToken)name.Green, attributes.Node.ToGreenList(), (Syntax.InternalSyntax.SyntaxToken)forwardSlash?.Green, (Syntax.InternalSyntax.SyntaxToken)closeAngle.Green).CreateRed(); } /// Creates a new MarkupStartTagSyntax instance. @@ -1055,6 +1071,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax default: throw new ArgumentException("forwardSlash"); } + if (bang != null) + { switch (bang.Kind) { case SyntaxKind.Bang: @@ -1063,6 +1081,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax default: throw new ArgumentException("bang"); } + } switch (name.Kind) { case SyntaxKind.Text: @@ -1077,7 +1096,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax default: throw new ArgumentException("closeAngle"); } - return (MarkupEndTagSyntax)InternalSyntax.SyntaxFactory.MarkupEndTag((Syntax.InternalSyntax.SyntaxToken)openAngle.Green, (Syntax.InternalSyntax.SyntaxToken)forwardSlash.Green, (Syntax.InternalSyntax.SyntaxToken)bang.Green, (Syntax.InternalSyntax.SyntaxToken)name.Green, miscAttributeContent == null ? null : (InternalSyntax.MarkupMiscAttributeContentSyntax)miscAttributeContent.Green, (Syntax.InternalSyntax.SyntaxToken)closeAngle.Green).CreateRed(); + return (MarkupEndTagSyntax)InternalSyntax.SyntaxFactory.MarkupEndTag((Syntax.InternalSyntax.SyntaxToken)openAngle.Green, (Syntax.InternalSyntax.SyntaxToken)forwardSlash.Green, (Syntax.InternalSyntax.SyntaxToken)bang?.Green, (Syntax.InternalSyntax.SyntaxToken)name.Green, miscAttributeContent == null ? null : (InternalSyntax.MarkupMiscAttributeContentSyntax)miscAttributeContent.Green, (Syntax.InternalSyntax.SyntaxToken)closeAngle.Green).CreateRed(); } /// Creates a new MarkupEndTagSyntax instance. @@ -1101,27 +1120,109 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax } /// Creates a new MarkupTagHelperStartTagSyntax instance. - public static MarkupTagHelperStartTagSyntax MarkupTagHelperStartTag(SyntaxList children) + public static MarkupTagHelperStartTagSyntax MarkupTagHelperStartTag(SyntaxToken openAngle, SyntaxToken bang, SyntaxToken name, SyntaxList attributes, SyntaxToken forwardSlash, SyntaxToken closeAngle) { - return (MarkupTagHelperStartTagSyntax)InternalSyntax.SyntaxFactory.MarkupTagHelperStartTag(children.Node.ToGreenList()).CreateRed(); + switch (openAngle.Kind) + { + case SyntaxKind.OpenAngle: + break; + default: + throw new ArgumentException("openAngle"); + } + if (bang != null) + { + switch (bang.Kind) + { + case SyntaxKind.Bang: + case SyntaxKind.None: + break; + default: + throw new ArgumentException("bang"); + } + } + switch (name.Kind) + { + case SyntaxKind.Text: + break; + default: + throw new ArgumentException("name"); + } + if (forwardSlash != null) + { + switch (forwardSlash.Kind) + { + case SyntaxKind.ForwardSlash: + case SyntaxKind.None: + break; + default: + throw new ArgumentException("forwardSlash"); + } + } + switch (closeAngle.Kind) + { + case SyntaxKind.CloseAngle: + break; + default: + throw new ArgumentException("closeAngle"); + } + return (MarkupTagHelperStartTagSyntax)InternalSyntax.SyntaxFactory.MarkupTagHelperStartTag((Syntax.InternalSyntax.SyntaxToken)openAngle.Green, (Syntax.InternalSyntax.SyntaxToken)bang?.Green, (Syntax.InternalSyntax.SyntaxToken)name.Green, attributes.Node.ToGreenList(), (Syntax.InternalSyntax.SyntaxToken)forwardSlash?.Green, (Syntax.InternalSyntax.SyntaxToken)closeAngle.Green).CreateRed(); } /// Creates a new MarkupTagHelperStartTagSyntax instance. - public static MarkupTagHelperStartTagSyntax MarkupTagHelperStartTag() + public static MarkupTagHelperStartTagSyntax MarkupTagHelperStartTag(SyntaxList attributes = default(SyntaxList)) { - return SyntaxFactory.MarkupTagHelperStartTag(default(SyntaxList)); + return SyntaxFactory.MarkupTagHelperStartTag(SyntaxFactory.Token(SyntaxKind.OpenAngle), default(SyntaxToken), SyntaxFactory.Token(SyntaxKind.Text), attributes, default(SyntaxToken), SyntaxFactory.Token(SyntaxKind.CloseAngle)); } /// Creates a new MarkupTagHelperEndTagSyntax instance. - public static MarkupTagHelperEndTagSyntax MarkupTagHelperEndTag(SyntaxList children) + public static MarkupTagHelperEndTagSyntax MarkupTagHelperEndTag(SyntaxToken openAngle, SyntaxToken forwardSlash, SyntaxToken bang, SyntaxToken name, MarkupMiscAttributeContentSyntax miscAttributeContent, SyntaxToken closeAngle) { - return (MarkupTagHelperEndTagSyntax)InternalSyntax.SyntaxFactory.MarkupTagHelperEndTag(children.Node.ToGreenList()).CreateRed(); + switch (openAngle.Kind) + { + case SyntaxKind.OpenAngle: + break; + default: + throw new ArgumentException("openAngle"); + } + switch (forwardSlash.Kind) + { + case SyntaxKind.ForwardSlash: + break; + default: + throw new ArgumentException("forwardSlash"); + } + if (bang != null) + { + switch (bang.Kind) + { + case SyntaxKind.Bang: + case SyntaxKind.None: + break; + default: + throw new ArgumentException("bang"); + } + } + switch (name.Kind) + { + case SyntaxKind.Text: + break; + default: + throw new ArgumentException("name"); + } + switch (closeAngle.Kind) + { + case SyntaxKind.CloseAngle: + break; + default: + throw new ArgumentException("closeAngle"); + } + return (MarkupTagHelperEndTagSyntax)InternalSyntax.SyntaxFactory.MarkupTagHelperEndTag((Syntax.InternalSyntax.SyntaxToken)openAngle.Green, (Syntax.InternalSyntax.SyntaxToken)forwardSlash.Green, (Syntax.InternalSyntax.SyntaxToken)bang?.Green, (Syntax.InternalSyntax.SyntaxToken)name.Green, miscAttributeContent == null ? null : (InternalSyntax.MarkupMiscAttributeContentSyntax)miscAttributeContent.Green, (Syntax.InternalSyntax.SyntaxToken)closeAngle.Green).CreateRed(); } /// Creates a new MarkupTagHelperEndTagSyntax instance. - public static MarkupTagHelperEndTagSyntax MarkupTagHelperEndTag() + public static MarkupTagHelperEndTagSyntax MarkupTagHelperEndTag(MarkupMiscAttributeContentSyntax miscAttributeContent = default(MarkupMiscAttributeContentSyntax)) { - return SyntaxFactory.MarkupTagHelperEndTag(default(SyntaxList)); + return SyntaxFactory.MarkupTagHelperEndTag(SyntaxFactory.Token(SyntaxKind.OpenAngle), SyntaxFactory.Token(SyntaxKind.ForwardSlash), default(SyntaxToken), SyntaxFactory.Token(SyntaxKind.Text), miscAttributeContent, SyntaxFactory.Token(SyntaxKind.CloseAngle)); } /// Creates a new MarkupTagHelperAttributeSyntax instance. diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Syntax.Generated.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Syntax.Generated.cs index 42cf2587aa..8a6cfb5a32 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Syntax.Generated.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Generated/Syntax.xml.Syntax.Generated.cs @@ -1810,37 +1810,76 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax return Update(StartTag, Body, endTag); } - public MarkupTagHelperElementSyntax AddStartTagChildren(params RazorSyntaxNode[] items) + public MarkupTagHelperElementSyntax AddStartTagAttributes(params RazorSyntaxNode[] items) { - return this.WithStartTag(this.StartTag.WithChildren(this.StartTag.Children.AddRange(items))); + return this.WithStartTag(this.StartTag.WithAttributes(this.StartTag.Attributes.AddRange(items))); } public MarkupTagHelperElementSyntax AddBody(params RazorSyntaxNode[] items) { return WithBody(this.Body.AddRange(items)); } - - public MarkupTagHelperElementSyntax AddEndTagChildren(params RazorSyntaxNode[] items) - { - var _endTag = this.EndTag ?? SyntaxFactory.MarkupTagHelperEndTag(); - return this.WithEndTag(_endTag.WithChildren(_endTag.Children.AddRange(items))); - } } - internal sealed partial class MarkupTagHelperStartTagSyntax : RazorBlockSyntax + internal sealed partial class MarkupTagHelperStartTagSyntax : MarkupSyntaxNode { - private SyntaxNode _children; + private SyntaxToken _openAngle; + private SyntaxToken _bang; + private SyntaxToken _name; + private SyntaxNode _attributes; + private SyntaxToken _forwardSlash; + private SyntaxToken _closeAngle; internal MarkupTagHelperStartTagSyntax(GreenNode green, SyntaxNode parent, int position) : base(green, parent, position) { } - public override SyntaxList Children + public SyntaxToken OpenAngle { get { - return new SyntaxList(GetRed(ref _children, 0)); + return GetRedAtZero(ref _openAngle); + } + } + + public SyntaxToken Bang + { + get + { + return GetRed(ref _bang, 1); + } + } + + public SyntaxToken Name + { + get + { + return GetRed(ref _name, 2); + } + } + + public SyntaxList Attributes + { + get + { + return new SyntaxList(GetRed(ref _attributes, 3)); + } + } + + public SyntaxToken ForwardSlash + { + get + { + return GetRed(ref _forwardSlash, 4); + } + } + + public SyntaxToken CloseAngle + { + get + { + return GetRed(ref _closeAngle, 5); } } @@ -1848,7 +1887,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax { switch (index) { - case 0: return GetRedAtZero(ref _children); + case 0: return GetRedAtZero(ref _openAngle); + case 1: return GetRed(ref _bang, 1); + case 2: return GetRed(ref _name, 2); + case 3: return GetRed(ref _attributes, 3); + case 4: return GetRed(ref _forwardSlash, 4); + case 5: return GetRed(ref _closeAngle, 5); default: return null; } } @@ -1856,7 +1900,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax { switch (index) { - case 0: return _children; + case 0: return _openAngle; + case 1: return _bang; + case 2: return _name; + case 3: return _attributes; + case 4: return _forwardSlash; + case 5: return _closeAngle; default: return null; } } @@ -1871,11 +1920,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax visitor.VisitMarkupTagHelperStartTag(this); } - public MarkupTagHelperStartTagSyntax Update(SyntaxList children) + public MarkupTagHelperStartTagSyntax Update(SyntaxToken openAngle, SyntaxToken bang, SyntaxToken name, SyntaxList attributes, SyntaxToken forwardSlash, SyntaxToken closeAngle) { - if (children != Children) + if (openAngle != OpenAngle || bang != Bang || name != Name || attributes != Attributes || forwardSlash != ForwardSlash || closeAngle != CloseAngle) { - var newNode = SyntaxFactory.MarkupTagHelperStartTag(children); + var newNode = SyntaxFactory.MarkupTagHelperStartTag(openAngle, bang, name, attributes, forwardSlash, closeAngle); var annotations = GetAnnotations(); if (annotations != null && annotations.Length > 0) return newNode.WithAnnotations(annotations); @@ -1885,33 +1934,101 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax return this; } - internal override RazorBlockSyntax WithChildrenCore(SyntaxList children) => WithChildren(children); - public new MarkupTagHelperStartTagSyntax WithChildren(SyntaxList children) + public MarkupTagHelperStartTagSyntax WithOpenAngle(SyntaxToken openAngle) { - return Update(children); + return Update(openAngle, Bang, Name, Attributes, ForwardSlash, CloseAngle); } - internal override RazorBlockSyntax AddChildrenCore(params RazorSyntaxNode[] items) => AddChildren(items); - public new MarkupTagHelperStartTagSyntax AddChildren(params RazorSyntaxNode[] items) + public MarkupTagHelperStartTagSyntax WithBang(SyntaxToken bang) { - return WithChildren(this.Children.AddRange(items)); + return Update(OpenAngle, bang, Name, Attributes, ForwardSlash, CloseAngle); + } + + public MarkupTagHelperStartTagSyntax WithName(SyntaxToken name) + { + return Update(OpenAngle, Bang, name, Attributes, ForwardSlash, CloseAngle); + } + + public MarkupTagHelperStartTagSyntax WithAttributes(SyntaxList attributes) + { + return Update(OpenAngle, Bang, Name, attributes, ForwardSlash, CloseAngle); + } + + public MarkupTagHelperStartTagSyntax WithForwardSlash(SyntaxToken forwardSlash) + { + return Update(OpenAngle, Bang, Name, Attributes, forwardSlash, CloseAngle); + } + + public MarkupTagHelperStartTagSyntax WithCloseAngle(SyntaxToken closeAngle) + { + return Update(OpenAngle, Bang, Name, Attributes, ForwardSlash, closeAngle); + } + + public MarkupTagHelperStartTagSyntax AddAttributes(params RazorSyntaxNode[] items) + { + return WithAttributes(this.Attributes.AddRange(items)); } } - internal sealed partial class MarkupTagHelperEndTagSyntax : RazorBlockSyntax + internal sealed partial class MarkupTagHelperEndTagSyntax : MarkupSyntaxNode { - private SyntaxNode _children; + private SyntaxToken _openAngle; + private SyntaxToken _forwardSlash; + private SyntaxToken _bang; + private SyntaxToken _name; + private MarkupMiscAttributeContentSyntax _miscAttributeContent; + private SyntaxToken _closeAngle; internal MarkupTagHelperEndTagSyntax(GreenNode green, SyntaxNode parent, int position) : base(green, parent, position) { } - public override SyntaxList Children + public SyntaxToken OpenAngle { get { - return new SyntaxList(GetRed(ref _children, 0)); + return GetRedAtZero(ref _openAngle); + } + } + + public SyntaxToken ForwardSlash + { + get + { + return GetRed(ref _forwardSlash, 1); + } + } + + public SyntaxToken Bang + { + get + { + return GetRed(ref _bang, 2); + } + } + + public SyntaxToken Name + { + get + { + return GetRed(ref _name, 3); + } + } + + public MarkupMiscAttributeContentSyntax MiscAttributeContent + { + get + { + return GetRed(ref _miscAttributeContent, 4); + } + } + + public SyntaxToken CloseAngle + { + get + { + return GetRed(ref _closeAngle, 5); } } @@ -1919,7 +2036,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax { switch (index) { - case 0: return GetRedAtZero(ref _children); + case 0: return GetRedAtZero(ref _openAngle); + case 1: return GetRed(ref _forwardSlash, 1); + case 2: return GetRed(ref _bang, 2); + case 3: return GetRed(ref _name, 3); + case 4: return GetRed(ref _miscAttributeContent, 4); + case 5: return GetRed(ref _closeAngle, 5); default: return null; } } @@ -1927,7 +2049,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax { switch (index) { - case 0: return _children; + case 0: return _openAngle; + case 1: return _forwardSlash; + case 2: return _bang; + case 3: return _name; + case 4: return _miscAttributeContent; + case 5: return _closeAngle; default: return null; } } @@ -1942,11 +2069,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax visitor.VisitMarkupTagHelperEndTag(this); } - public MarkupTagHelperEndTagSyntax Update(SyntaxList children) + public MarkupTagHelperEndTagSyntax Update(SyntaxToken openAngle, SyntaxToken forwardSlash, SyntaxToken bang, SyntaxToken name, MarkupMiscAttributeContentSyntax miscAttributeContent, SyntaxToken closeAngle) { - if (children != Children) + if (openAngle != OpenAngle || forwardSlash != ForwardSlash || bang != Bang || name != Name || miscAttributeContent != MiscAttributeContent || closeAngle != CloseAngle) { - var newNode = SyntaxFactory.MarkupTagHelperEndTag(children); + var newNode = SyntaxFactory.MarkupTagHelperEndTag(openAngle, forwardSlash, bang, name, miscAttributeContent, closeAngle); var annotations = GetAnnotations(); if (annotations != null && annotations.Length > 0) return newNode.WithAnnotations(annotations); @@ -1956,16 +2083,40 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax return this; } - internal override RazorBlockSyntax WithChildrenCore(SyntaxList children) => WithChildren(children); - public new MarkupTagHelperEndTagSyntax WithChildren(SyntaxList children) + public MarkupTagHelperEndTagSyntax WithOpenAngle(SyntaxToken openAngle) { - return Update(children); + return Update(openAngle, ForwardSlash, Bang, Name, MiscAttributeContent, CloseAngle); } - internal override RazorBlockSyntax AddChildrenCore(params RazorSyntaxNode[] items) => AddChildren(items); - public new MarkupTagHelperEndTagSyntax AddChildren(params RazorSyntaxNode[] items) + public MarkupTagHelperEndTagSyntax WithForwardSlash(SyntaxToken forwardSlash) { - return WithChildren(this.Children.AddRange(items)); + return Update(OpenAngle, forwardSlash, Bang, Name, MiscAttributeContent, CloseAngle); + } + + public MarkupTagHelperEndTagSyntax WithBang(SyntaxToken bang) + { + return Update(OpenAngle, ForwardSlash, bang, Name, MiscAttributeContent, CloseAngle); + } + + public MarkupTagHelperEndTagSyntax WithName(SyntaxToken name) + { + return Update(OpenAngle, ForwardSlash, Bang, name, MiscAttributeContent, CloseAngle); + } + + public MarkupTagHelperEndTagSyntax WithMiscAttributeContent(MarkupMiscAttributeContentSyntax miscAttributeContent) + { + return Update(OpenAngle, ForwardSlash, Bang, Name, miscAttributeContent, CloseAngle); + } + + public MarkupTagHelperEndTagSyntax WithCloseAngle(SyntaxToken closeAngle) + { + return Update(OpenAngle, ForwardSlash, Bang, Name, MiscAttributeContent, closeAngle); + } + + public MarkupTagHelperEndTagSyntax AddMiscAttributeContentChildren(params RazorSyntaxNode[] items) + { + var _miscAttributeContent = this.MiscAttributeContent ?? SyntaxFactory.MarkupMiscAttributeContent(); + return this.WithMiscAttributeContent(_miscAttributeContent.WithChildren(_miscAttributeContent.Children.AddRange(items))); } } diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Syntax.xml b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Syntax.xml index 89cc6623e7..bca21d77db 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Syntax.xml +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/Syntax.xml @@ -146,13 +146,43 @@ - + - + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxSerializer.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxSerializer.cs index 77052dcd18..817bcf8829 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxSerializer.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Syntax/SyntaxSerializer.cs @@ -305,6 +305,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax node.Kind == SyntaxKind.MarkupEphemeralTextLiteral || node.Kind == SyntaxKind.MarkupStartTag || node.Kind == SyntaxKind.MarkupEndTag || + node.Kind == SyntaxKind.MarkupTagHelperStartTag || + node.Kind == SyntaxKind.MarkupTagHelperEndTag || node.Kind == SyntaxKind.MarkupAttributeBlock || node.Kind == SyntaxKind.MarkupMinimizedAttributeBlock || node.Kind == SyntaxKind.MarkupTagHelperAttribute || diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxNodeWriter.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxNodeWriter.cs index 33fef39d49..914f035f67 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxNodeWriter.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxNodeWriter.cs @@ -221,6 +221,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax node.Kind == SyntaxKind.MarkupEphemeralTextLiteral || node.Kind == SyntaxKind.MarkupStartTag || node.Kind == SyntaxKind.MarkupEndTag || + node.Kind == SyntaxKind.MarkupTagHelperStartTag || + node.Kind == SyntaxKind.MarkupTagHelperEndTag || node.Kind == SyntaxKind.MarkupAttributeBlock || node.Kind == SyntaxKind.MarkupMinimizedAttributeBlock || node.Kind == SyntaxKind.MarkupTagHelperAttribute ||