Refined Start tag and End tag structure (dotnet/aspnetcore-tooling#62)
Regenerated baselines\n\nCommit migrated from d54460296f
This commit is contained in:
parent
583113686c
commit
053121e0b7
|
|
@ -1,65 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Razor.Language.Legacy;
|
||||
using Microsoft.AspNetCore.Razor.Language.Syntax;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
{
|
||||
internal class ClassifiedSpanRewriter : SyntaxRewriter
|
||||
{
|
||||
public override SyntaxNode VisitMarkupStartTag(MarkupStartTagSyntax node)
|
||||
{
|
||||
SpanContext latestSpanContext = null;
|
||||
var newChildren = SyntaxListBuilder<RazorSyntaxNode>.Create();
|
||||
var literals = new List<MarkupTextLiteralSyntax>();
|
||||
foreach (var child in node.Children)
|
||||
{
|
||||
if (child is MarkupTextLiteralSyntax literal)
|
||||
{
|
||||
literals.Add(literal);
|
||||
latestSpanContext = literal.GetSpanContext() ?? latestSpanContext;
|
||||
}
|
||||
else if (child is MarkupMiscAttributeContentSyntax miscContent)
|
||||
{
|
||||
foreach (var contentChild in miscContent.Children)
|
||||
{
|
||||
if (contentChild is MarkupTextLiteralSyntax contentLiteral)
|
||||
{
|
||||
literals.Add(contentLiteral);
|
||||
latestSpanContext = contentLiteral.GetSpanContext() ?? latestSpanContext;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pop stack
|
||||
AddLiteralIfExists();
|
||||
newChildren.Add(contentChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLiteralIfExists();
|
||||
newChildren.Add(child);
|
||||
}
|
||||
}
|
||||
|
||||
AddLiteralIfExists();
|
||||
|
||||
return SyntaxFactory.MarkupStartTag(newChildren.ToList()).Green.CreateRed(node.Parent, node.Position);
|
||||
|
||||
void AddLiteralIfExists()
|
||||
{
|
||||
if (literals.Count > 0)
|
||||
{
|
||||
var mergedLiteral = SyntaxUtilities.MergeTextLiterals(literals.ToArray());
|
||||
mergedLiteral = mergedLiteral.WithSpanContext(latestSpanContext);
|
||||
literals.Clear();
|
||||
latestSpanContext = null;
|
||||
newChildren.Add(mergedLiteral);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor.Language.Legacy;
|
||||
using Microsoft.AspNetCore.Razor.Language.Syntax;
|
||||
|
||||
|
|
@ -108,12 +109,26 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
|
||||
public override void VisitMarkupStartTag(MarkupStartTagSyntax node)
|
||||
{
|
||||
WriteBlock(node, BlockKindInternal.Tag, base.VisitMarkupStartTag);
|
||||
WriteBlock(node, BlockKindInternal.Tag, n =>
|
||||
{
|
||||
var children = GetRewrittenMarkupStartTagChildren(node);
|
||||
foreach (var child in children)
|
||||
{
|
||||
Visit(child);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override void VisitMarkupEndTag(MarkupEndTagSyntax node)
|
||||
{
|
||||
WriteBlock(node, BlockKindInternal.Tag, base.VisitMarkupEndTag);
|
||||
WriteBlock(node, BlockKindInternal.Tag, n =>
|
||||
{
|
||||
var children = GetRewrittenMarkupEndTagChildren(node);
|
||||
foreach (var child in children)
|
||||
{
|
||||
Visit(child);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override void VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node)
|
||||
|
|
@ -275,5 +290,100 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var span = new ClassifiedSpanInternal(spanSource, blockSource, kind, _currentBlockKind, acceptedCharacters.Value);
|
||||
_spans.Add(span);
|
||||
}
|
||||
|
||||
private static SyntaxList<RazorSyntaxNode> GetRewrittenMarkupStartTagChildren(MarkupStartTagSyntax node)
|
||||
{
|
||||
// Rewrites the children of the start tag to look like the legacy syntax tree.
|
||||
if (node.IsMarkupTransition)
|
||||
{
|
||||
var tokens = node.DescendantNodes().Where(n => n is SyntaxToken token && !token.IsMissing).Cast<SyntaxToken>().ToArray();
|
||||
var tokenBuilder = SyntaxListBuilder<SyntaxToken>.Create();
|
||||
tokenBuilder.AddRange(tokens, 0, tokens.Length);
|
||||
var markupTransition = SyntaxFactory.MarkupTransition(tokenBuilder.ToList()).Green.CreateRed(node, node.Position);
|
||||
var spanContext = node.GetSpanContext();
|
||||
if (spanContext != null)
|
||||
{
|
||||
markupTransition = markupTransition.WithSpanContext(spanContext);
|
||||
}
|
||||
|
||||
var builder = new SyntaxListBuilder(1);
|
||||
builder.Add(markupTransition);
|
||||
return new SyntaxList<RazorSyntaxNode>(builder.ToListNode().CreateRed(node, node.Position));
|
||||
}
|
||||
|
||||
SpanContext latestSpanContext = null;
|
||||
var children = node.Children;
|
||||
var newChildren = new SyntaxListBuilder(children.Count);
|
||||
var literals = new List<MarkupTextLiteralSyntax>();
|
||||
foreach (var child in children)
|
||||
{
|
||||
if (child is MarkupTextLiteralSyntax literal)
|
||||
{
|
||||
literals.Add(literal);
|
||||
latestSpanContext = literal.GetSpanContext() ?? latestSpanContext;
|
||||
}
|
||||
else if (child is MarkupMiscAttributeContentSyntax miscContent)
|
||||
{
|
||||
foreach (var contentChild in miscContent.Children)
|
||||
{
|
||||
if (contentChild is MarkupTextLiteralSyntax contentLiteral)
|
||||
{
|
||||
literals.Add(contentLiteral);
|
||||
latestSpanContext = contentLiteral.GetSpanContext() ?? latestSpanContext;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pop stack
|
||||
AddLiteralIfExists();
|
||||
newChildren.Add(contentChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLiteralIfExists();
|
||||
newChildren.Add(child);
|
||||
}
|
||||
}
|
||||
|
||||
AddLiteralIfExists();
|
||||
|
||||
return new SyntaxList<RazorSyntaxNode>(newChildren.ToListNode().CreateRed(node, node.Position));
|
||||
|
||||
void AddLiteralIfExists()
|
||||
{
|
||||
if (literals.Count > 0)
|
||||
{
|
||||
var mergedLiteral = SyntaxUtilities.MergeTextLiterals(literals.ToArray());
|
||||
mergedLiteral = mergedLiteral.WithSpanContext(latestSpanContext);
|
||||
literals.Clear();
|
||||
latestSpanContext = null;
|
||||
newChildren.Add(mergedLiteral);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static SyntaxList<RazorSyntaxNode> GetRewrittenMarkupEndTagChildren(MarkupEndTagSyntax node)
|
||||
{
|
||||
// Rewrites the children of the end tag to look like the legacy syntax tree.
|
||||
if (node.IsMarkupTransition)
|
||||
{
|
||||
var tokens = node.DescendantNodes().Where(n => n is SyntaxToken token && !token.IsMissing).Cast<SyntaxToken>().ToArray();
|
||||
var tokenBuilder = SyntaxListBuilder<SyntaxToken>.Create();
|
||||
tokenBuilder.AddRange(tokens, 0, tokens.Length);
|
||||
var markupTransition = SyntaxFactory.MarkupTransition(tokenBuilder.ToList()).Green.CreateRed(node, node.Position);
|
||||
var spanContext = node.GetSpanContext();
|
||||
if (spanContext != null)
|
||||
{
|
||||
markupTransition = markupTransition.WithSpanContext(spanContext);
|
||||
}
|
||||
|
||||
var builder = new SyntaxListBuilder(1);
|
||||
builder.Add(markupTransition);
|
||||
return new SyntaxList<RazorSyntaxNode>(builder.ToListNode().CreateRed(node, node.Position));
|
||||
}
|
||||
|
||||
return node.Children;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -810,6 +810,22 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
base.VisitMarkupTextLiteral(node);
|
||||
}
|
||||
|
||||
public override void VisitMarkupStartTag(MarkupStartTagSyntax node)
|
||||
{
|
||||
foreach (var child in node.Children)
|
||||
{
|
||||
Visit(child);
|
||||
}
|
||||
}
|
||||
|
||||
public override void VisitMarkupEndTag(MarkupEndTagSyntax node)
|
||||
{
|
||||
foreach (var child in node.Children)
|
||||
{
|
||||
Visit(child);
|
||||
}
|
||||
}
|
||||
|
||||
public override void VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node)
|
||||
{
|
||||
var info = node.TagHelperInfo;
|
||||
|
|
@ -1110,7 +1126,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
Source = BuildSourceSpanFromNode(node),
|
||||
|
||||
// Could be empty while the tag is being typed in.
|
||||
TagName = node.StartTag?.GetTagName() ?? node.EndTag?.GetTagName() ?? string.Empty,
|
||||
TagName = node.StartTag?.GetTagNameWithOptionalBang() ?? node.EndTag?.GetTagName() ?? string.Empty,
|
||||
});
|
||||
|
||||
base.VisitMarkupElement(node);
|
||||
|
|
|
|||
|
|
@ -322,7 +322,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
// Check if the previous span was a transition.
|
||||
var previousSpan = builder.Count > 0 ? GetLastSpan(builder[builder.Count - 1]) : null;
|
||||
if (previousSpan != null && previousSpan.Kind == SyntaxKind.MarkupTransition)
|
||||
if (previousSpan != null &&
|
||||
((previousSpan is MarkupStartTagSyntax startTag && startTag.IsMarkupTransition) ||
|
||||
(previousSpan is MarkupEndTagSyntax endTag && endTag.IsMarkupTransition)))
|
||||
{
|
||||
var tokens = ReadWhile(
|
||||
f => (f.Kind == SyntaxKind.Whitespace) || (f.Kind == SyntaxKind.NewLine));
|
||||
|
|
@ -576,179 +578,201 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
tagName = null;
|
||||
tagMode = MarkupTagMode.Invalid;
|
||||
isWellFormed = false;
|
||||
|
||||
var openAngleToken = EatCurrentToken(); // Accept '<'
|
||||
var isBangEscape = TryParseBangEscape(out var bangToken);
|
||||
|
||||
if (At(SyntaxKind.Text))
|
||||
{
|
||||
tagName = CurrentToken.Content;
|
||||
tagMode = MarkupTagMode.Normal;
|
||||
|
||||
if (isBangEscape)
|
||||
{
|
||||
// We don't want to group <p> and </!p> together.
|
||||
tagName = "!" + tagName;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == ParseMode.MarkupInCodeBlock &&
|
||||
_tagTracker.Count == 0 &&
|
||||
string.Equals(tagName, SyntaxConstants.TextTagName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// "<text>" tag is special only if it is the outermost tag.
|
||||
return ParseStartTextTag(openAngleToken, out tagMode, out isWellFormed);
|
||||
}
|
||||
|
||||
var tagNameToken = At(SyntaxKind.Text) ? EatCurrentToken() : SyntaxFactory.MissingToken(SyntaxKind.Text);
|
||||
|
||||
var attributes = EmptySyntaxList;
|
||||
using (var pooledResult = Pool.Allocate<RazorSyntaxNode>())
|
||||
{
|
||||
var tagBuilder = pooledResult.Builder;
|
||||
var attributeBuilder = pooledResult.Builder;
|
||||
|
||||
// Parse the contents of a tag like attributes.
|
||||
ParseAttributes(attributeBuilder);
|
||||
attributes = attributeBuilder.ToList();
|
||||
}
|
||||
|
||||
AcceptAndMoveNext(); // Accept '<'
|
||||
var isBangEscape = TryParseBangEscape(tagBuilder);
|
||||
SyntaxToken forwardSlashToken = null;
|
||||
if (At(SyntaxKind.ForwardSlash))
|
||||
{
|
||||
// This is a self closing tag.
|
||||
tagMode = MarkupTagMode.SelfClosing;
|
||||
forwardSlashToken = EatCurrentToken();
|
||||
}
|
||||
|
||||
if (At(SyntaxKind.Text))
|
||||
var closeAngleToken = SyntaxFactory.MissingToken(SyntaxKind.CloseAngle);
|
||||
if (mode == ParseMode.MarkupInCodeBlock)
|
||||
{
|
||||
if (EndOfFile || !At(SyntaxKind.CloseAngle))
|
||||
{
|
||||
tagName = CurrentToken.Content;
|
||||
tagMode = MarkupTagMode.Normal;
|
||||
|
||||
if (isBangEscape)
|
||||
// Unfinished tag
|
||||
Context.ErrorSink.OnError(
|
||||
RazorDiagnosticFactory.CreateParsing_UnfinishedTag(
|
||||
new SourceSpan(
|
||||
tagName == null ? tagStartLocation : SourceLocationTracker.Advance(tagStartLocation, "<"),
|
||||
Math.Max(tagName?.Length ?? 0, 1)),
|
||||
tagName ?? string.Empty));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (At(SyntaxKind.CloseAngle))
|
||||
{
|
||||
// We don't want to group <p> and </!p> together.
|
||||
tagName = "!" + tagName;
|
||||
isWellFormed = true;
|
||||
closeAngleToken = EatCurrentToken();
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == ParseMode.MarkupInCodeBlock &&
|
||||
_tagTracker.Count == 0 &&
|
||||
string.Equals(tagName, SyntaxConstants.TextTagName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// "<text>" tag is special only if it is the outermost tag.
|
||||
return ParseStartTextTag(out tagMode, out isWellFormed);
|
||||
}
|
||||
|
||||
TryAccept(SyntaxKind.Text);
|
||||
|
||||
if (At(SyntaxKind.CloseAngle) && mode == ParseMode.MarkupInCodeBlock)
|
||||
{
|
||||
// Completed tags in code blocks have no accepted characters.
|
||||
SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None;
|
||||
}
|
||||
|
||||
// Output open angle and tag name
|
||||
tagBuilder.Add(OutputAsMarkupLiteral());
|
||||
|
||||
// Parse the contents of a tag like attributes.
|
||||
ParseAttributes(tagBuilder);
|
||||
|
||||
if (TryAccept(SyntaxKind.ForwardSlash))
|
||||
{
|
||||
// This is a self closing tag.
|
||||
tagMode = MarkupTagMode.SelfClosing;
|
||||
}
|
||||
|
||||
if (mode == ParseMode.MarkupInCodeBlock)
|
||||
{
|
||||
if (EndOfFile || !At(SyntaxKind.CloseAngle))
|
||||
if (tagMode != MarkupTagMode.SelfClosing && ParserHelpers.VoidElements.Contains(tagName))
|
||||
{
|
||||
// Unfinished tag
|
||||
isWellFormed = false;
|
||||
Context.ErrorSink.OnError(
|
||||
RazorDiagnosticFactory.CreateParsing_UnfinishedTag(
|
||||
new SourceSpan(
|
||||
tagName == null ? tagStartLocation : SourceLocationTracker.Advance(tagStartLocation, "<"),
|
||||
Math.Max(tagName?.Length ?? 0, 1)),
|
||||
tagName ?? string.Empty));
|
||||
}
|
||||
else
|
||||
{
|
||||
isWellFormed = TryAccept(SyntaxKind.CloseAngle);
|
||||
// This is a void element.
|
||||
// Technically, void elements like "meta" are not allowed to have end tags. Just in case they do,
|
||||
// we need to look ahead at the next set of tokens.
|
||||
|
||||
// Completed tags in code blocks have no accepted characters.
|
||||
SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None;
|
||||
// Place a bookmark
|
||||
var bookmark = CurrentStart.AbsoluteIndex;
|
||||
|
||||
if (tagMode != MarkupTagMode.SelfClosing && ParserHelpers.VoidElements.Contains(tagName))
|
||||
// Skip whitespace
|
||||
ReadWhile(IsSpacingToken(includeNewLines: true));
|
||||
|
||||
// Open Angle
|
||||
if (At(SyntaxKind.OpenAngle) && NextIs(SyntaxKind.ForwardSlash))
|
||||
{
|
||||
// This is a void element.
|
||||
// Technically, void elements like "meta" are not allowed to have end tags. Just in case they do,
|
||||
// we need to look ahead at the next set of tokens.
|
||||
|
||||
// Place a bookmark
|
||||
var bookmark = CurrentStart.AbsoluteIndex;
|
||||
|
||||
// Skip whitespace
|
||||
var whiteSpace = ReadWhile(IsSpacingToken(includeNewLines: true));
|
||||
|
||||
// Open Angle
|
||||
if (At(SyntaxKind.OpenAngle) && NextIs(SyntaxKind.ForwardSlash))
|
||||
{
|
||||
var openAngle = CurrentToken;
|
||||
NextToken();
|
||||
Assert(SyntaxKind.ForwardSlash);
|
||||
var forwardSlash = CurrentToken;
|
||||
NextToken();
|
||||
if (!At(SyntaxKind.Text) || !string.Equals(CurrentToken.Content, tagName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// There is no matching end void tag.
|
||||
tagMode = MarkupTagMode.Void;
|
||||
}
|
||||
}
|
||||
else
|
||||
NextToken();
|
||||
Assert(SyntaxKind.ForwardSlash);
|
||||
NextToken();
|
||||
if (!At(SyntaxKind.Text) || !string.Equals(CurrentToken.Content, tagName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// There is no matching end void tag.
|
||||
tagMode = MarkupTagMode.Void;
|
||||
}
|
||||
|
||||
// Go back to the bookmark and just finish this tag at the close angle
|
||||
Context.Source.Position = bookmark;
|
||||
NextToken();
|
||||
}
|
||||
else
|
||||
{
|
||||
// There is no matching end void tag.
|
||||
tagMode = MarkupTagMode.Void;
|
||||
}
|
||||
|
||||
// Go back to the bookmark and just finish this tag at the close angle
|
||||
Context.Source.Position = bookmark;
|
||||
NextToken();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isWellFormed = TryAccept(SyntaxKind.CloseAngle);
|
||||
}
|
||||
|
||||
// End tag block
|
||||
tagBuilder.Add(OutputAsMarkupLiteral());
|
||||
var tagBlock = SyntaxFactory.MarkupStartTag(tagBuilder.ToList());
|
||||
if (string.Equals(tagName, ScriptTagName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// If the script tag expects javascript content then we should do minimal parsing until we reach
|
||||
// the end script tag. Don't want to incorrectly parse a "var tag = '<input />';" as an HTML tag.
|
||||
if (!ScriptTagExpectsHtml(tagBlock))
|
||||
{
|
||||
tagMode = MarkupTagMode.Script;
|
||||
}
|
||||
}
|
||||
|
||||
return tagBlock;
|
||||
}
|
||||
else if (At(SyntaxKind.CloseAngle))
|
||||
{
|
||||
isWellFormed = true;
|
||||
closeAngleToken = EatCurrentToken();
|
||||
}
|
||||
|
||||
// End tag block
|
||||
var startTag = SyntaxFactory.MarkupStartTag(openAngleToken, bangToken, tagNameToken, attributes, forwardSlashToken, closeAngleToken);
|
||||
if (string.Equals(tagName, ScriptTagName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// If the script tag expects javascript content then we should do minimal parsing until we reach
|
||||
// the end script tag. Don't want to incorrectly parse a "var tag = '<input />';" as an HTML tag.
|
||||
if (!ScriptTagExpectsHtml(startTag))
|
||||
{
|
||||
tagMode = MarkupTagMode.Script;
|
||||
}
|
||||
}
|
||||
|
||||
return GetNodeWithSpanContext(startTag);
|
||||
}
|
||||
|
||||
private MarkupStartTagSyntax ParseStartTextTag(out MarkupTagMode tagMode, out bool isWellFormed)
|
||||
private MarkupStartTagSyntax ParseStartTextTag(SyntaxToken openAngleToken, out MarkupTagMode tagMode, out bool isWellFormed)
|
||||
{
|
||||
// At this point, we should have already accepted the open angle. We won't get here if the tag is escaped.
|
||||
tagMode = MarkupTagMode.Normal;
|
||||
var textLocation = CurrentStart;
|
||||
Assert(SyntaxKind.Text);
|
||||
|
||||
AcceptAndMoveNext();
|
||||
var tagNameToken = EatCurrentToken();
|
||||
|
||||
AcceptWhile(IsSpacingToken(includeNewLines: false));
|
||||
if (At(SyntaxKind.CloseAngle) ||
|
||||
(At(SyntaxKind.ForwardSlash) && NextIs(SyntaxKind.CloseAngle)))
|
||||
using (var pooledResult = Pool.Allocate<RazorSyntaxNode>())
|
||||
{
|
||||
if (At(SyntaxKind.ForwardSlash))
|
||||
var miscAttributeContentBuilder = pooledResult.Builder;
|
||||
SyntaxToken forwardSlashToken = null;
|
||||
SyntaxToken closeAngleToken = null;
|
||||
|
||||
AcceptWhile(IsSpacingToken(includeNewLines: false));
|
||||
miscAttributeContentBuilder.Add(OutputAsMarkupLiteral());
|
||||
|
||||
if (At(SyntaxKind.CloseAngle) ||
|
||||
(At(SyntaxKind.ForwardSlash) && NextIs(SyntaxKind.CloseAngle)))
|
||||
{
|
||||
tagMode = MarkupTagMode.SelfClosing;
|
||||
AcceptAndMoveNext(); // '/'
|
||||
if (At(SyntaxKind.ForwardSlash))
|
||||
{
|
||||
tagMode = MarkupTagMode.SelfClosing;
|
||||
forwardSlashToken = EatCurrentToken();
|
||||
}
|
||||
|
||||
closeAngleToken = EatCurrentToken();
|
||||
SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
Context.ErrorSink.OnError(
|
||||
RazorDiagnosticFactory.CreateParsing_TextTagCannotContainAttributes(
|
||||
new SourceSpan(textLocation, contentLength: 4 /* text */)));
|
||||
|
||||
RecoverTextTag(out var miscContent, out closeAngleToken);
|
||||
miscAttributeContentBuilder.Add(miscContent);
|
||||
}
|
||||
|
||||
AcceptAndMoveNext(); // '>'
|
||||
SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None;
|
||||
isWellFormed = true;
|
||||
SpanContext.ChunkGenerator = SpanChunkGenerator.Null;
|
||||
var startTextTag = SyntaxFactory.MarkupStartTag(
|
||||
openAngleToken,
|
||||
bang: null,
|
||||
name: tagNameToken,
|
||||
attributes: miscAttributeContentBuilder.ToList(),
|
||||
forwardSlash: forwardSlashToken,
|
||||
closeAngle: closeAngleToken);
|
||||
|
||||
return GetNodeWithSpanContext(startTextTag).AsMarkupTransition();
|
||||
}
|
||||
else
|
||||
{
|
||||
Context.ErrorSink.OnError(
|
||||
RazorDiagnosticFactory.CreateParsing_TextTagCannotContainAttributes(
|
||||
new SourceSpan(textLocation, contentLength: 4 /* text */)));
|
||||
|
||||
RecoverTextTag();
|
||||
}
|
||||
|
||||
isWellFormed = true;
|
||||
SpanContext.ChunkGenerator = SpanChunkGenerator.Null;
|
||||
var transition = GetNodeWithSpanContext(SyntaxFactory.MarkupTransition(Output()));
|
||||
var startTextTag = SyntaxFactory.MarkupStartTag(transition);
|
||||
|
||||
return startTextTag;
|
||||
}
|
||||
|
||||
private void RecoverTextTag()
|
||||
private void RecoverTextTag(out MarkupTextLiteralSyntax miscContent, out SyntaxToken closeAngleToken)
|
||||
{
|
||||
// We don't want to skip-to and parse because there shouldn't be anything in the body of text tags.
|
||||
AcceptUntil(SyntaxKind.CloseAngle, SyntaxKind.NewLine);
|
||||
miscContent = OutputAsMarkupLiteral();
|
||||
|
||||
// Include the close angle in the text tag block if it's there, otherwise just move on
|
||||
TryAccept(SyntaxKind.CloseAngle);
|
||||
if (At(SyntaxKind.CloseAngle))
|
||||
{
|
||||
closeAngleToken = EatCurrentToken();
|
||||
}
|
||||
else
|
||||
{
|
||||
closeAngleToken = SyntaxFactory.MissingToken(SyntaxKind.CloseAngle);
|
||||
}
|
||||
}
|
||||
|
||||
private MarkupEndTagSyntax ParseEndTag(ParseMode mode, out string tagName, out bool isWellFormed)
|
||||
|
|
@ -757,51 +781,61 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
Assert(SyntaxKind.OpenAngle);
|
||||
|
||||
tagName = null;
|
||||
SyntaxToken tagNameToken = null;
|
||||
|
||||
using (var pooledResult = Pool.Allocate<RazorSyntaxNode>())
|
||||
var openAngleToken = EatCurrentToken(); // Accept '<'
|
||||
var forwardSlashToken = At(SyntaxKind.ForwardSlash) ? EatCurrentToken() : SyntaxFactory.MissingToken(SyntaxKind.ForwardSlash);
|
||||
|
||||
// Whitespace here is invalid (according to the spec)
|
||||
var isBangEscape = TryParseBangEscape(out var bangToken);
|
||||
if (At(SyntaxKind.Text))
|
||||
{
|
||||
var tagBuilder = pooledResult.Builder;
|
||||
tagName = isBangEscape ? "!" : string.Empty;
|
||||
tagName += CurrentToken.Content;
|
||||
|
||||
AcceptAndMoveNext(); // Accept '<'
|
||||
TryAccept(SyntaxKind.ForwardSlash);
|
||||
|
||||
// Whitespace here is invalid (according to the spec)
|
||||
var isBangEscape = TryParseBangEscape(tagBuilder);
|
||||
if (At(SyntaxKind.Text))
|
||||
if (mode == ParseMode.MarkupInCodeBlock &&
|
||||
string.Equals(tagName, SyntaxConstants.TextTagName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
tagName = isBangEscape ? "!" : string.Empty;
|
||||
tagName += CurrentToken.Content;
|
||||
|
||||
if (mode == ParseMode.MarkupInCodeBlock &&
|
||||
string.Equals(tagName, SyntaxConstants.TextTagName, StringComparison.OrdinalIgnoreCase))
|
||||
// "<text>" tag is special only if it is the outermost tag. We need to figure out if the current end text tag
|
||||
// matches the outermost start text tag.
|
||||
var openTextTagCount = 0;
|
||||
foreach (var tracker in _tagTracker)
|
||||
{
|
||||
// "<text>" tag is special only if it is the outermost tag. We need to figure out if the current end text tag
|
||||
// matches the outermost start text tag.
|
||||
var openTextTagCount = 0;
|
||||
foreach (var tracker in _tagTracker)
|
||||
if (string.Equals(tracker.TagName, SyntaxConstants.TextTagName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (string.Equals(tracker.TagName, SyntaxConstants.TextTagName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
openTextTagCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (openTextTagCount == 1 &&
|
||||
string.Equals(_tagTracker.Last().TagName, SyntaxConstants.TextTagName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// This means there is only one open text tag and it is the outermost tag.
|
||||
return ParseEndTextTag(out isWellFormed);
|
||||
openTextTagCount++;
|
||||
}
|
||||
}
|
||||
|
||||
AcceptAndMoveNext();
|
||||
if (openTextTagCount == 1 &&
|
||||
string.Equals(_tagTracker.Last().TagName, SyntaxConstants.TextTagName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// This means there is only one open text tag and it is the outermost tag.
|
||||
return ParseEndTextTag(openAngleToken, forwardSlashToken, out isWellFormed);
|
||||
}
|
||||
}
|
||||
TryAccept(SyntaxKind.Whitespace);
|
||||
|
||||
tagNameToken = EatCurrentToken();
|
||||
}
|
||||
else
|
||||
{
|
||||
tagNameToken = SyntaxFactory.MissingToken(SyntaxKind.Text);
|
||||
}
|
||||
|
||||
SyntaxToken closeAngleToken = null;
|
||||
MarkupMiscAttributeContentSyntax miscAttributeContent = null;
|
||||
using (var pooledResult = Pool.Allocate<RazorSyntaxNode>())
|
||||
{
|
||||
var miscAttributeBuilder = pooledResult.Builder;
|
||||
|
||||
AcceptWhile(SyntaxKind.Whitespace);
|
||||
miscAttributeBuilder.Add(OutputAsMarkupLiteral());
|
||||
|
||||
if (mode == ParseMode.MarkupInCodeBlock)
|
||||
{
|
||||
// We want to accept malformed end tags as content.
|
||||
AcceptUntil(SyntaxKind.CloseAngle, SyntaxKind.OpenAngle);
|
||||
miscAttributeBuilder.Add(OutputAsMarkupLiteral());
|
||||
|
||||
if (At(SyntaxKind.CloseAngle))
|
||||
{
|
||||
|
|
@ -810,42 +844,73 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
}
|
||||
}
|
||||
|
||||
isWellFormed = TryAccept(SyntaxKind.CloseAngle);
|
||||
|
||||
// End tag block
|
||||
tagBuilder.Add(OutputAsMarkupLiteral());
|
||||
var tagBlock = SyntaxFactory.MarkupEndTag(tagBuilder.ToList());
|
||||
return tagBlock;
|
||||
if (miscAttributeBuilder.Count > 0)
|
||||
{
|
||||
miscAttributeContent = SyntaxFactory.MarkupMiscAttributeContent(miscAttributeBuilder.ToList());
|
||||
}
|
||||
}
|
||||
|
||||
if (At(SyntaxKind.CloseAngle))
|
||||
{
|
||||
isWellFormed = true;
|
||||
closeAngleToken = EatCurrentToken();
|
||||
}
|
||||
else
|
||||
{
|
||||
isWellFormed = false;
|
||||
closeAngleToken = SyntaxFactory.MissingToken(SyntaxKind.CloseAngle);
|
||||
}
|
||||
|
||||
// End tag block
|
||||
var endTag = SyntaxFactory.MarkupEndTag(openAngleToken, forwardSlashToken, bangToken, tagNameToken, miscAttributeContent, closeAngleToken);
|
||||
return GetNodeWithSpanContext(endTag);
|
||||
}
|
||||
|
||||
private MarkupEndTagSyntax ParseEndTextTag(out bool isWellFormed)
|
||||
private MarkupEndTagSyntax ParseEndTextTag(SyntaxToken openAngleToken, SyntaxToken forwardSlashToken, out bool isWellFormed)
|
||||
{
|
||||
// At this point, we should have already accepted the open angle and forward slash. We won't get here if the tag is escaped.
|
||||
var textLocation = CurrentStart;
|
||||
Assert(SyntaxKind.Text);
|
||||
AcceptAndMoveNext();
|
||||
var tagNameToken = EatCurrentToken();
|
||||
|
||||
isWellFormed = TryAccept(SyntaxKind.CloseAngle);
|
||||
if (!isWellFormed)
|
||||
MarkupMiscAttributeContentSyntax miscAttributeContent = null;
|
||||
SyntaxToken closeAngleToken = null;
|
||||
using (var pooledResult = Pool.Allocate<RazorSyntaxNode>())
|
||||
{
|
||||
Context.ErrorSink.OnError(
|
||||
RazorDiagnosticFactory.CreateParsing_TextTagCannotContainAttributes(
|
||||
new SourceSpan(textLocation, contentLength: 4 /* text */)));
|
||||
var miscAttributeBuilder = pooledResult.Builder;
|
||||
|
||||
SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any;
|
||||
RecoverTextTag();
|
||||
}
|
||||
else
|
||||
{
|
||||
SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None;
|
||||
isWellFormed = At(SyntaxKind.CloseAngle);
|
||||
if (!isWellFormed)
|
||||
{
|
||||
Context.ErrorSink.OnError(
|
||||
RazorDiagnosticFactory.CreateParsing_TextTagCannotContainAttributes(
|
||||
new SourceSpan(textLocation, contentLength: 4 /* text */)));
|
||||
|
||||
SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any;
|
||||
RecoverTextTag(out var miscContent, out closeAngleToken);
|
||||
miscAttributeBuilder.Add(miscContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpanContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None;
|
||||
closeAngleToken = EatCurrentToken();
|
||||
}
|
||||
|
||||
if (miscAttributeBuilder.Count > 0)
|
||||
{
|
||||
miscAttributeContent = SyntaxFactory.MarkupMiscAttributeContent(miscAttributeBuilder.ToList());
|
||||
}
|
||||
}
|
||||
|
||||
SpanContext.ChunkGenerator = SpanChunkGenerator.Null;
|
||||
|
||||
var transition = GetNodeWithSpanContext(SyntaxFactory.MarkupTransition(Output()));
|
||||
var endTextTag = SyntaxFactory.MarkupEndTag(transition);
|
||||
return endTextTag;
|
||||
var endTextTag = SyntaxFactory.MarkupEndTag(
|
||||
openAngleToken,
|
||||
forwardSlashToken,
|
||||
bang: null,
|
||||
name: tagNameToken,
|
||||
miscAttributeContent: miscAttributeContent,
|
||||
closeAngle: closeAngleToken);
|
||||
return GetNodeWithSpanContext(endTextTag).AsMarkupTransition();
|
||||
}
|
||||
|
||||
private void ParseAttributes(in SyntaxListBuilder<RazorSyntaxNode> builder)
|
||||
|
|
@ -1257,26 +1322,47 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
var tagStart = CurrentStart;
|
||||
builder.Add(OutputAsMarkupLiteral());
|
||||
|
||||
SpanContext.EditHandler.AcceptedCharacters = endTagAcceptedCharacters;
|
||||
|
||||
var openAngleToken = EatCurrentToken(); // '<'
|
||||
var forwardSlashToken = EatCurrentToken(); // '/'
|
||||
var tagNameToken = EatCurrentToken(); // 'script'
|
||||
MarkupMiscAttributeContentSyntax miscContent = null;
|
||||
SyntaxToken closeAngleToken = null;
|
||||
|
||||
using (var pooledResult = Pool.Allocate<RazorSyntaxNode>())
|
||||
{
|
||||
var tagBuilder = pooledResult.Builder;
|
||||
SpanContext.EditHandler.AcceptedCharacters = endTagAcceptedCharacters;
|
||||
var miscAttributeBuilder = pooledResult.Builder;
|
||||
|
||||
AcceptAndMoveNext(); // '<'
|
||||
AcceptAndMoveNext(); // '/'
|
||||
ParseMarkupNodes(tagBuilder, ParseMode.Text, token => token.Kind == SyntaxKind.CloseAngle);
|
||||
if (!TryAccept(SyntaxKind.CloseAngle))
|
||||
ParseMarkupNodes(miscAttributeBuilder, ParseMode.Text, token => token.Kind == SyntaxKind.CloseAngle);
|
||||
miscAttributeBuilder.Add(OutputAsMarkupLiteral());
|
||||
if (miscAttributeBuilder.Count > 0)
|
||||
{
|
||||
miscContent = SyntaxFactory.MarkupMiscAttributeContent(miscAttributeBuilder.ToList());
|
||||
}
|
||||
|
||||
if (!At(SyntaxKind.CloseAngle))
|
||||
{
|
||||
Context.ErrorSink.OnError(
|
||||
RazorDiagnosticFactory.CreateParsing_UnfinishedTag(
|
||||
new SourceSpan(SourceLocationTracker.Advance(tagStart, "</"), ScriptTagName.Length),
|
||||
ScriptTagName));
|
||||
var closeAngle = SyntaxFactory.MissingToken(SyntaxKind.CloseAngle);
|
||||
Accept(closeAngle);
|
||||
closeAngleToken = SyntaxFactory.MissingToken(SyntaxKind.CloseAngle);
|
||||
}
|
||||
else
|
||||
{
|
||||
closeAngleToken = EatCurrentToken();
|
||||
}
|
||||
tagBuilder.Add(OutputAsMarkupLiteral());
|
||||
endTag = SyntaxFactory.MarkupEndTag(tagBuilder.ToList());
|
||||
}
|
||||
|
||||
endTag = SyntaxFactory.MarkupEndTag(
|
||||
openAngleToken,
|
||||
forwardSlashToken,
|
||||
bang: null,
|
||||
name: tagNameToken,
|
||||
miscAttributeContent: miscContent,
|
||||
closeAngle: closeAngleToken);
|
||||
endTag = GetNodeWithSpanContext(endTag);
|
||||
}
|
||||
|
||||
var element = SyntaxFactory.MarkupElement(startTag, builder.Consume(), endTag);
|
||||
|
|
@ -1500,13 +1586,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
private bool ScriptTagExpectsHtml(MarkupStartTagSyntax tagBlock)
|
||||
{
|
||||
MarkupAttributeBlockSyntax typeAttribute = null;
|
||||
for (var i = 0; i < tagBlock.Children.Count; i++)
|
||||
for (var i = 0; i < tagBlock.Attributes.Count; i++)
|
||||
{
|
||||
var node = tagBlock.Children[i];
|
||||
if (node.IsToken || node.IsTrivia)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var node = tagBlock.Attributes[i];
|
||||
|
||||
if (node is MarkupAttributeBlockSyntax attributeBlock &&
|
||||
attributeBlock.Value.Children.Count > 0 &&
|
||||
|
|
@ -1678,19 +1760,15 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
}
|
||||
}
|
||||
|
||||
private bool TryParseBangEscape(in SyntaxListBuilder<RazorSyntaxNode> builder)
|
||||
private bool TryParseBangEscape(out SyntaxToken bangToken)
|
||||
{
|
||||
bangToken = null;
|
||||
if (IsBangEscape(lookahead: 0))
|
||||
{
|
||||
builder.Add(OutputAsMarkupLiteral());
|
||||
|
||||
// Accept the parser escape character '!'.
|
||||
Assert(SyntaxKind.Bang);
|
||||
AcceptAndMoveNext();
|
||||
bangToken = EatCurrentToken();
|
||||
|
||||
// Setup the metacode span that we will be outputing.
|
||||
SpanContext.ChunkGenerator = SpanChunkGenerator.Null;
|
||||
builder.Add(OutputAsMetaCode(Output()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,7 +100,20 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
}
|
||||
|
||||
SyntaxNode owner = null;
|
||||
var children = node.ChildNodes();
|
||||
IEnumerable<SyntaxNode> children = null;
|
||||
if (node is MarkupStartTagSyntax startTag)
|
||||
{
|
||||
children = startTag.Children;
|
||||
}
|
||||
else if (node is MarkupEndTagSyntax endTag)
|
||||
{
|
||||
children = endTag.Children;
|
||||
}
|
||||
else
|
||||
{
|
||||
children = node.ChildNodes();
|
||||
}
|
||||
|
||||
foreach (var child in children)
|
||||
{
|
||||
owner = LocateOwner(child, change);
|
||||
|
|
@ -192,7 +205,27 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
foreach (var child in node.DescendantNodes())
|
||||
{
|
||||
if (child.IsSpanKind())
|
||||
if (child is MarkupStartTagSyntax startTag)
|
||||
{
|
||||
foreach (var tagChild in startTag.Children)
|
||||
{
|
||||
if (tagChild.IsSpanKind())
|
||||
{
|
||||
yield return tagChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (child is MarkupEndTagSyntax endTag)
|
||||
{
|
||||
foreach (var tagChild in endTag.Children)
|
||||
{
|
||||
if (tagChild.IsSpanKind())
|
||||
{
|
||||
yield return tagChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (child.IsSpanKind())
|
||||
{
|
||||
yield return child;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
throw new ArgumentNullException(nameof(syntaxTree));
|
||||
}
|
||||
|
||||
var rewriter = new ClassifiedSpanRewriter();
|
||||
var rewritten = rewriter.Visit(syntaxTree.Root);
|
||||
var visitor = new ClassifiedSpanVisitor(syntaxTree.Source);
|
||||
visitor.Visit(rewritten);
|
||||
visitor.Visit(syntaxTree.Root);
|
||||
|
||||
return visitor.ClassifiedSpans;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
var startTag = (MarkupStartTagSyntax)Visit(node.StartTag);
|
||||
if (startTag != null)
|
||||
{
|
||||
var tagName = startTag.GetTagName();
|
||||
var tagName = startTag.GetTagNameWithOptionalBang();
|
||||
if (TryRewriteTagHelperStart(startTag, out tagHelperStart, out tagHelperInfo))
|
||||
{
|
||||
// This is a tag helper.
|
||||
|
|
@ -218,10 +218,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
tagHelperInfo = null;
|
||||
|
||||
// Get tag name of the current block
|
||||
var tagName = startTag.GetTagName();
|
||||
var tagName = startTag.GetTagNameWithOptionalBang();
|
||||
|
||||
// Could not determine tag name, it can't be a TagHelper, continue on and track the element.
|
||||
if (tagName == null || tagName.StartsWith("!"))
|
||||
if (string.IsNullOrEmpty(tagName) || tagName.StartsWith("!"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -288,7 +288,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
rewritten = null;
|
||||
var tagName = tagBlock.GetTagName();
|
||||
// Could not determine tag name, it can't be a TagHelper, continue on and track the element.
|
||||
if (tagName == null || tagName.StartsWith("!"))
|
||||
if (string.IsNullOrEmpty(tagName) || tagName.StartsWith("!"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -510,22 +510,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
return true;
|
||||
}
|
||||
|
||||
private bool IsPotentialTagHelperStart(string tagName, MarkupStartTagSyntax childBlock)
|
||||
private bool IsPotentialTagHelperStart(string tagName, MarkupStartTagSyntax startTag)
|
||||
{
|
||||
Debug.Assert(childBlock.Children.Count > 0);
|
||||
var child = childBlock.Children[0];
|
||||
|
||||
return !string.Equals(tagName, SyntaxConstants.TextTagName, StringComparison.OrdinalIgnoreCase) ||
|
||||
child.Kind != SyntaxKind.MarkupTransition;
|
||||
!startTag.IsMarkupTransition;
|
||||
}
|
||||
|
||||
private bool IsPotentialTagHelperEnd(string tagName, MarkupEndTagSyntax childBlock)
|
||||
private bool IsPotentialTagHelperEnd(string tagName, MarkupEndTagSyntax endTag)
|
||||
{
|
||||
Debug.Assert(childBlock.Children.Count > 0);
|
||||
var child = childBlock.Children[0];
|
||||
|
||||
return !string.Equals(tagName, SyntaxConstants.TextTagName, StringComparison.OrdinalIgnoreCase) ||
|
||||
child.Kind != SyntaxKind.MarkupTransition;
|
||||
!endTag.IsMarkupTransition;
|
||||
}
|
||||
|
||||
private static bool IsPartialStartTag(MarkupStartTagSyntax tagBlock)
|
||||
|
|
@ -605,7 +599,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
private void ValidateParentAllowsPlainStartTag(MarkupStartTagSyntax tagBlock)
|
||||
{
|
||||
var tagName = tagBlock.GetTagName();
|
||||
var tagName = tagBlock.GetTagNameWithOptionalBang();
|
||||
|
||||
// Treat partial tags such as '</' which have no tag names as content.
|
||||
if (string.IsNullOrEmpty(tagName))
|
||||
|
|
|
|||
|
|
@ -860,87 +860,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
|||
}
|
||||
}
|
||||
|
||||
internal sealed partial class MarkupTagBlockSyntax : RazorBlockSyntax
|
||||
{
|
||||
private readonly GreenNode _children;
|
||||
|
||||
internal MarkupTagBlockSyntax(SyntaxKind kind, GreenNode children, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
: base(kind, diagnostics, annotations)
|
||||
{
|
||||
SlotCount = 1;
|
||||
if (children != null)
|
||||
{
|
||||
AdjustFlagsAndWidth(children);
|
||||
_children = children;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal MarkupTagBlockSyntax(SyntaxKind kind, GreenNode children)
|
||||
: base(kind)
|
||||
{
|
||||
SlotCount = 1;
|
||||
if (children != null)
|
||||
{
|
||||
AdjustFlagsAndWidth(children);
|
||||
_children = children;
|
||||
}
|
||||
}
|
||||
|
||||
public override SyntaxList<RazorSyntaxNode> Children { get { return new SyntaxList<RazorSyntaxNode>(_children); } }
|
||||
|
||||
internal override GreenNode GetSlot(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return _children;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode parent, int position)
|
||||
{
|
||||
return new Syntax.MarkupTagBlockSyntax(this, parent, position);
|
||||
}
|
||||
|
||||
public override TResult Accept<TResult>(SyntaxVisitor<TResult> visitor)
|
||||
{
|
||||
return visitor.VisitMarkupTagBlock(this);
|
||||
}
|
||||
|
||||
public override void Accept(SyntaxVisitor visitor)
|
||||
{
|
||||
visitor.VisitMarkupTagBlock(this);
|
||||
}
|
||||
|
||||
public MarkupTagBlockSyntax Update(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList<RazorSyntaxNode> children)
|
||||
{
|
||||
if (children != Children)
|
||||
{
|
||||
var newNode = SyntaxFactory.MarkupTagBlock(children);
|
||||
var diags = GetDiagnostics();
|
||||
if (diags != null && diags.Length > 0)
|
||||
newNode = newNode.WithDiagnosticsGreen(diags);
|
||||
var annotations = GetAnnotations();
|
||||
if (annotations != null && annotations.Length > 0)
|
||||
newNode = newNode.WithAnnotationsGreen(annotations);
|
||||
return newNode;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new MarkupTagBlockSyntax(Kind, _children, diagnostics, GetAnnotations());
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new MarkupTagBlockSyntax(Kind, _children, GetDiagnostics(), annotations);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed partial class MarkupMinimizedAttributeBlockSyntax : MarkupSyntaxNode
|
||||
{
|
||||
private readonly MarkupTextLiteralSyntax _namePrefix;
|
||||
|
|
@ -1546,40 +1465,87 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
|||
}
|
||||
}
|
||||
|
||||
internal sealed partial class MarkupStartTagSyntax : RazorBlockSyntax
|
||||
internal sealed partial class MarkupStartTagSyntax : 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 MarkupStartTagSyntax(SyntaxKind kind, GreenNode children, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
internal MarkupStartTagSyntax(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 MarkupStartTagSyntax(SyntaxKind kind, GreenNode children)
|
||||
internal MarkupStartTagSyntax(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<RazorSyntaxNode> Children { get { return new SyntaxList<RazorSyntaxNode>(_children); } }
|
||||
public SyntaxToken OpenAngle { get { return _openAngle; } }
|
||||
public SyntaxToken Bang { get { return _bang; } }
|
||||
public SyntaxToken Name { get { return _name; } }
|
||||
public SyntaxList<RazorSyntaxNode> Attributes { get { return new SyntaxList<RazorSyntaxNode>(_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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1599,11 +1565,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
|||
visitor.VisitMarkupStartTag(this);
|
||||
}
|
||||
|
||||
public MarkupStartTagSyntax Update(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList<RazorSyntaxNode> children)
|
||||
public MarkupStartTagSyntax Update(SyntaxToken openAngle, SyntaxToken bang, SyntaxToken name, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList<RazorSyntaxNode> attributes, SyntaxToken forwardSlash, SyntaxToken closeAngle)
|
||||
{
|
||||
if (children != Children)
|
||||
if (openAngle != OpenAngle || bang != Bang || name != Name || attributes != Attributes || forwardSlash != ForwardSlash || closeAngle != CloseAngle)
|
||||
{
|
||||
var newNode = SyntaxFactory.MarkupStartTag(children);
|
||||
var newNode = SyntaxFactory.MarkupStartTag(openAngle, bang, name, attributes, forwardSlash, closeAngle);
|
||||
var diags = GetDiagnostics();
|
||||
if (diags != null && diags.Length > 0)
|
||||
newNode = newNode.WithDiagnosticsGreen(diags);
|
||||
|
|
@ -1618,49 +1584,90 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
|||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new MarkupStartTagSyntax(Kind, _children, diagnostics, GetAnnotations());
|
||||
return new MarkupStartTagSyntax(Kind, _openAngle, _bang, _name, _attributes, _forwardSlash, _closeAngle, diagnostics, GetAnnotations());
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new MarkupStartTagSyntax(Kind, _children, GetDiagnostics(), annotations);
|
||||
return new MarkupStartTagSyntax(Kind, _openAngle, _bang, _name, _attributes, _forwardSlash, _closeAngle, GetDiagnostics(), annotations);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed partial class MarkupEndTagSyntax : RazorBlockSyntax
|
||||
internal sealed partial class MarkupEndTagSyntax : 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 MarkupEndTagSyntax(SyntaxKind kind, GreenNode children, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
internal MarkupEndTagSyntax(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 MarkupEndTagSyntax(SyntaxKind kind, GreenNode children)
|
||||
internal MarkupEndTagSyntax(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<RazorSyntaxNode> Children { get { return new SyntaxList<RazorSyntaxNode>(_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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1680,11 +1687,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
|||
visitor.VisitMarkupEndTag(this);
|
||||
}
|
||||
|
||||
public MarkupEndTagSyntax Update(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList<RazorSyntaxNode> children)
|
||||
public MarkupEndTagSyntax 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.MarkupEndTag(children);
|
||||
var newNode = SyntaxFactory.MarkupEndTag(openAngle, forwardSlash, bang, name, miscAttributeContent, closeAngle);
|
||||
var diags = GetDiagnostics();
|
||||
if (diags != null && diags.Length > 0)
|
||||
newNode = newNode.WithDiagnosticsGreen(diags);
|
||||
|
|
@ -1699,12 +1706,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
|||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new MarkupEndTagSyntax(Kind, _children, diagnostics, GetAnnotations());
|
||||
return new MarkupEndTagSyntax(Kind, _openAngle, _forwardSlash, _bang, _name, _miscAttributeContent, _closeAngle, diagnostics, GetAnnotations());
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new MarkupEndTagSyntax(Kind, _children, GetDiagnostics(), annotations);
|
||||
return new MarkupEndTagSyntax(Kind, _openAngle, _forwardSlash, _bang, _name, _miscAttributeContent, _closeAngle, GetDiagnostics(), annotations);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3510,11 +3517,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
|||
return DefaultVisit(node);
|
||||
}
|
||||
|
||||
public virtual TResult VisitMarkupTagBlock(MarkupTagBlockSyntax node)
|
||||
{
|
||||
return DefaultVisit(node);
|
||||
}
|
||||
|
||||
public virtual TResult VisitMarkupMinimizedAttributeBlock(MarkupMinimizedAttributeBlockSyntax node)
|
||||
{
|
||||
return DefaultVisit(node);
|
||||
|
|
@ -3709,11 +3711,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
|||
DefaultVisit(node);
|
||||
}
|
||||
|
||||
public virtual void VisitMarkupTagBlock(MarkupTagBlockSyntax node)
|
||||
{
|
||||
DefaultVisit(node);
|
||||
}
|
||||
|
||||
public virtual void VisitMarkupMinimizedAttributeBlock(MarkupMinimizedAttributeBlockSyntax node)
|
||||
{
|
||||
DefaultVisit(node);
|
||||
|
|
@ -3921,12 +3918,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
|||
return node.Update(children);
|
||||
}
|
||||
|
||||
public override GreenNode VisitMarkupTagBlock(MarkupTagBlockSyntax node)
|
||||
{
|
||||
var children = VisitList(node.Children);
|
||||
return node.Update(children);
|
||||
}
|
||||
|
||||
public override GreenNode VisitMarkupMinimizedAttributeBlock(MarkupMinimizedAttributeBlockSyntax node)
|
||||
{
|
||||
var namePrefix = (MarkupTextLiteralSyntax)Visit(node.NamePrefix);
|
||||
|
|
@ -3976,14 +3967,24 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
|||
|
||||
public override GreenNode VisitMarkupStartTag(MarkupStartTagSyntax 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 VisitMarkupEndTag(MarkupEndTagSyntax 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 VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node)
|
||||
|
|
@ -4244,13 +4245,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
|||
return result;
|
||||
}
|
||||
|
||||
public static MarkupTagBlockSyntax MarkupTagBlock(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList<RazorSyntaxNode> children)
|
||||
{
|
||||
var result = new MarkupTagBlockSyntax(SyntaxKind.MarkupTagBlock, children.Node);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static MarkupMinimizedAttributeBlockSyntax MarkupMinimizedAttributeBlock(MarkupTextLiteralSyntax namePrefix, MarkupTextLiteralSyntax name)
|
||||
{
|
||||
if (name == null)
|
||||
|
|
@ -4309,18 +4303,112 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
|||
return result;
|
||||
}
|
||||
|
||||
public static MarkupStartTagSyntax MarkupStartTag(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList<RazorSyntaxNode> children)
|
||||
public static MarkupStartTagSyntax MarkupStartTag(SyntaxToken openAngle, SyntaxToken bang, SyntaxToken name, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList<RazorSyntaxNode> attributes, SyntaxToken forwardSlash, SyntaxToken closeAngle)
|
||||
{
|
||||
var result = new MarkupStartTagSyntax(SyntaxKind.MarkupStartTag, 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 MarkupStartTagSyntax(SyntaxKind.MarkupStartTag, openAngle, bang, name, attributes.Node, forwardSlash, closeAngle);
|
||||
}
|
||||
|
||||
public static MarkupEndTagSyntax MarkupEndTag(Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList<RazorSyntaxNode> children)
|
||||
public static MarkupEndTagSyntax MarkupEndTag(SyntaxToken openAngle, SyntaxToken forwardSlash, SyntaxToken bang, SyntaxToken name, MarkupMiscAttributeContentSyntax miscAttributeContent, SyntaxToken closeAngle)
|
||||
{
|
||||
var result = new MarkupEndTagSyntax(SyntaxKind.MarkupEndTag, 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 MarkupEndTagSyntax(SyntaxKind.MarkupEndTag, openAngle, forwardSlash, bang, name, miscAttributeContent, closeAngle);
|
||||
}
|
||||
|
||||
public static MarkupTagHelperElementSyntax MarkupTagHelperElement(MarkupTagHelperStartTagSyntax startTag, Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax.SyntaxList<RazorSyntaxNode> body, MarkupTagHelperEndTagSyntax endTag)
|
||||
|
|
@ -4544,7 +4632,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
|||
typeof(MarkupTextLiteralSyntax),
|
||||
typeof(MarkupEphemeralTextLiteralSyntax),
|
||||
typeof(MarkupCommentBlockSyntax),
|
||||
typeof(MarkupTagBlockSyntax),
|
||||
typeof(MarkupMinimizedAttributeBlockSyntax),
|
||||
typeof(MarkupAttributeBlockSyntax),
|
||||
typeof(MarkupMiscAttributeContentSyntax),
|
||||
|
|
|
|||
|
|
@ -71,12 +71,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
return DefaultVisit(node);
|
||||
}
|
||||
|
||||
/// <summary>Called when the visitor visits a MarkupTagBlockSyntax node.</summary>
|
||||
public virtual TResult VisitMarkupTagBlock(MarkupTagBlockSyntax node)
|
||||
{
|
||||
return DefaultVisit(node);
|
||||
}
|
||||
|
||||
/// <summary>Called when the visitor visits a MarkupMinimizedAttributeBlockSyntax node.</summary>
|
||||
public virtual TResult VisitMarkupMinimizedAttributeBlock(MarkupMinimizedAttributeBlockSyntax node)
|
||||
{
|
||||
|
|
@ -308,12 +302,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
DefaultVisit(node);
|
||||
}
|
||||
|
||||
/// <summary>Called when the visitor visits a MarkupTagBlockSyntax node.</summary>
|
||||
public virtual void VisitMarkupTagBlock(MarkupTagBlockSyntax node)
|
||||
{
|
||||
DefaultVisit(node);
|
||||
}
|
||||
|
||||
/// <summary>Called when the visitor visits a MarkupMinimizedAttributeBlockSyntax node.</summary>
|
||||
public virtual void VisitMarkupMinimizedAttributeBlock(MarkupMinimizedAttributeBlockSyntax node)
|
||||
{
|
||||
|
|
@ -549,12 +537,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
return node.Update(children);
|
||||
}
|
||||
|
||||
public override SyntaxNode VisitMarkupTagBlock(MarkupTagBlockSyntax node)
|
||||
{
|
||||
var children = VisitList(node.Children);
|
||||
return node.Update(children);
|
||||
}
|
||||
|
||||
public override SyntaxNode VisitMarkupMinimizedAttributeBlock(MarkupMinimizedAttributeBlockSyntax node)
|
||||
{
|
||||
var namePrefix = (MarkupTextLiteralSyntax)Visit(node.NamePrefix);
|
||||
|
|
@ -604,14 +586,24 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
|
||||
public override SyntaxNode VisitMarkupStartTag(MarkupStartTagSyntax 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 VisitMarkupEndTag(MarkupEndTagSyntax 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 VisitMarkupTagHelperElement(MarkupTagHelperElementSyntax node)
|
||||
|
|
@ -906,18 +898,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
return SyntaxFactory.MarkupCommentBlock(default(SyntaxList<RazorSyntaxNode>));
|
||||
}
|
||||
|
||||
/// <summary>Creates a new MarkupTagBlockSyntax instance.</summary>
|
||||
public static MarkupTagBlockSyntax MarkupTagBlock(SyntaxList<RazorSyntaxNode> children)
|
||||
{
|
||||
return (MarkupTagBlockSyntax)InternalSyntax.SyntaxFactory.MarkupTagBlock(children.Node.ToGreenList<InternalSyntax.RazorSyntaxNode>()).CreateRed();
|
||||
}
|
||||
|
||||
/// <summary>Creates a new MarkupTagBlockSyntax instance.</summary>
|
||||
public static MarkupTagBlockSyntax MarkupTagBlock()
|
||||
{
|
||||
return SyntaxFactory.MarkupTagBlock(default(SyntaxList<RazorSyntaxNode>));
|
||||
}
|
||||
|
||||
/// <summary>Creates a new MarkupMinimizedAttributeBlockSyntax instance.</summary>
|
||||
public static MarkupMinimizedAttributeBlockSyntax MarkupMinimizedAttributeBlock(MarkupTextLiteralSyntax namePrefix, MarkupTextLiteralSyntax name)
|
||||
{
|
||||
|
|
@ -1010,27 +990,100 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
}
|
||||
|
||||
/// <summary>Creates a new MarkupStartTagSyntax instance.</summary>
|
||||
public static MarkupStartTagSyntax MarkupStartTag(SyntaxList<RazorSyntaxNode> children)
|
||||
public static MarkupStartTagSyntax MarkupStartTag(SyntaxToken openAngle, SyntaxToken bang, SyntaxToken name, SyntaxList<RazorSyntaxNode> attributes, SyntaxToken forwardSlash, SyntaxToken closeAngle)
|
||||
{
|
||||
return (MarkupStartTagSyntax)InternalSyntax.SyntaxFactory.MarkupStartTag(children.Node.ToGreenList<InternalSyntax.RazorSyntaxNode>()).CreateRed();
|
||||
switch (openAngle.Kind)
|
||||
{
|
||||
case SyntaxKind.OpenAngle:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("openAngle");
|
||||
}
|
||||
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 (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 (MarkupStartTagSyntax)InternalSyntax.SyntaxFactory.MarkupStartTag((Syntax.InternalSyntax.SyntaxToken)openAngle.Green, (Syntax.InternalSyntax.SyntaxToken)bang.Green, (Syntax.InternalSyntax.SyntaxToken)name.Green, attributes.Node.ToGreenList<InternalSyntax.RazorSyntaxNode>(), (Syntax.InternalSyntax.SyntaxToken)forwardSlash.Green, (Syntax.InternalSyntax.SyntaxToken)closeAngle.Green).CreateRed();
|
||||
}
|
||||
|
||||
/// <summary>Creates a new MarkupStartTagSyntax instance.</summary>
|
||||
public static MarkupStartTagSyntax MarkupStartTag()
|
||||
public static MarkupStartTagSyntax MarkupStartTag(SyntaxList<RazorSyntaxNode> attributes = default(SyntaxList<RazorSyntaxNode>))
|
||||
{
|
||||
return SyntaxFactory.MarkupStartTag(default(SyntaxList<RazorSyntaxNode>));
|
||||
return SyntaxFactory.MarkupStartTag(SyntaxFactory.Token(SyntaxKind.OpenAngle), default(SyntaxToken), SyntaxFactory.Token(SyntaxKind.Text), attributes, default(SyntaxToken), SyntaxFactory.Token(SyntaxKind.CloseAngle));
|
||||
}
|
||||
|
||||
/// <summary>Creates a new MarkupEndTagSyntax instance.</summary>
|
||||
public static MarkupEndTagSyntax MarkupEndTag(SyntaxList<RazorSyntaxNode> children)
|
||||
public static MarkupEndTagSyntax MarkupEndTag(SyntaxToken openAngle, SyntaxToken forwardSlash, SyntaxToken bang, SyntaxToken name, MarkupMiscAttributeContentSyntax miscAttributeContent, SyntaxToken closeAngle)
|
||||
{
|
||||
return (MarkupEndTagSyntax)InternalSyntax.SyntaxFactory.MarkupEndTag(children.Node.ToGreenList<InternalSyntax.RazorSyntaxNode>()).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");
|
||||
}
|
||||
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 (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();
|
||||
}
|
||||
|
||||
/// <summary>Creates a new MarkupEndTagSyntax instance.</summary>
|
||||
public static MarkupEndTagSyntax MarkupEndTag()
|
||||
public static MarkupEndTagSyntax MarkupEndTag(MarkupMiscAttributeContentSyntax miscAttributeContent = default(MarkupMiscAttributeContentSyntax))
|
||||
{
|
||||
return SyntaxFactory.MarkupEndTag(default(SyntaxList<RazorSyntaxNode>));
|
||||
return SyntaxFactory.MarkupEndTag(SyntaxFactory.Token(SyntaxKind.OpenAngle), SyntaxFactory.Token(SyntaxKind.ForwardSlash), default(SyntaxToken), SyntaxFactory.Token(SyntaxKind.Text), miscAttributeContent, SyntaxFactory.Token(SyntaxKind.CloseAngle));
|
||||
}
|
||||
|
||||
/// <summary>Creates a new MarkupTagHelperElementSyntax instance.</summary>
|
||||
|
|
|
|||
|
|
@ -782,77 +782,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
}
|
||||
}
|
||||
|
||||
internal sealed partial class MarkupTagBlockSyntax : RazorBlockSyntax
|
||||
{
|
||||
private SyntaxNode _children;
|
||||
|
||||
internal MarkupTagBlockSyntax(GreenNode green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
public override SyntaxList<RazorSyntaxNode> Children
|
||||
{
|
||||
get
|
||||
{
|
||||
return new SyntaxList<RazorSyntaxNode>(GetRed(ref _children, 0));
|
||||
}
|
||||
}
|
||||
|
||||
internal override SyntaxNode GetNodeSlot(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return GetRedAtZero(ref _children);
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
internal override SyntaxNode GetCachedSlot(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return _children;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
public override TResult Accept<TResult>(SyntaxVisitor<TResult> visitor)
|
||||
{
|
||||
return visitor.VisitMarkupTagBlock(this);
|
||||
}
|
||||
|
||||
public override void Accept(SyntaxVisitor visitor)
|
||||
{
|
||||
visitor.VisitMarkupTagBlock(this);
|
||||
}
|
||||
|
||||
public MarkupTagBlockSyntax Update(SyntaxList<RazorSyntaxNode> children)
|
||||
{
|
||||
if (children != Children)
|
||||
{
|
||||
var newNode = SyntaxFactory.MarkupTagBlock(children);
|
||||
var annotations = GetAnnotations();
|
||||
if (annotations != null && annotations.Length > 0)
|
||||
return newNode.WithAnnotations(annotations);
|
||||
return newNode;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
internal override RazorBlockSyntax WithChildrenCore(SyntaxList<RazorSyntaxNode> children) => WithChildren(children);
|
||||
public new MarkupTagBlockSyntax WithChildren(SyntaxList<RazorSyntaxNode> children)
|
||||
{
|
||||
return Update(children);
|
||||
}
|
||||
internal override RazorBlockSyntax AddChildrenCore(params RazorSyntaxNode[] items) => AddChildren(items);
|
||||
|
||||
public new MarkupTagBlockSyntax AddChildren(params RazorSyntaxNode[] items)
|
||||
{
|
||||
return WithChildren(this.Children.AddRange(items));
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed partial class MarkupMinimizedAttributeBlockSyntax : MarkupSyntaxNode
|
||||
{
|
||||
private MarkupTextLiteralSyntax _namePrefix;
|
||||
|
|
@ -1475,38 +1404,77 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
return Update(StartTag, Body, endTag);
|
||||
}
|
||||
|
||||
public MarkupElementSyntax AddStartTagChildren(params RazorSyntaxNode[] items)
|
||||
public MarkupElementSyntax AddStartTagAttributes(params RazorSyntaxNode[] items)
|
||||
{
|
||||
var _startTag = this.StartTag ?? SyntaxFactory.MarkupStartTag();
|
||||
return this.WithStartTag(_startTag.WithChildren(_startTag.Children.AddRange(items)));
|
||||
return this.WithStartTag(_startTag.WithAttributes(_startTag.Attributes.AddRange(items)));
|
||||
}
|
||||
|
||||
public MarkupElementSyntax AddBody(params RazorSyntaxNode[] items)
|
||||
{
|
||||
return WithBody(this.Body.AddRange(items));
|
||||
}
|
||||
|
||||
public MarkupElementSyntax AddEndTagChildren(params RazorSyntaxNode[] items)
|
||||
{
|
||||
var _endTag = this.EndTag ?? SyntaxFactory.MarkupEndTag();
|
||||
return this.WithEndTag(_endTag.WithChildren(_endTag.Children.AddRange(items)));
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed partial class MarkupStartTagSyntax : RazorBlockSyntax
|
||||
internal sealed partial class MarkupStartTagSyntax : MarkupSyntaxNode
|
||||
{
|
||||
private SyntaxNode _children;
|
||||
private SyntaxToken _openAngle;
|
||||
private SyntaxToken _bang;
|
||||
private SyntaxToken _name;
|
||||
private SyntaxNode _attributes;
|
||||
private SyntaxToken _forwardSlash;
|
||||
private SyntaxToken _closeAngle;
|
||||
|
||||
internal MarkupStartTagSyntax(GreenNode green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
public override SyntaxList<RazorSyntaxNode> Children
|
||||
public SyntaxToken OpenAngle
|
||||
{
|
||||
get
|
||||
{
|
||||
return new SyntaxList<RazorSyntaxNode>(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<RazorSyntaxNode> Attributes
|
||||
{
|
||||
get
|
||||
{
|
||||
return new SyntaxList<RazorSyntaxNode>(GetRed(ref _attributes, 3));
|
||||
}
|
||||
}
|
||||
|
||||
public SyntaxToken ForwardSlash
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetRed(ref _forwardSlash, 4);
|
||||
}
|
||||
}
|
||||
|
||||
public SyntaxToken CloseAngle
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetRed(ref _closeAngle, 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1514,7 +1482,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1522,7 +1495,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1537,11 +1515,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
visitor.VisitMarkupStartTag(this);
|
||||
}
|
||||
|
||||
public MarkupStartTagSyntax Update(SyntaxList<RazorSyntaxNode> children)
|
||||
public MarkupStartTagSyntax Update(SyntaxToken openAngle, SyntaxToken bang, SyntaxToken name, SyntaxList<RazorSyntaxNode> attributes, SyntaxToken forwardSlash, SyntaxToken closeAngle)
|
||||
{
|
||||
if (children != Children)
|
||||
if (openAngle != OpenAngle || bang != Bang || name != Name || attributes != Attributes || forwardSlash != ForwardSlash || closeAngle != CloseAngle)
|
||||
{
|
||||
var newNode = SyntaxFactory.MarkupStartTag(children);
|
||||
var newNode = SyntaxFactory.MarkupStartTag(openAngle, bang, name, attributes, forwardSlash, closeAngle);
|
||||
var annotations = GetAnnotations();
|
||||
if (annotations != null && annotations.Length > 0)
|
||||
return newNode.WithAnnotations(annotations);
|
||||
|
|
@ -1551,33 +1529,101 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
return this;
|
||||
}
|
||||
|
||||
internal override RazorBlockSyntax WithChildrenCore(SyntaxList<RazorSyntaxNode> children) => WithChildren(children);
|
||||
public new MarkupStartTagSyntax WithChildren(SyntaxList<RazorSyntaxNode> children)
|
||||
public MarkupStartTagSyntax 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 MarkupStartTagSyntax AddChildren(params RazorSyntaxNode[] items)
|
||||
public MarkupStartTagSyntax WithBang(SyntaxToken bang)
|
||||
{
|
||||
return WithChildren(this.Children.AddRange(items));
|
||||
return Update(OpenAngle, bang, Name, Attributes, ForwardSlash, CloseAngle);
|
||||
}
|
||||
|
||||
public MarkupStartTagSyntax WithName(SyntaxToken name)
|
||||
{
|
||||
return Update(OpenAngle, Bang, name, Attributes, ForwardSlash, CloseAngle);
|
||||
}
|
||||
|
||||
public MarkupStartTagSyntax WithAttributes(SyntaxList<RazorSyntaxNode> attributes)
|
||||
{
|
||||
return Update(OpenAngle, Bang, Name, attributes, ForwardSlash, CloseAngle);
|
||||
}
|
||||
|
||||
public MarkupStartTagSyntax WithForwardSlash(SyntaxToken forwardSlash)
|
||||
{
|
||||
return Update(OpenAngle, Bang, Name, Attributes, forwardSlash, CloseAngle);
|
||||
}
|
||||
|
||||
public MarkupStartTagSyntax WithCloseAngle(SyntaxToken closeAngle)
|
||||
{
|
||||
return Update(OpenAngle, Bang, Name, Attributes, ForwardSlash, closeAngle);
|
||||
}
|
||||
|
||||
public MarkupStartTagSyntax AddAttributes(params RazorSyntaxNode[] items)
|
||||
{
|
||||
return WithAttributes(this.Attributes.AddRange(items));
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed partial class MarkupEndTagSyntax : RazorBlockSyntax
|
||||
internal sealed partial class MarkupEndTagSyntax : MarkupSyntaxNode
|
||||
{
|
||||
private SyntaxNode _children;
|
||||
private SyntaxToken _openAngle;
|
||||
private SyntaxToken _forwardSlash;
|
||||
private SyntaxToken _bang;
|
||||
private SyntaxToken _name;
|
||||
private MarkupMiscAttributeContentSyntax _miscAttributeContent;
|
||||
private SyntaxToken _closeAngle;
|
||||
|
||||
internal MarkupEndTagSyntax(GreenNode green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
public override SyntaxList<RazorSyntaxNode> Children
|
||||
public SyntaxToken OpenAngle
|
||||
{
|
||||
get
|
||||
{
|
||||
return new SyntaxList<RazorSyntaxNode>(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1585,7 +1631,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1593,7 +1644,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1608,11 +1664,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
visitor.VisitMarkupEndTag(this);
|
||||
}
|
||||
|
||||
public MarkupEndTagSyntax Update(SyntaxList<RazorSyntaxNode> children)
|
||||
public MarkupEndTagSyntax 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.MarkupEndTag(children);
|
||||
var newNode = SyntaxFactory.MarkupEndTag(openAngle, forwardSlash, bang, name, miscAttributeContent, closeAngle);
|
||||
var annotations = GetAnnotations();
|
||||
if (annotations != null && annotations.Length > 0)
|
||||
return newNode.WithAnnotations(annotations);
|
||||
|
|
@ -1622,16 +1678,40 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
return this;
|
||||
}
|
||||
|
||||
internal override RazorBlockSyntax WithChildrenCore(SyntaxList<RazorSyntaxNode> children) => WithChildren(children);
|
||||
public new MarkupEndTagSyntax WithChildren(SyntaxList<RazorSyntaxNode> children)
|
||||
public MarkupEndTagSyntax 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 MarkupEndTagSyntax AddChildren(params RazorSyntaxNode[] items)
|
||||
public MarkupEndTagSyntax WithForwardSlash(SyntaxToken forwardSlash)
|
||||
{
|
||||
return WithChildren(this.Children.AddRange(items));
|
||||
return Update(OpenAngle, forwardSlash, Bang, Name, MiscAttributeContent, CloseAngle);
|
||||
}
|
||||
|
||||
public MarkupEndTagSyntax WithBang(SyntaxToken bang)
|
||||
{
|
||||
return Update(OpenAngle, ForwardSlash, bang, Name, MiscAttributeContent, CloseAngle);
|
||||
}
|
||||
|
||||
public MarkupEndTagSyntax WithName(SyntaxToken name)
|
||||
{
|
||||
return Update(OpenAngle, ForwardSlash, Bang, name, MiscAttributeContent, CloseAngle);
|
||||
}
|
||||
|
||||
public MarkupEndTagSyntax WithMiscAttributeContent(MarkupMiscAttributeContentSyntax miscAttributeContent)
|
||||
{
|
||||
return Update(OpenAngle, ForwardSlash, Bang, Name, miscAttributeContent, CloseAngle);
|
||||
}
|
||||
|
||||
public MarkupEndTagSyntax WithCloseAngle(SyntaxToken closeAngle)
|
||||
{
|
||||
return Update(OpenAngle, ForwardSlash, Bang, Name, MiscAttributeContent, closeAngle);
|
||||
}
|
||||
|
||||
public MarkupEndTagSyntax AddMiscAttributeContentChildren(params RazorSyntaxNode[] items)
|
||||
{
|
||||
var _miscAttributeContent = this.MiscAttributeContent ?? SyntaxFactory.MarkupMiscAttributeContent();
|
||||
return this.WithMiscAttributeContent(_miscAttributeContent.WithChildren(_miscAttributeContent.Children.AddRange(items)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal sealed partial class MarkupEndTagSyntax
|
||||
{
|
||||
private static readonly string MarkupTransitionKey = "MarkupTransition";
|
||||
|
||||
public bool IsMarkupTransition
|
||||
{
|
||||
get
|
||||
{
|
||||
var annotation = GetAnnotations().FirstOrDefault(n => n.Kind == MarkupTransitionKey);
|
||||
return annotation != null;
|
||||
}
|
||||
}
|
||||
|
||||
public MarkupEndTagSyntax AsMarkupTransition()
|
||||
{
|
||||
var annotations = new List<SyntaxAnnotation>(GetAnnotations())
|
||||
{
|
||||
new SyntaxAnnotation(MarkupTransitionKey, new object())
|
||||
};
|
||||
|
||||
var newGreen = this.WithAnnotationsGreen(annotations.ToArray());
|
||||
|
||||
return newGreen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal sealed partial class MarkupStartTagSyntax
|
||||
{
|
||||
private static readonly string MarkupTransitionKey = "MarkupTransition";
|
||||
|
||||
public bool IsMarkupTransition
|
||||
{
|
||||
get
|
||||
{
|
||||
var annotation = GetAnnotations().FirstOrDefault(n => n.Kind == MarkupTransitionKey);
|
||||
return annotation != null;
|
||||
}
|
||||
}
|
||||
|
||||
public MarkupStartTagSyntax AsMarkupTransition()
|
||||
{
|
||||
var annotations = new List<SyntaxAnnotation>(GetAnnotations())
|
||||
{
|
||||
new SyntaxAnnotation(MarkupTransitionKey, new object())
|
||||
};
|
||||
|
||||
var newGreen = this.WithAnnotationsGreen(annotations.ToArray());
|
||||
|
||||
return newGreen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Razor.Language.Legacy;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal partial class MarkupEndTagSyntax
|
||||
{
|
||||
public bool IsMarkupTransition
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((InternalSyntax.MarkupEndTagSyntax)Green).IsMarkupTransition;
|
||||
}
|
||||
}
|
||||
|
||||
public SyntaxList<RazorSyntaxNode> Children => GetLegacyChildren();
|
||||
|
||||
public string GetTagName()
|
||||
{
|
||||
return Name.IsMissing ? string.Empty : Bang?.Content + Name.Content;
|
||||
}
|
||||
|
||||
private SyntaxList<RazorSyntaxNode> GetLegacyChildren()
|
||||
{
|
||||
// This method returns the children of this end tag in legacy format.
|
||||
// This is needed to generate the same classified spans as the legacy syntax tree.
|
||||
var builder = new SyntaxListBuilder(3);
|
||||
var tokens = SyntaxListBuilder<SyntaxToken>.Create();
|
||||
var context = this.GetSpanContext();
|
||||
if (!OpenAngle.IsMissing)
|
||||
{
|
||||
tokens.Add(OpenAngle);
|
||||
}
|
||||
if (!ForwardSlash.IsMissing)
|
||||
{
|
||||
tokens.Add(ForwardSlash);
|
||||
}
|
||||
if (Bang != null)
|
||||
{
|
||||
// The prefix of an end tag(E.g '|</|!foo>') will have 'Any' accepted characters if a bang exists.
|
||||
var acceptsAnyContext = new SpanContext(context.ChunkGenerator, SpanEditHandler.CreateDefault());
|
||||
acceptsAnyContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any;
|
||||
builder.Add(SyntaxFactory.MarkupTextLiteral(tokens.Consume()).WithSpanContext(acceptsAnyContext));
|
||||
|
||||
tokens.Add(Bang);
|
||||
var acceptsNoneContext = new SpanContext(context.ChunkGenerator, SpanEditHandler.CreateDefault());
|
||||
acceptsNoneContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None;
|
||||
builder.Add(SyntaxFactory.RazorMetaCode(tokens.Consume()).WithSpanContext(acceptsNoneContext));
|
||||
}
|
||||
if (!Name.IsMissing)
|
||||
{
|
||||
tokens.Add(Name);
|
||||
}
|
||||
if (MiscAttributeContent?.Children != null && MiscAttributeContent.Children.Count > 0)
|
||||
{
|
||||
foreach (var content in MiscAttributeContent.Children)
|
||||
{
|
||||
tokens.AddRange(((MarkupTextLiteralSyntax)content).LiteralTokens);
|
||||
}
|
||||
}
|
||||
if (!CloseAngle.IsMissing)
|
||||
{
|
||||
tokens.Add(CloseAngle);
|
||||
}
|
||||
builder.Add(SyntaxFactory.MarkupTextLiteral(tokens.Consume()).WithSpanContext(context));
|
||||
|
||||
return new SyntaxList<RazorSyntaxNode>(builder.ToListNode().CreateRed(this, Position));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Razor.Language.Legacy;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal partial class MarkupStartTagSyntax
|
||||
{
|
||||
public bool IsMarkupTransition
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((InternalSyntax.MarkupStartTagSyntax)Green).IsMarkupTransition;
|
||||
}
|
||||
}
|
||||
|
||||
public SyntaxList<RazorSyntaxNode> Children => GetLegacyChildren();
|
||||
|
||||
public string GetTagNameWithOptionalBang()
|
||||
{
|
||||
return Name.IsMissing ? string.Empty : Bang?.Content + Name.Content;
|
||||
}
|
||||
|
||||
public bool IsSelfClosing()
|
||||
{
|
||||
return ForwardSlash != null &&
|
||||
!ForwardSlash.IsMissing &&
|
||||
!CloseAngle.IsMissing;
|
||||
}
|
||||
|
||||
public bool IsVoidElement()
|
||||
{
|
||||
return ParserHelpers.VoidElements.Contains(Name.Content);
|
||||
}
|
||||
|
||||
private SyntaxList<RazorSyntaxNode> GetLegacyChildren()
|
||||
{
|
||||
// This method returns the children of this start tag in legacy format.
|
||||
// This is needed to generate the same classified spans as the legacy syntax tree.
|
||||
var builder = new SyntaxListBuilder(5);
|
||||
var tokens = SyntaxListBuilder<SyntaxToken>.Create();
|
||||
var context = this.GetSpanContext();
|
||||
|
||||
// We want to know if this tag contains non-whitespace attribute content to set the appropriate AcceptedCharacters.
|
||||
// The prefix of a start tag(E.g '|<foo| attr>') will have 'Any' accepted characters if non-whitespace attribute content exists.
|
||||
var acceptsAnyContext = new SpanContext(context.ChunkGenerator, SpanEditHandler.CreateDefault());
|
||||
acceptsAnyContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.Any;
|
||||
var containsAttributesContent = false;
|
||||
foreach (var attribute in Attributes)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(attribute.GetContent()))
|
||||
{
|
||||
containsAttributesContent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!OpenAngle.IsMissing)
|
||||
{
|
||||
tokens.Add(OpenAngle);
|
||||
}
|
||||
if (Bang != null)
|
||||
{
|
||||
builder.Add(SyntaxFactory.MarkupTextLiteral(tokens.Consume()).WithSpanContext(acceptsAnyContext));
|
||||
|
||||
tokens.Add(Bang);
|
||||
var acceptsNoneContext = new SpanContext(context.ChunkGenerator, SpanEditHandler.CreateDefault());
|
||||
acceptsNoneContext.EditHandler.AcceptedCharacters = AcceptedCharactersInternal.None;
|
||||
builder.Add(SyntaxFactory.RazorMetaCode(tokens.Consume()).WithSpanContext(acceptsNoneContext));
|
||||
}
|
||||
if (!Name.IsMissing)
|
||||
{
|
||||
tokens.Add(Name);
|
||||
}
|
||||
|
||||
builder.Add(SyntaxFactory.MarkupTextLiteral(tokens.Consume()).WithSpanContext(containsAttributesContent ? acceptsAnyContext : context));
|
||||
|
||||
builder.AddRange(Attributes);
|
||||
|
||||
if (ForwardSlash != null)
|
||||
{
|
||||
tokens.Add(ForwardSlash);
|
||||
}
|
||||
if (!CloseAngle.IsMissing)
|
||||
{
|
||||
tokens.Add(CloseAngle);
|
||||
}
|
||||
|
||||
if (tokens.Count > 0)
|
||||
{
|
||||
builder.Add(SyntaxFactory.MarkupTextLiteral(tokens.Consume()).WithSpanContext(context));
|
||||
}
|
||||
|
||||
return new SyntaxList<RazorSyntaxNode>(builder.ToListNode().CreateRed(this, Position));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -65,10 +65,6 @@
|
|||
<Kind Name="MarkupCommentBlock" />
|
||||
<Field Name="Children" Type="SyntaxList<RazorSyntaxNode>" Override="true" />
|
||||
</Node>
|
||||
<Node Name="MarkupTagBlockSyntax" Base="RazorBlockSyntax">
|
||||
<Kind Name="MarkupTagBlock" />
|
||||
<Field Name="Children" Type="SyntaxList<RazorSyntaxNode>" Override="true" />
|
||||
</Node>
|
||||
<Node Name="MarkupMinimizedAttributeBlockSyntax" Base="MarkupSyntaxNode">
|
||||
<Kind Name="MarkupMinimizedAttributeBlock" />
|
||||
<Field Name="NamePrefix" Type="MarkupTextLiteralSyntax" Optional="true" />
|
||||
|
|
@ -106,13 +102,43 @@
|
|||
<Field Name="Body" Type="SyntaxList<RazorSyntaxNode>" />
|
||||
<Field Name="EndTag" Type="MarkupEndTagSyntax" Optional="true" />
|
||||
</Node>
|
||||
<Node Name="MarkupStartTagSyntax" Base="RazorBlockSyntax">
|
||||
<Node Name="MarkupStartTagSyntax" Base="MarkupSyntaxNode">
|
||||
<Kind Name="MarkupStartTag" />
|
||||
<Field Name="Children" Type="SyntaxList<RazorSyntaxNode>" Override="true" />
|
||||
<Field Name="OpenAngle" Type="SyntaxToken">
|
||||
<Kind Name="OpenAngle" />
|
||||
</Field>
|
||||
<Field Name="Bang" Type="SyntaxToken" Optional="true">
|
||||
<Kind Name="Bang" />
|
||||
</Field>
|
||||
<Field Name="Name" Type="SyntaxToken">
|
||||
<Kind Name="Text" />
|
||||
</Field>
|
||||
<Field Name="Attributes" Type="SyntaxList<RazorSyntaxNode>" />
|
||||
<Field Name="ForwardSlash" Type="SyntaxToken" Optional="true">
|
||||
<Kind Name="ForwardSlash" />
|
||||
</Field>
|
||||
<Field Name="CloseAngle" Type="SyntaxToken">
|
||||
<Kind Name="CloseAngle" />
|
||||
</Field>
|
||||
</Node>
|
||||
<Node Name="MarkupEndTagSyntax" Base="RazorBlockSyntax">
|
||||
<Node Name="MarkupEndTagSyntax" Base="MarkupSyntaxNode">
|
||||
<Kind Name="MarkupEndTag" />
|
||||
<Field Name="Children" Type="SyntaxList<RazorSyntaxNode>" Override="true" />
|
||||
<Field Name="OpenAngle" Type="SyntaxToken">
|
||||
<Kind Name="OpenAngle" />
|
||||
</Field>
|
||||
<Field Name="ForwardSlash" Type="SyntaxToken">
|
||||
<Kind Name="ForwardSlash" />
|
||||
</Field>
|
||||
<Field Name="Bang" Type="SyntaxToken" Optional="true">
|
||||
<Kind Name="Bang" />
|
||||
</Field>
|
||||
<Field Name="Name" Type="SyntaxToken">
|
||||
<Kind Name="Text" />
|
||||
</Field>
|
||||
<Field Name="MiscAttributeContent" Type="MarkupMiscAttributeContentSyntax" Optional="true" />
|
||||
<Field Name="CloseAngle" Type="SyntaxToken">
|
||||
<Kind Name="CloseAngle" />
|
||||
</Field>
|
||||
</Node>
|
||||
<Node Name="MarkupTagHelperElementSyntax" Base="MarkupSyntaxNode">
|
||||
<Kind Name="MarkupTagHelperElement" />
|
||||
|
|
|
|||
|
|
@ -75,6 +75,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
return _builder.ToList();
|
||||
}
|
||||
|
||||
public SyntaxList<TNode> Consume()
|
||||
{
|
||||
var list = ToList();
|
||||
Clear();
|
||||
return list;
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxListBuilder(SyntaxListBuilder<TNode> builder)
|
||||
{
|
||||
return builder._builder;
|
||||
|
|
|
|||
|
|
@ -220,109 +220,5 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
var content = string.Concat(tokens.Select(t => t.Content));
|
||||
return content;
|
||||
}
|
||||
|
||||
public static string GetTagName(this MarkupTagBlockSyntax tagBlock)
|
||||
{
|
||||
return GetTagNameCore(tagBlock);
|
||||
}
|
||||
|
||||
public static string GetTagName(this MarkupStartTagSyntax startTag)
|
||||
{
|
||||
return GetTagNameCore(startTag);
|
||||
}
|
||||
|
||||
public static string GetTagName(this MarkupEndTagSyntax endTag)
|
||||
{
|
||||
return GetTagNameCore(endTag);
|
||||
}
|
||||
|
||||
private static string GetTagNameCore(RazorBlockSyntax tagBlock)
|
||||
{
|
||||
if (tagBlock == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(tagBlock));
|
||||
}
|
||||
|
||||
MarkupTextLiteralSyntax nameLiteral = null;
|
||||
var isBangTag = false;
|
||||
if (tagBlock.Children.Count > 0 && tagBlock.Children[0] is MarkupTextLiteralSyntax firstChild)
|
||||
{
|
||||
if (firstChild.GetContent().StartsWith("<") &&
|
||||
tagBlock.Children.Count >= 3 &&
|
||||
tagBlock.Children[1] is RazorMetaCodeSyntax &&
|
||||
tagBlock.Children[2] is MarkupTextLiteralSyntax potentialBangTagName)
|
||||
{
|
||||
isBangTag = true;
|
||||
nameLiteral = potentialBangTagName;
|
||||
}
|
||||
else
|
||||
{
|
||||
nameLiteral = firstChild;
|
||||
}
|
||||
}
|
||||
|
||||
if (nameLiteral == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
SyntaxToken textToken = null;
|
||||
for (var i = 0; i < nameLiteral.LiteralTokens.Count; i++)
|
||||
{
|
||||
var token = nameLiteral.LiteralTokens[i];
|
||||
|
||||
if (token != null &&
|
||||
(token.Kind == SyntaxKind.Whitespace || token.Kind == SyntaxKind.Text))
|
||||
{
|
||||
textToken = token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (textToken == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var name = textToken.Kind == SyntaxKind.Whitespace ? null : textToken.Content;
|
||||
if (name != null && isBangTag)
|
||||
{
|
||||
name = "!" + name;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public static bool IsSelfClosing(this MarkupTagBlockSyntax tagBlock)
|
||||
{
|
||||
return IsSelfClosingCore(tagBlock);
|
||||
}
|
||||
|
||||
public static bool IsSelfClosing(this MarkupStartTagSyntax startTag)
|
||||
{
|
||||
return IsSelfClosingCore(startTag);
|
||||
}
|
||||
|
||||
private static bool IsSelfClosingCore(RazorBlockSyntax tagBlock)
|
||||
{
|
||||
if (tagBlock == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(tagBlock));
|
||||
}
|
||||
|
||||
var lastChild = tagBlock.ChildNodes().LastOrDefault();
|
||||
|
||||
return lastChild?.GetContent().EndsWith("/>", StringComparison.Ordinal) ?? false;
|
||||
}
|
||||
|
||||
public static bool IsVoidElement(this MarkupStartTagSyntax startTag)
|
||||
{
|
||||
if (startTag == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(startTag));
|
||||
}
|
||||
|
||||
return ParserHelpers.VoidElements.Contains(startTag.GetTagName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,6 +151,22 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
{
|
||||
WriteTagHelperAttributeInfo(minimizedTagHelperAttribute.TagHelperAttributeInfo);
|
||||
}
|
||||
else if (node is MarkupStartTagSyntax startTag)
|
||||
{
|
||||
if (startTag.IsMarkupTransition)
|
||||
{
|
||||
WriteSeparator();
|
||||
Write("MarkupTransition");
|
||||
}
|
||||
}
|
||||
else if (node is MarkupEndTagSyntax endTag)
|
||||
{
|
||||
if (endTag.IsMarkupTransition)
|
||||
{
|
||||
WriteSeparator();
|
||||
Write("MarkupTransition");
|
||||
}
|
||||
}
|
||||
|
||||
if (ShouldDisplayNodeContent(node))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -67,6 +67,22 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
|||
{
|
||||
WriteTagHelperAttributeInfo(minimizedTagHelperAttribute.TagHelperAttributeInfo);
|
||||
}
|
||||
else if (node is MarkupStartTagSyntax startTag)
|
||||
{
|
||||
if (startTag.IsMarkupTransition)
|
||||
{
|
||||
WriteSeparator();
|
||||
Write("MarkupTransition");
|
||||
}
|
||||
}
|
||||
else if (node is MarkupEndTagSyntax endTag)
|
||||
{
|
||||
if (endTag.IsMarkupTransition)
|
||||
{
|
||||
WriteSeparator();
|
||||
Write("MarkupTransition");
|
||||
}
|
||||
}
|
||||
|
||||
if (ShouldDisplayNodeContent(node))
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue