Initial infrastrucure for a better html parser (#2522)
Initial infrastrucure for a better html parser - Added new syntax node types that follow Roslyn's red/green pattern - Modified the html text node in the current syntax tree to use the new nodes - Updated test infrastructure - Generated baselines
This commit is contained in:
parent
7450a3a0fb
commit
9a9931d59f
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
{
|
||||
|
|
@ -33,6 +35,15 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
public CSharpKeyword? Keyword { get; set; }
|
||||
|
||||
protected override SyntaxToken GetSyntaxToken()
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
default:
|
||||
return SyntaxFactory.UnknownToken(Content, Errors.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var other = obj as CSharpToken;
|
||||
|
|
|
|||
|
|
@ -1590,6 +1590,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
Span.Start = CurrentLocation;
|
||||
|
||||
ParserState = ParserState.Misc;
|
||||
NextToken();
|
||||
while (!EndOfFile)
|
||||
{
|
||||
|
|
@ -1636,7 +1637,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
return;
|
||||
}
|
||||
|
||||
Output(SpanKindInternal.Markup);
|
||||
if (ParserState == ParserState.Content)
|
||||
{
|
||||
Output(SpanKindInternal.Markup, SyntaxKind.HtmlText);
|
||||
}
|
||||
else
|
||||
{
|
||||
Output(SpanKindInternal.Markup);
|
||||
}
|
||||
|
||||
// Start tag block
|
||||
var tagBlock = Context.Builder.StartBlock(BlockKindInternal.Tag);
|
||||
|
|
@ -1645,6 +1653,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
if (!At(HtmlTokenType.ForwardSlash))
|
||||
{
|
||||
ParserState = ParserState.StartTag;
|
||||
OptionalBangEscape();
|
||||
|
||||
// Parsing a start tag
|
||||
|
|
@ -1655,6 +1664,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
Optional(HtmlTokenType.ForwardSlash);
|
||||
Optional(HtmlTokenType.CloseAngle);
|
||||
|
||||
ParserState = ParserState.Content;
|
||||
|
||||
// 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 (scriptTag && !CurrentScriptTagExpectsHtml())
|
||||
|
|
@ -1670,6 +1681,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
// Parsing an end tag
|
||||
// This section can accept things like: '</p >' or '</p>' etc.
|
||||
ParserState = ParserState.EndTag;
|
||||
Optional(HtmlTokenType.ForwardSlash);
|
||||
|
||||
// Whitespace here is invalid (according to the spec)
|
||||
|
|
@ -1677,6 +1689,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
Optional(HtmlTokenType.Text);
|
||||
Optional(HtmlTokenType.WhiteSpace);
|
||||
Optional(HtmlTokenType.CloseAngle);
|
||||
ParserState = ParserState.Content;
|
||||
}
|
||||
|
||||
Output(SpanKindInternal.Markup);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
{
|
||||
|
|
@ -30,5 +32,46 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
throw new ArgumentNullException(nameof(content));
|
||||
}
|
||||
}
|
||||
|
||||
protected override SyntaxToken GetSyntaxToken()
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case HtmlTokenType.Text:
|
||||
return SyntaxFactory.HtmlTextToken(Content, Errors.ToArray());
|
||||
case HtmlTokenType.WhiteSpace:
|
||||
return SyntaxFactory.WhitespaceToken(Content, Errors.ToArray());
|
||||
case HtmlTokenType.NewLine:
|
||||
return SyntaxFactory.NewLineToken(Content, Errors.ToArray());
|
||||
case HtmlTokenType.OpenAngle:
|
||||
return SyntaxFactory.Punctuation(SyntaxKind.OpenAngle, Content, Errors.ToArray());
|
||||
case HtmlTokenType.Bang:
|
||||
return SyntaxFactory.Punctuation(SyntaxKind.Bang, Content, Errors.ToArray());
|
||||
case HtmlTokenType.ForwardSlash:
|
||||
return SyntaxFactory.Punctuation(SyntaxKind.ForwardSlash, Content, Errors.ToArray());
|
||||
case HtmlTokenType.QuestionMark:
|
||||
return SyntaxFactory.Punctuation(SyntaxKind.QuestionMark, Content, Errors.ToArray());
|
||||
case HtmlTokenType.DoubleHyphen:
|
||||
return SyntaxFactory.Punctuation(SyntaxKind.DoubleHyphen, Content, Errors.ToArray());
|
||||
case HtmlTokenType.LeftBracket:
|
||||
return SyntaxFactory.Punctuation(SyntaxKind.LeftBracket, Content, Errors.ToArray());
|
||||
case HtmlTokenType.CloseAngle:
|
||||
return SyntaxFactory.Punctuation(SyntaxKind.CloseAngle, Content, Errors.ToArray());
|
||||
case HtmlTokenType.RightBracket:
|
||||
return SyntaxFactory.Punctuation(SyntaxKind.RightBracket, Content, Errors.ToArray());
|
||||
case HtmlTokenType.Equals:
|
||||
return SyntaxFactory.Punctuation(SyntaxKind.Equals, Content, Errors.ToArray());
|
||||
case HtmlTokenType.DoubleQuote:
|
||||
return SyntaxFactory.Punctuation(SyntaxKind.DoubleQuote, Content, Errors.ToArray());
|
||||
case HtmlTokenType.SingleQuote:
|
||||
return SyntaxFactory.Punctuation(SyntaxKind.SingleQuote, Content, Errors.ToArray());
|
||||
case HtmlTokenType.Transition:
|
||||
return SyntaxFactory.Punctuation(SyntaxKind.Transition, Content, Errors.ToArray());
|
||||
case HtmlTokenType.Colon:
|
||||
return SyntaxFactory.Punctuation(SyntaxKind.Colon, Content, Errors.ToArray());
|
||||
default:
|
||||
return SyntaxFactory.UnknownToken(Content, Errors.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
// 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.Syntax.InternalSyntax;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
{
|
||||
internal interface IToken
|
||||
|
|
@ -10,5 +12,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
string Content { get; }
|
||||
|
||||
SourceLocation Start { get; }
|
||||
|
||||
SyntaxKind SyntaxKind { get; }
|
||||
|
||||
SyntaxToken SyntaxToken { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
{
|
||||
|
|
@ -31,6 +32,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
public SpanEditHandler EditHandler { get; private set; }
|
||||
|
||||
public HtmlNodeSyntax SyntaxNode { get; private set; }
|
||||
|
||||
public override bool IsBlock => false;
|
||||
|
||||
public override int Length
|
||||
|
|
@ -94,6 +97,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
Kind = builder.Kind;
|
||||
Tokens = builder.Tokens;
|
||||
SyntaxNode = builder.SyntaxNode;
|
||||
|
||||
for (var i = 0; i <Tokens.Count; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
{
|
||||
|
|
@ -33,6 +35,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
Start = location;
|
||||
}
|
||||
|
||||
public HtmlNodeSyntax SyntaxNode { get; private set; }
|
||||
|
||||
public ISpanChunkGenerator ChunkGenerator { get; set; }
|
||||
|
||||
public SourceLocation Start
|
||||
|
|
@ -76,8 +80,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
Start = SourceLocation.Undefined;
|
||||
}
|
||||
|
||||
public Span Build()
|
||||
public Span Build(SyntaxKind syntaxKind = SyntaxKind.Unknown)
|
||||
{
|
||||
SyntaxNode = GetSyntaxNode(syntaxKind);
|
||||
|
||||
var span = new Span(this);
|
||||
|
||||
for (var i = 0; i < span.Tokens.Count; i++)
|
||||
|
|
@ -109,5 +115,27 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
_tokens.Add(token);
|
||||
_tracker.UpdateLocation(token.Content);
|
||||
}
|
||||
|
||||
private HtmlNodeSyntax GetSyntaxNode(SyntaxKind syntaxKind)
|
||||
{
|
||||
if (syntaxKind == SyntaxKind.HtmlText)
|
||||
{
|
||||
var textTokens = new SyntaxListBuilder<SyntaxToken>(SyntaxListBuilder.Create());
|
||||
foreach (var token in Tokens)
|
||||
{
|
||||
if (token.SyntaxKind == SyntaxKind.Unknown)
|
||||
{
|
||||
Debug.Assert(false, $"Unexpected html token {((HtmlToken)token).Type}");
|
||||
continue;
|
||||
}
|
||||
|
||||
textTokens.Add(token.SyntaxToken);
|
||||
}
|
||||
var textResult = textTokens.ToList();
|
||||
return SyntaxFactory.HtmlText(new SyntaxList<SyntaxToken>(textResult.Node));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
|
|
@ -58,10 +59,15 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
}
|
||||
}
|
||||
|
||||
public SyntaxKind SyntaxKind => SyntaxToken.Kind;
|
||||
|
||||
public SyntaxToken SyntaxToken => GetSyntaxToken();
|
||||
|
||||
protected abstract SyntaxToken GetSyntaxToken();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var other = obj as TokenBase<TType>;
|
||||
return other != null &&
|
||||
return obj is TokenBase<TType> other &&
|
||||
string.Equals(Content, other.Content, StringComparison.Ordinal) &&
|
||||
Type.Equals(other.Type);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
{
|
||||
|
|
@ -25,6 +26,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
Span = new SpanBuilder(CurrentLocation);
|
||||
}
|
||||
|
||||
protected ParserState ParserState { get; set; }
|
||||
|
||||
protected SpanBuilder Span { get; private set; }
|
||||
|
||||
protected Action<SpanBuilder> SpanConfig { get; set; }
|
||||
|
|
@ -34,6 +37,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
get { return _tokenizer.Current; }
|
||||
}
|
||||
|
||||
protected SyntaxToken CurrentSyntaxToken => CurrentToken?.SyntaxToken;
|
||||
|
||||
protected TToken PreviousToken { get; private set; }
|
||||
|
||||
protected SourceLocation CurrentLocation => _tokenizer.Tokenizer.CurrentLocation;
|
||||
|
|
@ -388,31 +393,31 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
}
|
||||
}
|
||||
|
||||
protected internal void Output(SpanKindInternal kind)
|
||||
protected internal void Output(SpanKindInternal kind, SyntaxKind syntaxKind = SyntaxKind.Unknown)
|
||||
{
|
||||
Configure(kind, null);
|
||||
Output();
|
||||
Output(syntaxKind);
|
||||
}
|
||||
|
||||
protected internal void Output(SpanKindInternal kind, AcceptedCharactersInternal accepts)
|
||||
protected internal void Output(SpanKindInternal kind, AcceptedCharactersInternal accepts, SyntaxKind syntaxKind = SyntaxKind.Unknown)
|
||||
{
|
||||
Configure(kind, accepts);
|
||||
Output();
|
||||
Output(syntaxKind);
|
||||
}
|
||||
|
||||
protected internal void Output(AcceptedCharactersInternal accepts)
|
||||
protected internal void Output(AcceptedCharactersInternal accepts, SyntaxKind syntaxKind = SyntaxKind.Unknown)
|
||||
{
|
||||
Configure(null, accepts);
|
||||
Output();
|
||||
Output(syntaxKind);
|
||||
}
|
||||
|
||||
private void Output()
|
||||
private void Output(SyntaxKind syntaxKind)
|
||||
{
|
||||
if (Span.Tokens.Count > 0)
|
||||
{
|
||||
var nextStart = Span.End;
|
||||
|
||||
var builtSpan = Span.Build();
|
||||
var builtSpan = Span.Build(syntaxKind);
|
||||
Context.Builder.Add(builtSpan);
|
||||
Initialize(Span);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal struct ArrayElement<T>
|
||||
{
|
||||
public T Value;
|
||||
|
||||
public static implicit operator T(ArrayElement<T> element)
|
||||
{
|
||||
return element.Value;
|
||||
}
|
||||
|
||||
//NOTE: there is no opposite conversion operator T -> ArrayElement<T>
|
||||
//
|
||||
// that is because it is preferred to update array elements in-place
|
||||
// "elements[i].Value = v" results in much better code than "elements[i] = (ArrayElement<T>)v"
|
||||
//
|
||||
// The reason is that x86 ABI requires that structs must be returned in
|
||||
// a return buffer even if they can fit in a register like this one.
|
||||
// Also since struct contains a reference, the write to the buffer is done with a checked GC barrier
|
||||
// as JIT does not know if the write goes to a stack or a heap location.
|
||||
// Assigning to Value directly easily avoids all this redundancy.
|
||||
|
||||
public static ArrayElement<T>[] MakeElementArray(T[] items)
|
||||
{
|
||||
if (items == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var array = new ArrayElement<T>[items.Length];
|
||||
for (var i = 0; i < items.Length; i++)
|
||||
{
|
||||
array[i].Value = items[i];
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
public static T[] MakeArray(ArrayElement<T>[] items)
|
||||
{
|
||||
if (items == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var array = new T[items.Length];
|
||||
for (var i = 0; i < items.Length; i++)
|
||||
{
|
||||
array[i] = items[i].Value;
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,514 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal abstract class GreenNode
|
||||
{
|
||||
private static readonly RazorDiagnostic[] EmptyDiagnostics = Array.Empty<RazorDiagnostic>();
|
||||
private static readonly SyntaxAnnotation[] EmptyAnnotations = Array.Empty<SyntaxAnnotation>();
|
||||
private static readonly ConditionalWeakTable<GreenNode, RazorDiagnostic[]> DiagnosticsTable =
|
||||
new ConditionalWeakTable<GreenNode, RazorDiagnostic[]>();
|
||||
private static readonly ConditionalWeakTable<GreenNode, SyntaxAnnotation[]> AnnotationsTable =
|
||||
new ConditionalWeakTable<GreenNode, SyntaxAnnotation[]>();
|
||||
|
||||
private NodeFlags _flags;
|
||||
private byte _slotCount;
|
||||
|
||||
protected GreenNode(SyntaxKind kind)
|
||||
{
|
||||
Kind = kind;
|
||||
}
|
||||
|
||||
protected GreenNode(SyntaxKind kind, int fullWidth)
|
||||
: this(kind)
|
||||
{
|
||||
FullWidth = fullWidth;
|
||||
}
|
||||
|
||||
protected GreenNode(SyntaxKind kind, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
: this(kind, 0, diagnostics, annotations)
|
||||
{
|
||||
}
|
||||
|
||||
protected GreenNode(SyntaxKind kind, int fullWidth, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
: this(kind, fullWidth)
|
||||
{
|
||||
if (diagnostics?.Length > 0)
|
||||
{
|
||||
_flags |= NodeFlags.ContainsDiagnostics;
|
||||
DiagnosticsTable.Add(this, diagnostics);
|
||||
}
|
||||
|
||||
if (annotations?.Length > 0)
|
||||
{
|
||||
foreach (var annotation in annotations)
|
||||
{
|
||||
if (annotation == null)
|
||||
{
|
||||
throw new ArgumentException(nameof(annotations), "Annotation cannot be null");
|
||||
}
|
||||
}
|
||||
|
||||
_flags |= NodeFlags.ContainsAnnotations;
|
||||
AnnotationsTable.Add(this, annotations);
|
||||
}
|
||||
}
|
||||
|
||||
protected void AdjustFlagsAndWidth(GreenNode node)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_flags |= (node.Flags & NodeFlags.InheritMask);
|
||||
FullWidth += node.FullWidth;
|
||||
}
|
||||
|
||||
#region Kind
|
||||
internal SyntaxKind Kind { get; }
|
||||
|
||||
internal virtual bool IsList => false;
|
||||
|
||||
internal virtual bool IsToken => false;
|
||||
|
||||
internal virtual bool IsTrivia => false;
|
||||
#endregion
|
||||
|
||||
#region Slots
|
||||
public int SlotCount
|
||||
{
|
||||
get
|
||||
{
|
||||
int count = _slotCount;
|
||||
if (count == byte.MaxValue)
|
||||
{
|
||||
count = GetSlotCount();
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
protected set
|
||||
{
|
||||
_slotCount = (byte)value;
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract GreenNode GetSlot(int index);
|
||||
|
||||
// for slot counts >= byte.MaxValue
|
||||
protected virtual int GetSlotCount()
|
||||
{
|
||||
return _slotCount;
|
||||
}
|
||||
|
||||
public virtual int GetSlotOffset(int index)
|
||||
{
|
||||
var offset = 0;
|
||||
for (var i = 0; i < index; i++)
|
||||
{
|
||||
var child = GetSlot(i);
|
||||
if (child != null)
|
||||
offset += child.FullWidth;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
public virtual int FindSlotIndexContainingOffset(int offset)
|
||||
{
|
||||
Debug.Assert(0 <= offset && offset < FullWidth);
|
||||
|
||||
int i;
|
||||
var accumulatedWidth = 0;
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
Debug.Assert(i < SlotCount);
|
||||
var child = GetSlot(i);
|
||||
if (child != null)
|
||||
{
|
||||
accumulatedWidth += child.FullWidth;
|
||||
if (offset < accumulatedWidth)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Flags
|
||||
internal NodeFlags Flags => _flags;
|
||||
|
||||
internal void SetFlags(NodeFlags flags)
|
||||
{
|
||||
_flags |= flags;
|
||||
}
|
||||
|
||||
internal void ClearFlags(NodeFlags flags)
|
||||
{
|
||||
_flags &= ~flags;
|
||||
}
|
||||
|
||||
internal virtual bool IsMissing => (_flags & NodeFlags.IsMissing) != 0;
|
||||
|
||||
public bool ContainsDiagnostics
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_flags & NodeFlags.ContainsDiagnostics) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ContainsAnnotations
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_flags & NodeFlags.ContainsAnnotations) != 0;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Spans
|
||||
internal int FullWidth { get; private set; }
|
||||
|
||||
public virtual int Width
|
||||
{
|
||||
get
|
||||
{
|
||||
return FullWidth - GetLeadingTriviaWidth() - GetTrailingTriviaWidth();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int GetLeadingTriviaWidth()
|
||||
{
|
||||
return FullWidth != 0 ? GetFirstTerminal().GetLeadingTriviaWidth() : 0;
|
||||
}
|
||||
|
||||
public virtual int GetTrailingTriviaWidth()
|
||||
{
|
||||
return FullWidth != 0 ? GetLastTerminal().GetTrailingTriviaWidth() : 0;
|
||||
}
|
||||
|
||||
public bool HasLeadingTrivia
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetLeadingTriviaWidth() != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasTrailingTrivia
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetTrailingTriviaWidth() != 0;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Diagnostics
|
||||
internal abstract GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics);
|
||||
|
||||
internal RazorDiagnostic[] GetDiagnostics()
|
||||
{
|
||||
if (ContainsDiagnostics)
|
||||
{
|
||||
if (DiagnosticsTable.TryGetValue(this, out var diagnostics))
|
||||
{
|
||||
return diagnostics;
|
||||
}
|
||||
}
|
||||
|
||||
return EmptyDiagnostics;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Annotations
|
||||
internal abstract GreenNode SetAnnotations(SyntaxAnnotation[] annotations);
|
||||
|
||||
internal SyntaxAnnotation[] GetAnnotations()
|
||||
{
|
||||
if (ContainsAnnotations)
|
||||
{
|
||||
if (AnnotationsTable.TryGetValue(this, out var annotations))
|
||||
{
|
||||
Debug.Assert(annotations.Length != 0, "There cannot be an empty annotation entry.");
|
||||
return annotations;
|
||||
}
|
||||
}
|
||||
|
||||
return EmptyAnnotations;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Text
|
||||
public virtual string ToFullString()
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
var writer = new StringWriter(builder, System.Globalization.CultureInfo.InvariantCulture);
|
||||
WriteTo(writer);
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public virtual void WriteTo(TextWriter writer)
|
||||
{
|
||||
WriteTo(writer, leading: true, trailing: true);
|
||||
}
|
||||
|
||||
protected internal void WriteTo(TextWriter writer, bool leading, bool trailing)
|
||||
{
|
||||
// Use an actual Stack so we can write out deeply recursive structures without overflowing.
|
||||
var stack = new Stack<StackEntry>();
|
||||
stack.Push(new StackEntry(this, leading, trailing));
|
||||
|
||||
// Separated out stack processing logic so that it does not unintentionally refer to
|
||||
// "this", "leading" or "trailing.
|
||||
ProcessStack(writer, stack);
|
||||
}
|
||||
|
||||
protected virtual void WriteTriviaTo(TextWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected virtual void WriteTokenTo(TextWriter writer, bool leading, bool trailing)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Tokens
|
||||
|
||||
public virtual object GetValue()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual string GetValueText()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public virtual GreenNode GetLeadingTrivia()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual GreenNode GetTrailingTrivia()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual GreenNode WithLeadingTrivia(GreenNode trivia)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public virtual GreenNode WithTrailingTrivia(GreenNode trivia)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public InternalSyntax.SyntaxToken GetFirstToken()
|
||||
{
|
||||
return (InternalSyntax.SyntaxToken)GetFirstTerminal();
|
||||
}
|
||||
|
||||
public InternalSyntax.SyntaxToken GetLastToken()
|
||||
{
|
||||
return (InternalSyntax.SyntaxToken)GetLastTerminal();
|
||||
}
|
||||
|
||||
internal GreenNode GetFirstTerminal()
|
||||
{
|
||||
var node = this;
|
||||
|
||||
do
|
||||
{
|
||||
GreenNode firstChild = null;
|
||||
for (int i = 0, n = node.SlotCount; i < n; i++)
|
||||
{
|
||||
var child = node.GetSlot(i);
|
||||
if (child != null)
|
||||
{
|
||||
firstChild = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
node = firstChild;
|
||||
} while (node?._slotCount > 0);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
internal GreenNode GetLastTerminal()
|
||||
{
|
||||
var node = this;
|
||||
|
||||
do
|
||||
{
|
||||
GreenNode lastChild = null;
|
||||
for (var i = node.SlotCount - 1; i >= 0; i--)
|
||||
{
|
||||
var child = node.GetSlot(i);
|
||||
if (child != null)
|
||||
{
|
||||
lastChild = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
node = lastChild;
|
||||
} while (node?._slotCount > 0);
|
||||
|
||||
return node;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Factories
|
||||
public virtual GreenNode CreateList(IEnumerable<GreenNode> nodes, bool alwaysCreateListNode = false)
|
||||
{
|
||||
if (nodes == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var list = nodes.ToArray();
|
||||
|
||||
switch (list.Length)
|
||||
{
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
if (alwaysCreateListNode)
|
||||
{
|
||||
goto default;
|
||||
}
|
||||
else
|
||||
{
|
||||
return list[0];
|
||||
}
|
||||
case 2:
|
||||
return InternalSyntax.SyntaxList.List(list[0], list[1]);
|
||||
case 3:
|
||||
return InternalSyntax.SyntaxList.List(list[0], list[1], list[2]);
|
||||
default:
|
||||
return InternalSyntax.SyntaxList.List(list);
|
||||
}
|
||||
}
|
||||
|
||||
public SyntaxNode CreateRed()
|
||||
{
|
||||
return CreateRed(null, 0);
|
||||
}
|
||||
|
||||
internal abstract SyntaxNode CreateRed(SyntaxNode parent, int position);
|
||||
#endregion
|
||||
|
||||
internal virtual GreenNode Accept(InternalSyntax.SyntaxVisitor visitor)
|
||||
{
|
||||
return visitor.Visit(this);
|
||||
}
|
||||
|
||||
#region StaticMethods
|
||||
|
||||
private static void ProcessStack(TextWriter writer,
|
||||
Stack<StackEntry> stack)
|
||||
{
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
var current = stack.Pop();
|
||||
var currentNode = current.Node;
|
||||
var currentLeading = current.Leading;
|
||||
var currentTrailing = current.Trailing;
|
||||
|
||||
if (currentNode.IsToken)
|
||||
{
|
||||
currentNode.WriteTokenTo(writer, currentLeading, currentTrailing);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentNode.IsTrivia)
|
||||
{
|
||||
currentNode.WriteTriviaTo(writer);
|
||||
continue;
|
||||
}
|
||||
|
||||
var firstIndex = GetFirstNonNullChildIndex(currentNode);
|
||||
var lastIndex = GetLastNonNullChildIndex(currentNode);
|
||||
|
||||
for (var i = lastIndex; i >= firstIndex; i--)
|
||||
{
|
||||
var child = currentNode.GetSlot(i);
|
||||
if (child != null)
|
||||
{
|
||||
var first = i == firstIndex;
|
||||
var last = i == lastIndex;
|
||||
stack.Push(new StackEntry(child, currentLeading | !first, currentTrailing | !last));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetFirstNonNullChildIndex(GreenNode node)
|
||||
{
|
||||
int n = node.SlotCount;
|
||||
int firstIndex = 0;
|
||||
for (; firstIndex < n; firstIndex++)
|
||||
{
|
||||
var child = node.GetSlot(firstIndex);
|
||||
if (child != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return firstIndex;
|
||||
}
|
||||
|
||||
private static int GetLastNonNullChildIndex(GreenNode node)
|
||||
{
|
||||
int n = node.SlotCount;
|
||||
int lastIndex = n - 1;
|
||||
for (; lastIndex >= 0; lastIndex--)
|
||||
{
|
||||
var child = node.GetSlot(lastIndex);
|
||||
if (child != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return lastIndex;
|
||||
}
|
||||
|
||||
private struct StackEntry
|
||||
{
|
||||
public StackEntry(GreenNode node, bool leading, bool trailing)
|
||||
{
|
||||
Node = node;
|
||||
Leading = leading;
|
||||
Trailing = trailing;
|
||||
}
|
||||
|
||||
public GreenNode Node { get; }
|
||||
|
||||
public bool Leading { get; }
|
||||
|
||||
public bool Trailing { get; }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal abstract class HtmlNodeSyntax : SyntaxNode
|
||||
{
|
||||
internal HtmlNodeSyntax(GreenNode green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
internal new InternalSyntax.HtmlNodeSyntax Green => (InternalSyntax.HtmlNodeSyntax)base.Green;
|
||||
|
||||
internal override SyntaxNode Accept(SyntaxVisitor visitor)
|
||||
{
|
||||
return visitor.VisitHtmlNode(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal class HtmlTextSyntax : HtmlNodeSyntax
|
||||
{
|
||||
private SyntaxNode _textTokens;
|
||||
|
||||
internal HtmlTextSyntax(GreenNode green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
public SyntaxList<SyntaxNode> TextTokens => new SyntaxList<SyntaxNode>(GetRed(ref _textTokens, 0));
|
||||
|
||||
public string Value => TextTokens[0]?.ToFullString() ?? string.Empty;
|
||||
|
||||
internal override SyntaxNode Accept(SyntaxVisitor visitor)
|
||||
{
|
||||
return visitor.VisitHtmlText(this);
|
||||
}
|
||||
|
||||
internal override SyntaxNode GetCachedSlot(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return _textTokens;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal override SyntaxNode GetNodeSlot(int slot)
|
||||
{
|
||||
switch (slot)
|
||||
{
|
||||
case 0: return GetRed(ref _textTokens, 0);
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal class HtmlTextTokenSyntax : SyntaxToken
|
||||
{
|
||||
internal HtmlTextTokenSyntax(GreenNode green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
internal new InternalSyntax.HtmlTextTokenSyntax Green => (InternalSyntax.HtmlTextTokenSyntax)base.Green;
|
||||
|
||||
public string Value => Text;
|
||||
|
||||
internal override SyntaxToken WithLeadingTriviaCore(SyntaxNode trivia)
|
||||
{
|
||||
return new InternalSyntax.HtmlTextTokenSyntax(Text, trivia?.Green, GetTrailingTrivia().Node?.Green).CreateRed(Parent, Position) as HtmlTextTokenSyntax;
|
||||
}
|
||||
|
||||
internal override SyntaxToken WithTrailingTriviaCore(SyntaxNode trivia)
|
||||
{
|
||||
return new InternalSyntax.HtmlTextTokenSyntax(Text, GetLeadingTrivia().Node?.Green, trivia?.Green).CreateRed(Parent, Position) as HtmlTextTokenSyntax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal abstract class HtmlNodeSyntax : GreenNode
|
||||
{
|
||||
protected HtmlNodeSyntax(SyntaxKind kind)
|
||||
: base(kind)
|
||||
{
|
||||
}
|
||||
|
||||
protected HtmlNodeSyntax(SyntaxKind kind, int fullWidth)
|
||||
: base(kind, fullWidth)
|
||||
{
|
||||
}
|
||||
|
||||
protected HtmlNodeSyntax(SyntaxKind kind, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
: base(kind, diagnostics, annotations)
|
||||
{
|
||||
}
|
||||
|
||||
internal override GreenNode Accept(SyntaxVisitor visitor)
|
||||
{
|
||||
return visitor.VisitHtmlNode(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal class HtmlTextSyntax : HtmlNodeSyntax
|
||||
{
|
||||
private readonly GreenNode _value;
|
||||
|
||||
internal HtmlTextSyntax(GreenNode value) : base(SyntaxKind.HtmlText)
|
||||
{
|
||||
SlotCount = 1;
|
||||
_value = value;
|
||||
AdjustFlagsAndWidth(value);
|
||||
}
|
||||
|
||||
internal HtmlTextSyntax(GreenNode value, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
: base(SyntaxKind.HtmlText, diagnostics, annotations)
|
||||
{
|
||||
SlotCount = 1;
|
||||
_value = value;
|
||||
AdjustFlagsAndWidth(value);
|
||||
}
|
||||
|
||||
internal SyntaxList<GreenNode> TextTokens => new SyntaxList<GreenNode>(_value);
|
||||
|
||||
internal override GreenNode GetSlot(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return _value;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
internal override GreenNode Accept(SyntaxVisitor visitor)
|
||||
{
|
||||
return visitor.VisitHtmlText(this);
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode parent, int position)
|
||||
{
|
||||
return new Syntax.HtmlTextSyntax(this, parent, position);
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new HtmlTextSyntax(_value, diagnostics, GetAnnotations());
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new HtmlTextSyntax(_value, GetDiagnostics(), annotations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal class HtmlTextTokenSyntax : SyntaxToken
|
||||
{
|
||||
internal HtmlTextTokenSyntax(string text, params RazorDiagnostic[] diagnostics)
|
||||
: base(SyntaxKind.HtmlTextLiteralToken, text, null, null, diagnostics, null)
|
||||
{
|
||||
}
|
||||
|
||||
internal HtmlTextTokenSyntax(string text, GreenNode leadingTrivia, GreenNode trailingTrivia)
|
||||
: base(SyntaxKind.HtmlTextLiteralToken, text, leadingTrivia, trailingTrivia)
|
||||
{
|
||||
}
|
||||
|
||||
protected HtmlTextTokenSyntax(SyntaxKind kind, string name, GreenNode leadingTrivia, GreenNode trailingTrivia)
|
||||
: base(kind, name, leadingTrivia, trailingTrivia)
|
||||
{
|
||||
}
|
||||
|
||||
protected HtmlTextTokenSyntax(SyntaxKind kind, string name, GreenNode leadingTrivia, GreenNode trailingTrivia, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
: base(kind, name, leadingTrivia, trailingTrivia, diagnostics, annotations)
|
||||
{
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode parent, int position)
|
||||
{
|
||||
return new Syntax.HtmlTextTokenSyntax(this, parent, position);
|
||||
}
|
||||
|
||||
public override SyntaxToken TokenWithLeadingTrivia(GreenNode trivia)
|
||||
{
|
||||
return new HtmlTextTokenSyntax(Kind, Text, trivia, TrailingTrivia);
|
||||
}
|
||||
|
||||
public override SyntaxToken TokenWithTrailingTrivia(GreenNode trivia)
|
||||
{
|
||||
return new HtmlTextTokenSyntax(Kind, Text, LeadingTrivia, trivia);
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new HtmlTextTokenSyntax(Kind, Text, LeadingTrivia, TrailingTrivia, diagnostics, GetAnnotations());
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new HtmlTextTokenSyntax(Kind, Text, LeadingTrivia, TrailingTrivia, GetDiagnostics(), annotations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal class NewLineTokenSyntax : SyntaxToken
|
||||
{
|
||||
internal NewLineTokenSyntax(string text, params RazorDiagnostic[] diagnostics)
|
||||
: base(SyntaxKind.NewLine, text, null, null, diagnostics, null)
|
||||
{
|
||||
}
|
||||
|
||||
internal NewLineTokenSyntax(string text, GreenNode leadingTrivia, GreenNode trailingTrivia)
|
||||
: base(SyntaxKind.NewLine, text, leadingTrivia, trailingTrivia)
|
||||
{
|
||||
}
|
||||
|
||||
protected NewLineTokenSyntax(SyntaxKind kind, string name, GreenNode leadingTrivia, GreenNode trailingTrivia)
|
||||
: base(kind, name, leadingTrivia, trailingTrivia)
|
||||
{
|
||||
}
|
||||
|
||||
protected NewLineTokenSyntax(SyntaxKind kind, string name, GreenNode leadingTrivia, GreenNode trailingTrivia, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
: base(kind, name, leadingTrivia, trailingTrivia, diagnostics, annotations)
|
||||
{
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode parent, int position) => new Syntax.NewLineTokenSyntax(this, parent, position);
|
||||
|
||||
public override SyntaxToken TokenWithLeadingTrivia(GreenNode trivia)
|
||||
{
|
||||
return new NewLineTokenSyntax(Kind, Text, trivia, TrailingTrivia);
|
||||
}
|
||||
|
||||
public override SyntaxToken TokenWithTrailingTrivia(GreenNode trivia)
|
||||
{
|
||||
return new NewLineTokenSyntax(Kind, Text, LeadingTrivia, trivia);
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new NewLineTokenSyntax(Kind, Text, LeadingTrivia, TrailingTrivia, diagnostics, GetAnnotations());
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new NewLineTokenSyntax(Kind, Text, LeadingTrivia, TrailingTrivia, GetDiagnostics(), annotations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal class PunctuationSyntax : SyntaxToken
|
||||
{
|
||||
internal PunctuationSyntax(SyntaxKind kind, string name, RazorDiagnostic[] diagnostics)
|
||||
: this(kind, name, null, null, diagnostics, null)
|
||||
{
|
||||
}
|
||||
|
||||
internal PunctuationSyntax(SyntaxKind kind, string name, GreenNode leadingTrivia, GreenNode trailingTrivia)
|
||||
: this(kind, name, leadingTrivia, trailingTrivia, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
internal PunctuationSyntax(SyntaxKind kind, string name, GreenNode leadingTrivia, GreenNode trailingTrivia, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
: base(kind, name, leadingTrivia, trailingTrivia, diagnostics, annotations)
|
||||
{
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode parent, int position) => new Syntax.PunctuationSyntax(this, parent, position);
|
||||
|
||||
public override SyntaxToken TokenWithLeadingTrivia(GreenNode trivia)
|
||||
{
|
||||
return new PunctuationSyntax(Kind, Text, trivia, TrailingTrivia);
|
||||
}
|
||||
|
||||
public override SyntaxToken TokenWithTrailingTrivia(GreenNode trivia)
|
||||
{
|
||||
return new PunctuationSyntax(Kind, Text, LeadingTrivia, trivia);
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new PunctuationSyntax(Kind, Text, LeadingTrivia, TrailingTrivia, diagnostics, GetAnnotations());
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new PunctuationSyntax(Kind, Text, LeadingTrivia, TrailingTrivia, GetDiagnostics(), annotations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal static class SyntaxFactory
|
||||
{
|
||||
internal static HtmlTextSyntax HtmlText(SyntaxList<SyntaxToken> textTokens)
|
||||
{
|
||||
return new HtmlTextSyntax(textTokens.Node);
|
||||
}
|
||||
|
||||
internal static HtmlTextTokenSyntax HtmlTextToken(string text, params RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new HtmlTextTokenSyntax(text, diagnostics);
|
||||
}
|
||||
|
||||
internal static WhitespaceTokenSyntax WhitespaceToken(string text, params RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new WhitespaceTokenSyntax(text, diagnostics);
|
||||
}
|
||||
|
||||
internal static NewLineTokenSyntax NewLineToken(string text, params RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new NewLineTokenSyntax(text, diagnostics);
|
||||
}
|
||||
|
||||
internal static PunctuationSyntax Punctuation(SyntaxKind syntaxKind, string text, params RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new PunctuationSyntax(syntaxKind, text, diagnostics);
|
||||
}
|
||||
|
||||
internal static UnknownTokenSyntax UnknownToken(string text, params RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new UnknownTokenSyntax(text, diagnostics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,418 @@
|
|||
// 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;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal abstract class SyntaxList : GreenNode
|
||||
{
|
||||
internal SyntaxList()
|
||||
: base(SyntaxKind.List)
|
||||
{
|
||||
}
|
||||
|
||||
internal SyntaxList(RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
: base(SyntaxKind.List, diagnostics, annotations)
|
||||
{
|
||||
}
|
||||
|
||||
internal override bool IsList => true;
|
||||
|
||||
internal static GreenNode List(GreenNode child)
|
||||
{
|
||||
return child;
|
||||
}
|
||||
|
||||
internal static WithTwoChildren List(GreenNode child0, GreenNode child1)
|
||||
{
|
||||
Debug.Assert(child0 != null);
|
||||
Debug.Assert(child1 != null);
|
||||
|
||||
var result = new WithTwoChildren(child0, child1);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static WithThreeChildren List(GreenNode child0, GreenNode child1, GreenNode child2)
|
||||
{
|
||||
Debug.Assert(child0 != null);
|
||||
Debug.Assert(child1 != null);
|
||||
Debug.Assert(child2 != null);
|
||||
|
||||
var result = new WithThreeChildren(child0, child1, child2);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static GreenNode List(GreenNode[] nodes)
|
||||
{
|
||||
return List(nodes, nodes.Length);
|
||||
}
|
||||
|
||||
internal static GreenNode List(GreenNode[] nodes, int count)
|
||||
{
|
||||
var array = new ArrayElement<GreenNode>[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Debug.Assert(nodes[i] != null);
|
||||
array[i].Value = nodes[i];
|
||||
}
|
||||
|
||||
return List(array);
|
||||
}
|
||||
|
||||
internal static SyntaxList List(ArrayElement<GreenNode>[] children)
|
||||
{
|
||||
// "WithLotsOfChildren" list will allocate a separate array to hold
|
||||
// precomputed node offsets. It may not be worth it for smallish lists.
|
||||
if (children.Length < 10)
|
||||
{
|
||||
return new WithManyChildren(children);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new WithLotsOfChildren(children);
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract void CopyTo(ArrayElement<GreenNode>[] array, int offset);
|
||||
|
||||
internal static GreenNode Concat(GreenNode left, GreenNode right)
|
||||
{
|
||||
if (left == null)
|
||||
{
|
||||
return right;
|
||||
}
|
||||
|
||||
if (right == null)
|
||||
{
|
||||
return left;
|
||||
}
|
||||
|
||||
var leftList = left as SyntaxList;
|
||||
var rightList = right as SyntaxList;
|
||||
if (leftList != null)
|
||||
{
|
||||
if (rightList != null)
|
||||
{
|
||||
var tmp = new ArrayElement<GreenNode>[left.SlotCount + right.SlotCount];
|
||||
leftList.CopyTo(tmp, 0);
|
||||
rightList.CopyTo(tmp, left.SlotCount);
|
||||
return List(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
var tmp = new ArrayElement<GreenNode>[left.SlotCount + 1];
|
||||
leftList.CopyTo(tmp, 0);
|
||||
tmp[left.SlotCount].Value = right;
|
||||
return List(tmp);
|
||||
}
|
||||
}
|
||||
else if (rightList != null)
|
||||
{
|
||||
var tmp = new ArrayElement<GreenNode>[rightList.SlotCount + 1];
|
||||
tmp[0].Value = left;
|
||||
rightList.CopyTo(tmp, 1);
|
||||
return List(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
return List(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
internal class WithTwoChildren : SyntaxList
|
||||
{
|
||||
private readonly GreenNode _child0;
|
||||
private readonly GreenNode _child1;
|
||||
|
||||
internal WithTwoChildren(GreenNode child0, GreenNode child1)
|
||||
{
|
||||
SlotCount = 2;
|
||||
AdjustFlagsAndWidth(child0);
|
||||
_child0 = child0;
|
||||
AdjustFlagsAndWidth(child1);
|
||||
_child1 = child1;
|
||||
}
|
||||
|
||||
internal WithTwoChildren(RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations, GreenNode child0, GreenNode child1)
|
||||
{
|
||||
SlotCount = 2;
|
||||
AdjustFlagsAndWidth(child0);
|
||||
_child0 = child0;
|
||||
AdjustFlagsAndWidth(child1);
|
||||
_child1 = child1;
|
||||
}
|
||||
|
||||
internal override GreenNode GetSlot(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return _child0;
|
||||
case 1:
|
||||
return _child1;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void CopyTo(ArrayElement<GreenNode>[] array, int offset)
|
||||
{
|
||||
array[offset].Value = _child0;
|
||||
array[offset + 1].Value = _child1;
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode parent, int position)
|
||||
{
|
||||
return new Syntax.SyntaxList.WithTwoChildren(this, parent, position);
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] errors)
|
||||
{
|
||||
return new WithTwoChildren(errors, this.GetAnnotations(), _child0, _child1);
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new WithTwoChildren(GetDiagnostics(), annotations, _child0, _child1);
|
||||
}
|
||||
}
|
||||
|
||||
internal class WithThreeChildren : SyntaxList
|
||||
{
|
||||
private readonly GreenNode _child0;
|
||||
private readonly GreenNode _child1;
|
||||
private readonly GreenNode _child2;
|
||||
|
||||
internal WithThreeChildren(GreenNode child0, GreenNode child1, GreenNode child2)
|
||||
{
|
||||
SlotCount = 3;
|
||||
AdjustFlagsAndWidth(child0);
|
||||
_child0 = child0;
|
||||
AdjustFlagsAndWidth(child1);
|
||||
_child1 = child1;
|
||||
AdjustFlagsAndWidth(child2);
|
||||
_child2 = child2;
|
||||
}
|
||||
|
||||
internal WithThreeChildren(RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations, GreenNode child0, GreenNode child1, GreenNode child2)
|
||||
: base(diagnostics, annotations)
|
||||
{
|
||||
SlotCount = 3;
|
||||
AdjustFlagsAndWidth(child0);
|
||||
_child0 = child0;
|
||||
AdjustFlagsAndWidth(child1);
|
||||
_child1 = child1;
|
||||
AdjustFlagsAndWidth(child2);
|
||||
_child2 = child2;
|
||||
}
|
||||
|
||||
internal override GreenNode GetSlot(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return _child0;
|
||||
case 1:
|
||||
return _child1;
|
||||
case 2:
|
||||
return _child2;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void CopyTo(ArrayElement<GreenNode>[] array, int offset)
|
||||
{
|
||||
array[offset].Value = _child0;
|
||||
array[offset + 1].Value = _child1;
|
||||
array[offset + 2].Value = _child2;
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode parent, int position)
|
||||
{
|
||||
return new Syntax.SyntaxList.WithThreeChildren(this, parent, position);
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] errors)
|
||||
{
|
||||
return new WithThreeChildren(errors, GetAnnotations(), _child0, _child1, _child2);
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new WithThreeChildren(GetDiagnostics(), annotations, _child0, _child1, _child2);
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class WithManyChildrenBase : SyntaxList
|
||||
{
|
||||
internal readonly ArrayElement<GreenNode>[] children;
|
||||
|
||||
internal WithManyChildrenBase(ArrayElement<GreenNode>[] children)
|
||||
{
|
||||
this.children = children;
|
||||
this.InitializeChildren();
|
||||
}
|
||||
|
||||
internal WithManyChildrenBase(RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations, ArrayElement<GreenNode>[] children)
|
||||
: base(diagnostics, annotations)
|
||||
{
|
||||
this.children = children;
|
||||
this.InitializeChildren();
|
||||
}
|
||||
|
||||
private void InitializeChildren()
|
||||
{
|
||||
var n = children.Length;
|
||||
if (n < byte.MaxValue)
|
||||
{
|
||||
SlotCount = (byte)n;
|
||||
}
|
||||
else
|
||||
{
|
||||
SlotCount = byte.MaxValue;
|
||||
}
|
||||
|
||||
for (var i = 0; i < children.Length; i++)
|
||||
{
|
||||
AdjustFlagsAndWidth(children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
protected override int GetSlotCount()
|
||||
{
|
||||
return children.Length;
|
||||
}
|
||||
|
||||
internal override GreenNode GetSlot(int index)
|
||||
{
|
||||
return children[index];
|
||||
}
|
||||
|
||||
internal override void CopyTo(ArrayElement<GreenNode>[] array, int offset)
|
||||
{
|
||||
Array.Copy(children, 0, array, offset, children.Length);
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode parent, int position)
|
||||
{
|
||||
return new Syntax.SyntaxList.WithManyChildren(this, parent, position);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class WithManyChildren : WithManyChildrenBase
|
||||
{
|
||||
internal WithManyChildren(ArrayElement<GreenNode>[] children)
|
||||
: base(children)
|
||||
{
|
||||
}
|
||||
|
||||
internal WithManyChildren(RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations, ArrayElement<GreenNode>[] children)
|
||||
: base(diagnostics, annotations, children)
|
||||
{
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] errors)
|
||||
{
|
||||
return new WithManyChildren(errors, GetAnnotations(), children);
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new WithManyChildren(GetDiagnostics(), annotations, children);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class WithLotsOfChildren : WithManyChildrenBase
|
||||
{
|
||||
private readonly int[] _childOffsets;
|
||||
|
||||
internal WithLotsOfChildren(ArrayElement<GreenNode>[] children)
|
||||
: base(children)
|
||||
{
|
||||
_childOffsets = CalculateOffsets(children);
|
||||
}
|
||||
|
||||
internal WithLotsOfChildren(RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations, ArrayElement<GreenNode>[] children, int[] childOffsets)
|
||||
: base(diagnostics, annotations, children)
|
||||
{
|
||||
_childOffsets = childOffsets;
|
||||
}
|
||||
|
||||
public override int GetSlotOffset(int index)
|
||||
{
|
||||
return _childOffsets[index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the slot that contains the given offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The target offset. Must be between 0 and <see cref="GreenNode.FullWidth"/>.</param>
|
||||
/// <returns>The slot index of the slot containing the given offset.</returns>
|
||||
/// <remarks>
|
||||
/// This implementation uses a binary search to find the first slot that contains
|
||||
/// the given offset.
|
||||
/// </remarks>
|
||||
public override int FindSlotIndexContainingOffset(int offset)
|
||||
{
|
||||
Debug.Assert(offset >= 0 && offset < FullWidth);
|
||||
return BinarySearchUpperBound(_childOffsets, offset) - 1;
|
||||
}
|
||||
|
||||
private static int[] CalculateOffsets(ArrayElement<GreenNode>[] children)
|
||||
{
|
||||
var n = children.Length;
|
||||
var childOffsets = new int[n];
|
||||
var offset = 0;
|
||||
for (var i = 0; i < n; i++)
|
||||
{
|
||||
childOffsets[i] = offset;
|
||||
offset += children[i].Value.FullWidth;
|
||||
}
|
||||
return childOffsets;
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] errors)
|
||||
{
|
||||
return new WithLotsOfChildren(errors, this.GetAnnotations(), children, _childOffsets);
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new WithLotsOfChildren(GetDiagnostics(), annotations, children, _childOffsets);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Search a sorted integer array for the target value in O(log N) time.
|
||||
/// </summary>
|
||||
/// <param name="array">The array of integers which must be sorted in ascending order.</param>
|
||||
/// <param name="value">The target value.</param>
|
||||
/// <returns>An index in the array pointing to the position where <paramref name="value"/> should be
|
||||
/// inserted in order to maintain the sorted order. All values to the right of this position will be
|
||||
/// strictly greater than <paramref name="value"/>. Note that this may return a position off the end
|
||||
/// of the array if all elements are less than or equal to <paramref name="value"/>.</returns>
|
||||
private static int BinarySearchUpperBound(int[] array, int value)
|
||||
{
|
||||
var low = 0;
|
||||
var high = array.Length - 1;
|
||||
|
||||
while (low <= high)
|
||||
{
|
||||
var middle = low + ((high - low) >> 1);
|
||||
if (array[middle] > value)
|
||||
{
|
||||
high = middle - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
low = middle + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return low;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
// 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;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal class SyntaxListBuilder
|
||||
{
|
||||
private ArrayElement<GreenNode>[] _nodes;
|
||||
|
||||
public int Count { get; private set; }
|
||||
|
||||
public SyntaxListBuilder(int size)
|
||||
{
|
||||
_nodes = new ArrayElement<GreenNode>[size];
|
||||
}
|
||||
|
||||
public static SyntaxListBuilder Create()
|
||||
{
|
||||
return new SyntaxListBuilder(8);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
public GreenNode this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _nodes[index];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_nodes[index].Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(GreenNode item)
|
||||
{
|
||||
if (item == null) return;
|
||||
|
||||
if (item.IsList)
|
||||
{
|
||||
var slotCount = item.SlotCount;
|
||||
|
||||
// Necessary, but not sufficient (e.g. for nested lists).
|
||||
EnsureAdditionalCapacity(slotCount);
|
||||
|
||||
for (var i = 0; i < slotCount; i++)
|
||||
{
|
||||
Add(item.GetSlot(i));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EnsureAdditionalCapacity(1);
|
||||
|
||||
_nodes[Count++].Value = item;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRange(GreenNode[] items)
|
||||
{
|
||||
AddRange(items, 0, items.Length);
|
||||
}
|
||||
|
||||
public void AddRange(GreenNode[] items, int offset, int length)
|
||||
{
|
||||
// Necessary, but not sufficient (e.g. for nested lists).
|
||||
EnsureAdditionalCapacity(length - offset);
|
||||
|
||||
var oldCount = Count;
|
||||
|
||||
for (var i = offset; i < length; i++)
|
||||
{
|
||||
Add(items[i]);
|
||||
}
|
||||
|
||||
Validate(oldCount, Count);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void Validate(int start, int end)
|
||||
{
|
||||
for (var i = start; i < end; i++)
|
||||
{
|
||||
Debug.Assert(_nodes[i].Value != null);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxList<GreenNode> list)
|
||||
{
|
||||
this.AddRange(list, 0, list.Count);
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxList<GreenNode> list, int offset, int length)
|
||||
{
|
||||
// Necessary, but not sufficient (e.g. for nested lists).
|
||||
EnsureAdditionalCapacity(length - offset);
|
||||
|
||||
var oldCount = Count;
|
||||
|
||||
for (var i = offset; i < length; i++)
|
||||
{
|
||||
Add(list[i]);
|
||||
}
|
||||
|
||||
Validate(oldCount, Count);
|
||||
}
|
||||
|
||||
public void AddRange<TNode>(SyntaxList<TNode> list) where TNode : GreenNode
|
||||
{
|
||||
this.AddRange(list, 0, list.Count);
|
||||
}
|
||||
|
||||
public void AddRange<TNode>(SyntaxList<TNode> list, int offset, int length) where TNode : GreenNode
|
||||
{
|
||||
AddRange(new SyntaxList<GreenNode>(list.Node), offset, length);
|
||||
}
|
||||
|
||||
public void RemoveLast()
|
||||
{
|
||||
Count--;
|
||||
_nodes[Count].Value = null;
|
||||
}
|
||||
|
||||
private void EnsureAdditionalCapacity(int additionalCount)
|
||||
{
|
||||
var currentSize = _nodes.Length;
|
||||
var requiredSize = Count + additionalCount;
|
||||
|
||||
if (requiredSize <= currentSize) return;
|
||||
|
||||
var newSize =
|
||||
requiredSize < 8 ? 8 :
|
||||
requiredSize >= (int.MaxValue / 2) ? int.MaxValue :
|
||||
Math.Max(requiredSize, currentSize * 2); // NB: Size will *at least* double.
|
||||
Debug.Assert(newSize >= requiredSize);
|
||||
|
||||
Array.Resize(ref _nodes, newSize);
|
||||
}
|
||||
|
||||
public bool Any(SyntaxKind kind)
|
||||
{
|
||||
for (var i = 0; i < Count; i++)
|
||||
{
|
||||
if (_nodes[i].Value.Kind == kind)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public GreenNode[] ToArray()
|
||||
{
|
||||
var array = new GreenNode[Count];
|
||||
for (var i = 0; i < array.Length; i++)
|
||||
{
|
||||
array[i] = _nodes[i];
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
internal GreenNode ToListNode()
|
||||
{
|
||||
switch (Count)
|
||||
{
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
return _nodes[0];
|
||||
case 2:
|
||||
return SyntaxList.List(_nodes[0], _nodes[1]);
|
||||
case 3:
|
||||
return SyntaxList.List(_nodes[0], _nodes[1], _nodes[2]);
|
||||
default:
|
||||
var tmp = new ArrayElement<GreenNode>[Count];
|
||||
Array.Copy(_nodes, tmp, Count);
|
||||
return SyntaxList.List(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
public SyntaxList<GreenNode> ToList()
|
||||
{
|
||||
return new SyntaxList<GreenNode>(ToListNode());
|
||||
}
|
||||
|
||||
public SyntaxList<TNode> ToList<TNode>() where TNode : GreenNode
|
||||
{
|
||||
return new SyntaxList<TNode>(ToListNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal readonly struct SyntaxListBuilder<TNode> where TNode : GreenNode
|
||||
{
|
||||
private readonly SyntaxListBuilder _builder;
|
||||
|
||||
public SyntaxListBuilder(int size)
|
||||
: this(new SyntaxListBuilder(size))
|
||||
{
|
||||
}
|
||||
|
||||
public static SyntaxListBuilder<TNode> Create()
|
||||
{
|
||||
return new SyntaxListBuilder<TNode>(8);
|
||||
}
|
||||
|
||||
internal SyntaxListBuilder(SyntaxListBuilder builder)
|
||||
{
|
||||
_builder = builder;
|
||||
}
|
||||
|
||||
public bool IsNull
|
||||
{
|
||||
get
|
||||
{
|
||||
return _builder == null;
|
||||
}
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return _builder.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public TNode this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return (TNode)_builder[index];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_builder[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_builder.Clear();
|
||||
}
|
||||
|
||||
public SyntaxListBuilder<TNode> Add(TNode node)
|
||||
{
|
||||
_builder.Add(node);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void AddRange(TNode[] items, int offset, int length)
|
||||
{
|
||||
_builder.AddRange(items, offset, length);
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxList<TNode> nodes)
|
||||
{
|
||||
_builder.AddRange(nodes);
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxList<TNode> nodes, int offset, int length)
|
||||
{
|
||||
_builder.AddRange(nodes, offset, length);
|
||||
}
|
||||
|
||||
public bool Any(SyntaxKind kind)
|
||||
{
|
||||
return _builder.Any(kind);
|
||||
}
|
||||
|
||||
public SyntaxList<TNode> ToList()
|
||||
{
|
||||
return _builder.ToList<TNode>();
|
||||
}
|
||||
|
||||
public GreenNode ToListNode()
|
||||
{
|
||||
return _builder.ToListNode();
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxListBuilder(SyntaxListBuilder<TNode> builder)
|
||||
{
|
||||
return builder._builder;
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxList<TNode>(SyntaxListBuilder<TNode> builder)
|
||||
{
|
||||
if (builder._builder != null)
|
||||
{
|
||||
return builder.ToList();
|
||||
}
|
||||
|
||||
return default(SyntaxList<TNode>);
|
||||
}
|
||||
|
||||
public SyntaxList<TDerived> ToList<TDerived>() where TDerived : GreenNode
|
||||
{
|
||||
return new SyntaxList<TDerived>(ToListNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
// 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.Diagnostics;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal readonly struct SyntaxList<TNode>
|
||||
where TNode : GreenNode
|
||||
{
|
||||
private readonly GreenNode _node;
|
||||
|
||||
public SyntaxList(GreenNode node)
|
||||
{
|
||||
_node = node;
|
||||
}
|
||||
|
||||
public GreenNode Node
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((GreenNode)_node);
|
||||
}
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_node == null) ? 0 : _node.IsList ? _node.SlotCount : 1;
|
||||
}
|
||||
}
|
||||
|
||||
public TNode Last
|
||||
{
|
||||
get
|
||||
{
|
||||
var node = _node;
|
||||
if (node.IsList)
|
||||
{
|
||||
return ((TNode)node.GetSlot(node.SlotCount - 1));
|
||||
}
|
||||
|
||||
return ((TNode)node);
|
||||
}
|
||||
}
|
||||
|
||||
/* Not Implemented: Default */
|
||||
public TNode this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
var node = _node;
|
||||
if (node.IsList)
|
||||
{
|
||||
return ((TNode)node.GetSlot(index));
|
||||
}
|
||||
|
||||
Debug.Assert(index == 0);
|
||||
return ((TNode)node);
|
||||
}
|
||||
}
|
||||
|
||||
public GreenNode ItemUntyped(int index)
|
||||
{
|
||||
var node = _node;
|
||||
if (node.IsList)
|
||||
{
|
||||
return node.GetSlot(index);
|
||||
}
|
||||
|
||||
Debug.Assert(index == 0);
|
||||
return node;
|
||||
}
|
||||
|
||||
public bool Any()
|
||||
{
|
||||
return _node != null;
|
||||
}
|
||||
|
||||
public bool Any(SyntaxKind kind)
|
||||
{
|
||||
for (var i = 0; i < Count; i++)
|
||||
{
|
||||
var element = ItemUntyped(i);
|
||||
if ((element.Kind == kind))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public TNode[] Nodes
|
||||
{
|
||||
get
|
||||
{
|
||||
var arr = new TNode[Count];
|
||||
for (var i = 0; i < Count; i++)
|
||||
{
|
||||
arr[i] = this[i];
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool operator ==(SyntaxList<TNode> left, SyntaxList<TNode> right)
|
||||
{
|
||||
return (left._node == right._node);
|
||||
}
|
||||
|
||||
public static bool operator !=(SyntaxList<TNode> left, SyntaxList<TNode> right)
|
||||
{
|
||||
return !(left._node == right._node);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return (obj is SyntaxList<TNode> && (_node == ((SyntaxList<TNode>)obj)._node));
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _node != null ? _node.GetHashCode() : 0;
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxList<TNode>(TNode node)
|
||||
{
|
||||
return new SyntaxList<TNode>(node);
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxList<GreenNode>(SyntaxList<TNode> nodes)
|
||||
{
|
||||
return new SyntaxList<GreenNode>(nodes._node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal abstract class SyntaxToken : GreenNode
|
||||
{
|
||||
internal SyntaxToken(SyntaxKind tokenKind, string text, GreenNode leadingTrivia, GreenNode trailingTrivia)
|
||||
: base(tokenKind, text.Length)
|
||||
{
|
||||
Text = text;
|
||||
LeadingTrivia = leadingTrivia;
|
||||
AdjustFlagsAndWidth(leadingTrivia);
|
||||
TrailingTrivia = trailingTrivia;
|
||||
AdjustFlagsAndWidth(trailingTrivia);
|
||||
}
|
||||
|
||||
internal SyntaxToken(SyntaxKind tokenKind, string text, GreenNode leadingTrivia, GreenNode trailingTrivia, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
: base(tokenKind, text.Length, diagnostics, annotations)
|
||||
{
|
||||
Text = text;
|
||||
LeadingTrivia = leadingTrivia;
|
||||
AdjustFlagsAndWidth(leadingTrivia);
|
||||
TrailingTrivia = trailingTrivia;
|
||||
AdjustFlagsAndWidth(trailingTrivia);
|
||||
}
|
||||
|
||||
public string Text { get; }
|
||||
|
||||
public GreenNode LeadingTrivia { get; }
|
||||
|
||||
public GreenNode TrailingTrivia { get; }
|
||||
|
||||
internal override bool IsToken => true;
|
||||
|
||||
public override int Width => Text.Length;
|
||||
|
||||
protected override void WriteTokenTo(TextWriter writer, bool leading, bool trailing)
|
||||
{
|
||||
if (leading)
|
||||
{
|
||||
var trivia = GetLeadingTrivia();
|
||||
if (trivia != null)
|
||||
{
|
||||
trivia.WriteTo(writer, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
writer.Write(Text);
|
||||
|
||||
if (trailing)
|
||||
{
|
||||
var trivia = GetTrailingTrivia();
|
||||
if (trivia != null)
|
||||
{
|
||||
trivia.WriteTo(writer, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override sealed GreenNode GetLeadingTrivia()
|
||||
{
|
||||
return LeadingTrivia;
|
||||
}
|
||||
|
||||
public override int GetLeadingTriviaWidth()
|
||||
{
|
||||
return LeadingTrivia == null ? 0 : LeadingTrivia.FullWidth;
|
||||
}
|
||||
|
||||
public override sealed GreenNode GetTrailingTrivia()
|
||||
{
|
||||
return TrailingTrivia;
|
||||
}
|
||||
|
||||
public override int GetTrailingTriviaWidth()
|
||||
{
|
||||
return TrailingTrivia == null ? 0 : TrailingTrivia.FullWidth;
|
||||
}
|
||||
|
||||
public sealed override GreenNode WithLeadingTrivia(GreenNode trivia)
|
||||
{
|
||||
return TokenWithLeadingTrivia(trivia);
|
||||
}
|
||||
|
||||
public abstract SyntaxToken TokenWithLeadingTrivia(GreenNode trivia);
|
||||
|
||||
public sealed override GreenNode WithTrailingTrivia(GreenNode trivia)
|
||||
{
|
||||
return TokenWithTrailingTrivia(trivia);
|
||||
}
|
||||
|
||||
public abstract SyntaxToken TokenWithTrailingTrivia(GreenNode trivia);
|
||||
|
||||
protected override sealed int GetSlotCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal override sealed GreenNode GetSlot(int index)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
internal override GreenNode Accept(SyntaxVisitor visitor)
|
||||
{
|
||||
return visitor.VisitSyntaxToken(this);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal class SyntaxTrivia : GreenNode
|
||||
{
|
||||
internal SyntaxTrivia(SyntaxKind kind, string text)
|
||||
: base(kind, text.Length)
|
||||
{
|
||||
Text = text;
|
||||
}
|
||||
|
||||
internal SyntaxTrivia(SyntaxKind kind, string text, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
: base(kind, text.Length, diagnostics, annotations)
|
||||
{
|
||||
Text = text;
|
||||
}
|
||||
|
||||
public string Text { get; }
|
||||
|
||||
internal override bool IsTrivia => true;
|
||||
|
||||
public override int Width => Text.Length;
|
||||
|
||||
protected override void WriteTriviaTo(TextWriter writer)
|
||||
{
|
||||
writer.Write(Text);
|
||||
}
|
||||
|
||||
public sealed override string ToFullString()
|
||||
{
|
||||
return Text;
|
||||
}
|
||||
|
||||
public sealed override int GetLeadingTriviaWidth()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public sealed override int GetTrailingTriviaWidth()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected override sealed int GetSlotCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal override sealed GreenNode GetSlot(int index)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode parent, int position)
|
||||
{
|
||||
return new Syntax.SyntaxTrivia(this, parent, position);
|
||||
}
|
||||
|
||||
internal override GreenNode Accept(SyntaxVisitor visitor)
|
||||
{
|
||||
return visitor.VisitSyntaxTrivia(this);
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new SyntaxTrivia(Kind, Text, diagnostics, GetAnnotations());
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new SyntaxTrivia(Kind, Text, GetDiagnostics(), annotations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal abstract class SyntaxVisitor
|
||||
{
|
||||
public virtual GreenNode Visit(GreenNode node)
|
||||
{
|
||||
if (node != null)
|
||||
{
|
||||
return node.Accept(this);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual GreenNode VisitSyntaxNode(GreenNode node)
|
||||
{
|
||||
return node;
|
||||
}
|
||||
|
||||
public virtual GreenNode VisitHtmlNode(HtmlNodeSyntax node)
|
||||
{
|
||||
return VisitSyntaxNode(node);
|
||||
}
|
||||
|
||||
public virtual GreenNode VisitHtmlText(HtmlTextSyntax node)
|
||||
{
|
||||
return VisitHtmlNode(node);
|
||||
}
|
||||
|
||||
public virtual SyntaxToken VisitSyntaxToken(SyntaxToken token)
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
public virtual SyntaxTrivia VisitSyntaxTrivia(SyntaxTrivia trivia)
|
||||
{
|
||||
return trivia;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal class UnknownTokenSyntax : SyntaxToken
|
||||
{
|
||||
internal UnknownTokenSyntax(string text, params RazorDiagnostic[] diagnostics)
|
||||
: base(SyntaxKind.Unknown, text, null, null, diagnostics, null)
|
||||
{
|
||||
}
|
||||
|
||||
internal UnknownTokenSyntax(string text, GreenNode leadingTrivia, GreenNode trailingTrivia)
|
||||
: base(SyntaxKind.Unknown, text, leadingTrivia, trailingTrivia)
|
||||
{
|
||||
}
|
||||
|
||||
protected UnknownTokenSyntax(SyntaxKind kind, string name, GreenNode leadingTrivia, GreenNode trailingTrivia)
|
||||
: base(kind, name, leadingTrivia, trailingTrivia)
|
||||
{
|
||||
}
|
||||
|
||||
protected UnknownTokenSyntax(SyntaxKind kind, string name, GreenNode leadingTrivia, GreenNode trailingTrivia, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
: base(kind, name, leadingTrivia, trailingTrivia, diagnostics, annotations)
|
||||
{
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode parent, int position) => new Syntax.UnknownTokenSyntax(this, parent, position);
|
||||
|
||||
public override SyntaxToken TokenWithLeadingTrivia(GreenNode trivia)
|
||||
{
|
||||
return new UnknownTokenSyntax(Kind, Text, trivia, TrailingTrivia);
|
||||
}
|
||||
|
||||
public override SyntaxToken TokenWithTrailingTrivia(GreenNode trivia)
|
||||
{
|
||||
return new UnknownTokenSyntax(Kind, Text, LeadingTrivia, trivia);
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new UnknownTokenSyntax(Kind, Text, LeadingTrivia, TrailingTrivia, diagnostics, GetAnnotations());
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new UnknownTokenSyntax(Kind, Text, LeadingTrivia, TrailingTrivia, GetDiagnostics(), annotations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax
|
||||
{
|
||||
internal class WhitespaceTokenSyntax : SyntaxToken
|
||||
{
|
||||
internal WhitespaceTokenSyntax(string text, params RazorDiagnostic[] diagnostics)
|
||||
: base(SyntaxKind.Whitespace, text, null, null, diagnostics, null)
|
||||
{
|
||||
}
|
||||
|
||||
internal WhitespaceTokenSyntax(string text, GreenNode leadingTrivia, GreenNode trailingTrivia)
|
||||
: base(SyntaxKind.Whitespace, text, leadingTrivia, trailingTrivia)
|
||||
{
|
||||
}
|
||||
|
||||
protected WhitespaceTokenSyntax(SyntaxKind kind, string name, GreenNode leadingTrivia, GreenNode trailingTrivia)
|
||||
: base(kind, name, leadingTrivia, trailingTrivia)
|
||||
{
|
||||
}
|
||||
|
||||
protected WhitespaceTokenSyntax(SyntaxKind kind, string name, GreenNode leadingTrivia, GreenNode trailingTrivia, RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations)
|
||||
: base(kind, name, leadingTrivia, trailingTrivia, diagnostics, annotations)
|
||||
{
|
||||
}
|
||||
|
||||
internal override SyntaxNode CreateRed(SyntaxNode parent, int position) => new Syntax.WhitespaceTokenSyntax(this, parent, position);
|
||||
|
||||
public override SyntaxToken TokenWithLeadingTrivia(GreenNode trivia)
|
||||
{
|
||||
return new WhitespaceTokenSyntax(Kind, Text, trivia, TrailingTrivia);
|
||||
}
|
||||
|
||||
public override SyntaxToken TokenWithTrailingTrivia(GreenNode trivia)
|
||||
{
|
||||
return new WhitespaceTokenSyntax(Kind, Text, LeadingTrivia, trivia);
|
||||
}
|
||||
|
||||
internal override GreenNode SetDiagnostics(RazorDiagnostic[] diagnostics)
|
||||
{
|
||||
return new WhitespaceTokenSyntax(Kind, Text, LeadingTrivia, TrailingTrivia, diagnostics, GetAnnotations());
|
||||
}
|
||||
|
||||
internal override GreenNode SetAnnotations(SyntaxAnnotation[] annotations)
|
||||
{
|
||||
return new WhitespaceTokenSyntax(Kind, Text, LeadingTrivia, TrailingTrivia, GetDiagnostics(), annotations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal class NewLineTokenSyntax : SyntaxToken
|
||||
{
|
||||
internal NewLineTokenSyntax(GreenNode green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
internal new InternalSyntax.NewLineTokenSyntax Green => (InternalSyntax.NewLineTokenSyntax)base.Green;
|
||||
|
||||
public string Value => Text;
|
||||
|
||||
internal override SyntaxToken WithLeadingTriviaCore(SyntaxNode trivia)
|
||||
{
|
||||
return new InternalSyntax.NewLineTokenSyntax(Text, trivia?.Green, GetTrailingTrivia().Node?.Green).CreateRed(Parent, Position) as NewLineTokenSyntax;
|
||||
}
|
||||
|
||||
internal override SyntaxToken WithTrailingTriviaCore(SyntaxNode trivia)
|
||||
{
|
||||
return new InternalSyntax.NewLineTokenSyntax(Text, GetLeadingTrivia().Node?.Green, trivia?.Green).CreateRed(Parent, Position) as NewLineTokenSyntax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
[Flags]
|
||||
internal enum NodeFlags : byte
|
||||
{
|
||||
None = 0,
|
||||
ContainsDiagnostics = 1 << 0,
|
||||
ContainsStructuredTrivia = 1 << 1,
|
||||
ContainsDirectives = 1 << 2,
|
||||
ContainsSkippedText = 1 << 3,
|
||||
ContainsAnnotations = 1 << 4,
|
||||
IsMissing = 1 << 5,
|
||||
|
||||
InheritMask = ContainsDiagnostics | ContainsStructuredTrivia | ContainsDirectives | ContainsSkippedText | ContainsAnnotations | IsMissing,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
// 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;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
#if DETECT_LEAKS
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#endif
|
||||
|
||||
// define TRACE_LEAKS to get additional diagnostics that can lead to the leak sources. note: it will
|
||||
// make everything about 2-3x slower
|
||||
//
|
||||
// #define TRACE_LEAKS
|
||||
|
||||
// define DETECT_LEAKS to detect possible leaks
|
||||
// #if DEBUG
|
||||
// #define DETECT_LEAKS //for now always enable DETECT_LEAKS in debug.
|
||||
// #endif
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic implementation of object pooling pattern with predefined pool size limit. The main
|
||||
/// purpose is that limited number of frequently used objects can be kept in the pool for
|
||||
/// further recycling.
|
||||
///
|
||||
/// Notes:
|
||||
/// 1) it is not the goal to keep all returned objects. Pool is not meant for storage. If there
|
||||
/// is no space in the pool, extra returned objects will be dropped.
|
||||
///
|
||||
/// 2) it is implied that if object was obtained from a pool, the caller will return it back in
|
||||
/// a relatively short time. Keeping checked out objects for long durations is ok, but
|
||||
/// reduces usefulness of pooling. Just new up your own.
|
||||
///
|
||||
/// Not returning objects to the pool in not detrimental to the pool's work, but is a bad practice.
|
||||
/// Rationale:
|
||||
/// If there is no intent for reusing the object, do not use pool - just use "new".
|
||||
/// </summary>
|
||||
internal class ObjectPool<T> where T : class
|
||||
{
|
||||
private struct Element
|
||||
{
|
||||
internal T Value;
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Not using <see cref="T:System.Func{T}"/> because this file is linked into the (debugger) Formatter,
|
||||
/// which does not have that type (since it compiles against .NET 2.0).
|
||||
/// </remarks>
|
||||
internal delegate T Factory();
|
||||
|
||||
// storage for the pool objects.
|
||||
private readonly Element[] _items;
|
||||
|
||||
// factory is stored for the lifetime of the pool. We will call this only when pool needs to
|
||||
// expand. compared to "new T()", Func gives more flexibility to implementers and faster
|
||||
// than "new T()".
|
||||
private readonly Factory _factory;
|
||||
|
||||
#if DETECT_LEAKS
|
||||
private static readonly ConditionalWeakTable<T, LeakTracker> leakTrackers = new ConditionalWeakTable<T, LeakTracker>();
|
||||
|
||||
private class LeakTracker : IDisposable
|
||||
{
|
||||
private volatile bool disposed;
|
||||
|
||||
#if TRACE_LEAKS
|
||||
internal volatile System.Diagnostics.StackTrace Trace = null;
|
||||
#endif
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
disposed = true;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private string GetTrace()
|
||||
{
|
||||
#if TRACE_LEAKS
|
||||
return Trace == null? "": Trace.ToString();
|
||||
#else
|
||||
return "Leak tracing information is disabled. Define TRACE_LEAKS on ObjectPool`1.cs to get more info \n";
|
||||
#endif
|
||||
}
|
||||
|
||||
~LeakTracker()
|
||||
{
|
||||
if (!this.disposed &&
|
||||
!Environment.HasShutdownStarted &&
|
||||
!AppDomain.CurrentDomain.IsFinalizingForUnload())
|
||||
{
|
||||
string report = string.Format("Pool detected potential leaking of {0}. \n Location of the leak: \n {1} ",
|
||||
typeof(T).ToString(),
|
||||
GetTrace());
|
||||
|
||||
// If you are seeing this message it means that object has been allocated from the pool
|
||||
// and has not been returned back. This is not critical, but turns pool into rather
|
||||
// inefficient kind of "new".
|
||||
Debug.WriteLine("TRACEOBJECTPOOLLEAKS_BEGIN\n" + report + "TRACEOBJECTPOOLLEAKS_END");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal ObjectPool(Factory factory)
|
||||
: this(factory, Environment.ProcessorCount * 2)
|
||||
{ }
|
||||
|
||||
internal ObjectPool(Factory factory, int size)
|
||||
{
|
||||
_factory = factory;
|
||||
_items = new Element[size];
|
||||
}
|
||||
|
||||
private T CreateInstance()
|
||||
{
|
||||
var inst = _factory();
|
||||
return inst;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Produces an instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Search strategy is a simple linear probing which is chosen for it cache-friendliness.
|
||||
/// Note that Free will try to store recycled objects close to the start thus statistically
|
||||
/// reducing how far we will typically search.
|
||||
/// </remarks>
|
||||
internal T Allocate()
|
||||
{
|
||||
var items = _items;
|
||||
T inst;
|
||||
|
||||
for (var i = 0; i < items.Length; i++)
|
||||
{
|
||||
// Note that the read is optimistically not synchronized. That is intentional.
|
||||
// We will interlock only when we have a candidate. in a worst case we may miss some
|
||||
// recently returned objects. Not a big deal.
|
||||
inst = items[i].Value;
|
||||
if (inst != null)
|
||||
{
|
||||
if (inst == Interlocked.CompareExchange(ref items[i].Value, null, inst))
|
||||
{
|
||||
goto gotInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inst = CreateInstance();
|
||||
gotInstance:
|
||||
|
||||
#if DETECT_LEAKS
|
||||
var tracker = new LeakTracker();
|
||||
leakTrackers.Add(inst, tracker);
|
||||
|
||||
#if TRACE_LEAKS
|
||||
var frame = new System.Diagnostics.StackTrace(false);
|
||||
tracker.Trace = frame;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns objects to the pool.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Search strategy is a simple linear probing which is chosen for it cache-friendliness.
|
||||
/// Note that Free will try to store recycled objects close to the start thus statistically
|
||||
/// reducing how far we will typically search in Allocate.
|
||||
/// </remarks>
|
||||
internal void Free(T obj)
|
||||
{
|
||||
Validate(obj);
|
||||
ForgetTrackedObject(obj);
|
||||
|
||||
var items = _items;
|
||||
for (var i = 0; i < items.Length; i++)
|
||||
{
|
||||
if (items[i].Value == null)
|
||||
{
|
||||
// Intentionally not using interlocked here.
|
||||
// In a worst case scenario two objects may be stored into same slot.
|
||||
// It is very unlikely to happen and will only mean that one of the objects will get collected.
|
||||
items[i].Value = obj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an object from leak tracking.
|
||||
///
|
||||
/// This is called when an object is returned to the pool. It may also be explicitly
|
||||
/// called if an object allocated from the pool is intentionally not being returned
|
||||
/// to the pool. This can be of use with pooled arrays if the consumer wants to
|
||||
/// return a larger array to the pool than was originally allocated.
|
||||
/// </summary>
|
||||
[Conditional("DEBUG")]
|
||||
internal void ForgetTrackedObject(T old, T replacement = null)
|
||||
{
|
||||
#if DETECT_LEAKS
|
||||
LeakTracker tracker;
|
||||
if (leakTrackers.TryGetValue(old, out tracker))
|
||||
{
|
||||
tracker.Dispose();
|
||||
leakTrackers.Remove(old);
|
||||
}
|
||||
else
|
||||
{
|
||||
string report = string.Format("Object of type {0} was freed, but was not from pool. \n Callstack: \n {1} ",
|
||||
typeof(T).ToString(),
|
||||
new System.Diagnostics.StackTrace(false));
|
||||
|
||||
Debug.WriteLine("TRACEOBJECTPOOLLEAKS_BEGIN\n" + report + "TRACEOBJECTPOOLLEAKS_END");
|
||||
}
|
||||
|
||||
if (replacement != null)
|
||||
{
|
||||
tracker = new LeakTracker();
|
||||
leakTrackers.Add(replacement, tracker);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void Validate(object obj)
|
||||
{
|
||||
Debug.Assert(obj != null, "freeing null?");
|
||||
|
||||
var items = _items;
|
||||
for (var i = 0; i < items.Length; i++)
|
||||
{
|
||||
var value = items[i].Value;
|
||||
if (value == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Assert(value != obj, "freeing twice?");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
{
|
||||
internal enum ParserState
|
||||
{
|
||||
Unknown,
|
||||
Misc,
|
||||
Content,
|
||||
StartTag,
|
||||
EndTag,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal class PunctuationSyntax : SyntaxToken
|
||||
{
|
||||
internal PunctuationSyntax(GreenNode green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
internal new InternalSyntax.PunctuationSyntax Green => (InternalSyntax.PunctuationSyntax)base.Green;
|
||||
|
||||
public string Punctuation => Text;
|
||||
|
||||
internal override SyntaxToken WithLeadingTriviaCore(SyntaxNode trivia)
|
||||
{
|
||||
return new InternalSyntax.PunctuationSyntax(Kind, Text, trivia?.Green, GetTrailingTrivia().Node?.Green).CreateRed(Parent, Position) as PunctuationSyntax;
|
||||
}
|
||||
|
||||
internal override SyntaxToken WithTrailingTriviaCore(SyntaxNode trivia)
|
||||
{
|
||||
return new InternalSyntax.PunctuationSyntax(Kind, Text, GetLeadingTrivia().Node?.Green, trivia?.Green).CreateRed(Parent, Position) as PunctuationSyntax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
// 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;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal static class SpecializedCollections
|
||||
{
|
||||
public static IEnumerator<T> EmptyEnumerator<T>()
|
||||
{
|
||||
return Empty.Enumerator<T>.Instance;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> EmptyEnumerable<T>()
|
||||
{
|
||||
return Empty.List<T>.Instance;
|
||||
}
|
||||
|
||||
public static ICollection<T> EmptyCollection<T>()
|
||||
{
|
||||
return Empty.List<T>.Instance;
|
||||
}
|
||||
|
||||
public static IList<T> EmptyList<T>()
|
||||
{
|
||||
return Empty.List<T>.Instance;
|
||||
}
|
||||
|
||||
public static IReadOnlyList<T> EmptyReadOnlyList<T>()
|
||||
{
|
||||
return Empty.List<T>.Instance;
|
||||
}
|
||||
|
||||
private class Empty
|
||||
{
|
||||
internal class Enumerator<T> : Enumerator, IEnumerator<T>
|
||||
{
|
||||
public static new readonly IEnumerator<T> Instance = new Enumerator<T>();
|
||||
|
||||
protected Enumerator()
|
||||
{
|
||||
}
|
||||
|
||||
public new T Current => throw new InvalidOperationException();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
internal class Enumerator : IEnumerator
|
||||
{
|
||||
public static readonly IEnumerator Instance = new Enumerator();
|
||||
|
||||
protected Enumerator()
|
||||
{
|
||||
}
|
||||
|
||||
public object Current => throw new InvalidOperationException();
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
internal class Enumerable<T> : IEnumerable<T>
|
||||
{
|
||||
// PERF: cache the instance of enumerator.
|
||||
// accessing a generic static field is kinda slow from here,
|
||||
// but since empty enumerables are singletons, there is no harm in having
|
||||
// one extra instance field
|
||||
private readonly IEnumerator<T> _enumerator = Enumerator<T>.Instance;
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return _enumerator;
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
internal class Collection<T> : Enumerable<T>, ICollection<T>
|
||||
{
|
||||
public static readonly ICollection<T> Instance = new Collection<T>();
|
||||
|
||||
protected Collection()
|
||||
{
|
||||
}
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
}
|
||||
|
||||
public int Count => 0;
|
||||
|
||||
public bool IsReadOnly => true;
|
||||
|
||||
public bool Remove(T item)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
internal class List<T> : Collection<T>, IList<T>, IReadOnlyList<T>
|
||||
{
|
||||
public static readonly new List<T> Instance = new List<T>();
|
||||
|
||||
protected List()
|
||||
{
|
||||
}
|
||||
|
||||
public int IndexOf(T item)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void Insert(int index, T item)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
// 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;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
/// <summary>
|
||||
/// A SyntaxAnnotation is used to annotate syntax elements with additional information.
|
||||
///
|
||||
/// Since syntax elements are immutable, annotating them requires creating new instances of them
|
||||
/// with the annotations attached.
|
||||
/// </summary>
|
||||
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
|
||||
internal sealed class SyntaxAnnotation : IEquatable<SyntaxAnnotation>
|
||||
{
|
||||
// use a value identity instead of object identity so a deserialized instance matches the original instance.
|
||||
private readonly long _id;
|
||||
private static long s_nextId;
|
||||
|
||||
// use a value identity instead of object identity so a deserialized instance matches the original instance.
|
||||
public string Kind { get; }
|
||||
public string Data { get; }
|
||||
|
||||
public SyntaxAnnotation()
|
||||
{
|
||||
_id = System.Threading.Interlocked.Increment(ref s_nextId);
|
||||
}
|
||||
|
||||
public SyntaxAnnotation(string kind)
|
||||
: this()
|
||||
{
|
||||
Kind = kind;
|
||||
}
|
||||
|
||||
public SyntaxAnnotation(string kind, string data)
|
||||
: this(kind)
|
||||
{
|
||||
Data = data;
|
||||
}
|
||||
|
||||
private string GetDebuggerDisplay()
|
||||
{
|
||||
return string.Format("Annotation: Kind='{0}' Data='{1}'", this.Kind ?? "", this.Data ?? "");
|
||||
}
|
||||
|
||||
public bool Equals(SyntaxAnnotation other)
|
||||
{
|
||||
return (object)other != null && _id == other._id;
|
||||
}
|
||||
|
||||
public static bool operator ==(SyntaxAnnotation left, SyntaxAnnotation right)
|
||||
{
|
||||
if ((object)left == (object)right)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((object)left == null || (object)right == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(SyntaxAnnotation left, SyntaxAnnotation right)
|
||||
{
|
||||
if ((object)left == (object)right)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((object)left == null || (object)right == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as SyntaxAnnotation);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _id.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
{
|
||||
internal enum SyntaxKind : byte
|
||||
{
|
||||
Unknown,
|
||||
List,
|
||||
Whitespace,
|
||||
NewLine,
|
||||
|
||||
// HTML
|
||||
HtmlText,
|
||||
HtmlDocument,
|
||||
HtmlDeclaration,
|
||||
HtmlTextLiteralToken,
|
||||
OpenAngle,
|
||||
Bang,
|
||||
ForwardSlash,
|
||||
QuestionMark,
|
||||
DoubleHyphen,
|
||||
LeftBracket,
|
||||
CloseAngle,
|
||||
RightBracket,
|
||||
Equals,
|
||||
DoubleQuote,
|
||||
SingleQuote,
|
||||
Transition,
|
||||
Colon,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal abstract class SyntaxList : SyntaxNode
|
||||
{
|
||||
internal SyntaxList(InternalSyntax.SyntaxList green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
internal override SyntaxNode Accept(SyntaxVisitor visitor)
|
||||
{
|
||||
return visitor.Visit(this);
|
||||
}
|
||||
|
||||
internal class WithTwoChildren : SyntaxList
|
||||
{
|
||||
private SyntaxNode _child0;
|
||||
private SyntaxNode _child1;
|
||||
|
||||
internal WithTwoChildren(InternalSyntax.SyntaxList green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
internal override SyntaxNode GetNodeSlot(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return GetRedElement(ref _child0, 0);
|
||||
case 1:
|
||||
return GetRedElement(ref _child1, 1);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal override SyntaxNode GetCachedSlot(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return _child0;
|
||||
case 1:
|
||||
return _child1;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class WithThreeChildren : SyntaxList
|
||||
{
|
||||
private SyntaxNode _child0;
|
||||
private SyntaxNode _child1;
|
||||
private SyntaxNode _child2;
|
||||
|
||||
internal WithThreeChildren(InternalSyntax.SyntaxList green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
internal override SyntaxNode GetNodeSlot(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return GetRedElement(ref _child0, 0);
|
||||
case 1:
|
||||
return GetRedElement(ref _child1, 1);
|
||||
case 2:
|
||||
return GetRedElement(ref _child2, 2);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal override SyntaxNode GetCachedSlot(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return _child0;
|
||||
case 1:
|
||||
return _child1;
|
||||
case 2:
|
||||
return _child2;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class WithManyChildren : SyntaxList
|
||||
{
|
||||
private readonly ArrayElement<SyntaxNode>[] _children;
|
||||
|
||||
internal WithManyChildren(InternalSyntax.SyntaxList green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
_children = new ArrayElement<SyntaxNode>[green.SlotCount];
|
||||
}
|
||||
|
||||
internal override SyntaxNode GetNodeSlot(int index)
|
||||
{
|
||||
return this.GetRedElement(ref _children[index].Value, index);
|
||||
}
|
||||
|
||||
internal override SyntaxNode GetCachedSlot(int index)
|
||||
{
|
||||
return _children[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
// 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;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal class SyntaxListBuilder
|
||||
{
|
||||
private ArrayElement<GreenNode>[] _nodes;
|
||||
|
||||
public int Count { get; private set; }
|
||||
|
||||
public SyntaxListBuilder(int size)
|
||||
{
|
||||
_nodes = new ArrayElement<GreenNode>[size];
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
public void Add(SyntaxNode item)
|
||||
{
|
||||
AddInternal(item.Green);
|
||||
}
|
||||
|
||||
internal void AddInternal(GreenNode item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
if (_nodes == null || Count >= _nodes.Length)
|
||||
{
|
||||
Grow(Count == 0 ? 8 : _nodes.Length * 2);
|
||||
}
|
||||
|
||||
_nodes[Count++].Value = item;
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxNode[] items)
|
||||
{
|
||||
AddRange(items, 0, items.Length);
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxNode[] items, int offset, int length)
|
||||
{
|
||||
if (_nodes == null || Count + length > _nodes.Length)
|
||||
{
|
||||
Grow(Count + length);
|
||||
}
|
||||
|
||||
for (int i = offset, j = Count; i < offset + length; ++i, ++j)
|
||||
{
|
||||
_nodes[j].Value = items[i].Green;
|
||||
}
|
||||
|
||||
var start = Count;
|
||||
Count += length;
|
||||
Validate(start, Count);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void Validate(int start, int end)
|
||||
{
|
||||
for (var i = start; i < end; i++)
|
||||
{
|
||||
if (_nodes[i].Value == null)
|
||||
{
|
||||
throw new ArgumentException("Cannot add a null node.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxList<SyntaxNode> list)
|
||||
{
|
||||
AddRange(list, 0, list.Count);
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxList<SyntaxNode> list, int offset, int count)
|
||||
{
|
||||
if (_nodes == null || Count + count > _nodes.Length)
|
||||
{
|
||||
Grow(Count + count);
|
||||
}
|
||||
|
||||
var dst = Count;
|
||||
for (int i = offset, limit = offset + count; i < limit; i++)
|
||||
{
|
||||
_nodes[dst].Value = list.ItemInternal(i).Green;
|
||||
dst++;
|
||||
}
|
||||
|
||||
var start = Count;
|
||||
Count += count;
|
||||
Validate(start, Count);
|
||||
}
|
||||
|
||||
public void AddRange<TNode>(SyntaxList<TNode> list) where TNode : SyntaxNode
|
||||
{
|
||||
AddRange(list, 0, list.Count);
|
||||
}
|
||||
|
||||
public void AddRange<TNode>(SyntaxList<TNode> list, int offset, int count) where TNode : SyntaxNode
|
||||
{
|
||||
AddRange(new SyntaxList<SyntaxNode>(list.Node), offset, count);
|
||||
}
|
||||
|
||||
private void Grow(int size)
|
||||
{
|
||||
var tmp = new ArrayElement<GreenNode>[size];
|
||||
Array.Copy(_nodes, tmp, _nodes.Length);
|
||||
_nodes = tmp;
|
||||
}
|
||||
|
||||
public bool Any(SyntaxKind kind)
|
||||
{
|
||||
for (var i = 0; i < Count; i++)
|
||||
{
|
||||
if (_nodes[i].Value.Kind == kind)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal GreenNode ToListNode()
|
||||
{
|
||||
switch (Count)
|
||||
{
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
return _nodes[0].Value;
|
||||
case 2:
|
||||
return InternalSyntax.SyntaxList.List(_nodes[0].Value, _nodes[1].Value);
|
||||
case 3:
|
||||
return InternalSyntax.SyntaxList.List(_nodes[0].Value, _nodes[1].Value, _nodes[2].Value);
|
||||
default:
|
||||
var tmp = new ArrayElement<GreenNode>[Count];
|
||||
for (var i = 0; i < Count; i++)
|
||||
{
|
||||
tmp[i].Value = _nodes[i].Value;
|
||||
}
|
||||
|
||||
return InternalSyntax.SyntaxList.List(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxList<SyntaxNode>(SyntaxListBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
return default(SyntaxList<SyntaxNode>);
|
||||
}
|
||||
|
||||
return builder.ToList();
|
||||
}
|
||||
|
||||
internal void RemoveLast()
|
||||
{
|
||||
Count -= 1;
|
||||
_nodes[Count] = default(ArrayElement<GreenNode>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal static class SyntaxListBuilderExtensions
|
||||
{
|
||||
public static SyntaxList<SyntaxNode> ToList(this SyntaxListBuilder builder)
|
||||
{
|
||||
if (builder == null || builder.Count == 0)
|
||||
{
|
||||
return default(SyntaxList<SyntaxNode>);
|
||||
}
|
||||
|
||||
return new SyntaxList<SyntaxNode>(builder.ToListNode().CreateRed());
|
||||
}
|
||||
|
||||
public static SyntaxList<TNode> ToList<TNode>(this SyntaxListBuilder builder)
|
||||
where TNode : SyntaxNode
|
||||
{
|
||||
if (builder == null || builder.Count == 0)
|
||||
{
|
||||
return new SyntaxList<TNode>();
|
||||
}
|
||||
|
||||
return new SyntaxList<TNode>(builder.ToListNode().CreateRed());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal readonly struct SyntaxListBuilder<TNode>
|
||||
where TNode : SyntaxNode
|
||||
{
|
||||
private readonly SyntaxListBuilder _builder;
|
||||
|
||||
public SyntaxListBuilder(int size)
|
||||
: this(new SyntaxListBuilder(size))
|
||||
{
|
||||
}
|
||||
|
||||
public static SyntaxListBuilder<TNode> Create()
|
||||
{
|
||||
return new SyntaxListBuilder<TNode>(8);
|
||||
}
|
||||
|
||||
internal SyntaxListBuilder(SyntaxListBuilder builder)
|
||||
{
|
||||
_builder = builder;
|
||||
}
|
||||
|
||||
public bool IsNull
|
||||
{
|
||||
get
|
||||
{
|
||||
return _builder == null;
|
||||
}
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return _builder.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_builder.Clear();
|
||||
}
|
||||
|
||||
public SyntaxListBuilder<TNode> Add(TNode node)
|
||||
{
|
||||
_builder.Add(node);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void AddRange(TNode[] items, int offset, int length)
|
||||
{
|
||||
_builder.AddRange(items, offset, length);
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxList<TNode> nodes)
|
||||
{
|
||||
_builder.AddRange(nodes);
|
||||
}
|
||||
|
||||
public void AddRange(SyntaxList<TNode> nodes, int offset, int length)
|
||||
{
|
||||
_builder.AddRange(nodes, offset, length);
|
||||
}
|
||||
|
||||
public bool Any(SyntaxKind kind)
|
||||
{
|
||||
return _builder.Any(kind);
|
||||
}
|
||||
|
||||
public SyntaxList<TNode> ToList()
|
||||
{
|
||||
return _builder.ToList();
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxListBuilder(SyntaxListBuilder<TNode> builder)
|
||||
{
|
||||
return builder._builder;
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxList<TNode>(SyntaxListBuilder<TNode> builder)
|
||||
{
|
||||
if (builder._builder != null)
|
||||
{
|
||||
return builder.ToList();
|
||||
}
|
||||
|
||||
return default(SyntaxList<TNode>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,606 @@
|
|||
// 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;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal readonly struct SyntaxList<TNode> : IReadOnlyList<TNode>, IEquatable<SyntaxList<TNode>>
|
||||
where TNode : SyntaxNode
|
||||
{
|
||||
public SyntaxList(SyntaxNode node)
|
||||
{
|
||||
Node = node;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a singleton list of syntax nodes.
|
||||
/// </summary>
|
||||
/// <param name="node">The single element node.</param>
|
||||
public SyntaxList(TNode node)
|
||||
: this((SyntaxNode)node)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a list of syntax nodes.
|
||||
/// </summary>
|
||||
/// <param name="nodes">A sequence of element nodes.</param>
|
||||
public SyntaxList(IEnumerable<TNode> nodes)
|
||||
: this(CreateNode(nodes))
|
||||
{
|
||||
}
|
||||
|
||||
private static SyntaxNode CreateNode(IEnumerable<TNode> nodes)
|
||||
{
|
||||
if (nodes == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var builder = (nodes is ICollection<TNode> collection) ? new SyntaxListBuilder<TNode>(collection.Count) : SyntaxListBuilder<TNode>.Create();
|
||||
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
builder.Add(node);
|
||||
}
|
||||
|
||||
return builder.ToList().Node;
|
||||
}
|
||||
|
||||
internal SyntaxNode Node { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of nodes in the list.
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return Node == null ? 0 : (Node.IsList ? Node.SlotCount : 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the node at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based index of the node to get or set.</param>
|
||||
/// <returns>The node at the specified index.</returns>
|
||||
public TNode this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Node != null)
|
||||
{
|
||||
if (Node.IsList)
|
||||
{
|
||||
if (unchecked((uint)index < (uint)Node.SlotCount))
|
||||
{
|
||||
return (TNode)Node.GetNodeSlot(index);
|
||||
}
|
||||
}
|
||||
else if (index == 0)
|
||||
{
|
||||
return (TNode)Node;
|
||||
}
|
||||
}
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
internal SyntaxNode ItemInternal(int index)
|
||||
{
|
||||
if (Node.IsList)
|
||||
{
|
||||
return Node.GetNodeSlot(index);
|
||||
}
|
||||
|
||||
Debug.Assert(index == 0);
|
||||
return Node;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The absolute span of the list elements in characters, including the leading and trailing trivia of the first and last elements.
|
||||
/// </summary>
|
||||
public TextSpan FullSpan
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Count == 0)
|
||||
{
|
||||
return default(TextSpan);
|
||||
}
|
||||
else
|
||||
{
|
||||
return TextSpan.FromBounds(this[0].FullSpan.Start, this[Count - 1].FullSpan.End);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The absolute span of the list elements in characters, not including the leading and trailing trivia of the first and last elements.
|
||||
/// </summary>
|
||||
public TextSpan Span
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Count == 0)
|
||||
{
|
||||
return default(TextSpan);
|
||||
}
|
||||
else
|
||||
{
|
||||
return TextSpan.FromBounds(this[0].Span.Start, this[Count - 1].Span.End);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the string representation of the nodes in this list, not including
|
||||
/// the first node's leading trivia and the last node's trailing trivia.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The string representation of the nodes in this list, not including
|
||||
/// the first node's leading trivia and the last node's trailing trivia.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Node != null ? Node.ToString() : string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the full string representation of the nodes in this list including
|
||||
/// the first node's leading trivia and the last node's trailing trivia.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The full string representation of the nodes in this list including
|
||||
/// the first node's leading trivia and the last node's trailing trivia.
|
||||
/// </returns>
|
||||
public string ToFullString()
|
||||
{
|
||||
return Node != null ? Node.ToFullString() : string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new list with the specified node added at the end.
|
||||
/// </summary>
|
||||
/// <param name="node">The node to add.</param>
|
||||
public SyntaxList<TNode> Add(TNode node)
|
||||
{
|
||||
return Insert(Count, node);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new list with the specified nodes added at the end.
|
||||
/// </summary>
|
||||
/// <param name="nodes">The nodes to add.</param>
|
||||
public SyntaxList<TNode> AddRange(IEnumerable<TNode> nodes)
|
||||
{
|
||||
return InsertRange(Count, nodes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new list with the specified node inserted at the index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index to insert at.</param>
|
||||
/// <param name="node">The node to insert.</param>
|
||||
public SyntaxList<TNode> Insert(int index, TNode node)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(node));
|
||||
}
|
||||
|
||||
return InsertRange(index, new[] { node });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new list with the specified nodes inserted at the index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index to insert at.</param>
|
||||
/// <param name="nodes">The nodes to insert.</param>
|
||||
public SyntaxList<TNode> InsertRange(int index, IEnumerable<TNode> nodes)
|
||||
{
|
||||
if (index < 0 || index > Count)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
if (nodes == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(nodes));
|
||||
}
|
||||
|
||||
var list = this.ToList();
|
||||
list.InsertRange(index, nodes);
|
||||
|
||||
if (list.Count == 0)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CreateList(list[0].Green, list);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new list with the element at specified index removed.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the element to remove.</param>
|
||||
public SyntaxList<TNode> RemoveAt(int index)
|
||||
{
|
||||
if (index < 0 || index > Count)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
return Remove(this[index]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new list with the element removed.
|
||||
/// </summary>
|
||||
/// <param name="node">The element to remove.</param>
|
||||
public SyntaxList<TNode> Remove(TNode node)
|
||||
{
|
||||
return CreateList(this.Where(x => x != node).ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new list with the specified element replaced with the new node.
|
||||
/// </summary>
|
||||
/// <param name="nodeInList">The element to replace.</param>
|
||||
/// <param name="newNode">The new node.</param>
|
||||
public SyntaxList<TNode> Replace(TNode nodeInList, TNode newNode)
|
||||
{
|
||||
return ReplaceRange(nodeInList, new[] { newNode });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new list with the specified element replaced with new nodes.
|
||||
/// </summary>
|
||||
/// <param name="nodeInList">The element to replace.</param>
|
||||
/// <param name="newNodes">The new nodes.</param>
|
||||
public SyntaxList<TNode> ReplaceRange(TNode nodeInList, IEnumerable<TNode> newNodes)
|
||||
{
|
||||
if (nodeInList == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(nodeInList));
|
||||
}
|
||||
|
||||
if (newNodes == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(newNodes));
|
||||
}
|
||||
|
||||
var index = IndexOf(nodeInList);
|
||||
if (index >= 0 && index < Count)
|
||||
{
|
||||
var list = this.ToList();
|
||||
list.RemoveAt(index);
|
||||
list.InsertRange(index, newNodes);
|
||||
return CreateList(list);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException(nameof(nodeInList));
|
||||
}
|
||||
}
|
||||
|
||||
static SyntaxList<TNode> CreateList(List<TNode> items)
|
||||
{
|
||||
if (items.Count == 0)
|
||||
{
|
||||
return default(SyntaxList<TNode>);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CreateList(items[0].Green, items);
|
||||
}
|
||||
}
|
||||
|
||||
static SyntaxList<TNode> CreateList(GreenNode creator, List<TNode> items)
|
||||
{
|
||||
if (items.Count == 0)
|
||||
{
|
||||
return default(SyntaxList<TNode>);
|
||||
}
|
||||
|
||||
var newGreen = creator.CreateList(items.Select(n => n.Green));
|
||||
return new SyntaxList<TNode>(newGreen.CreateRed());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The first node in the list.
|
||||
/// </summary>
|
||||
public TNode First()
|
||||
{
|
||||
return this[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The first node in the list or default if the list is empty.
|
||||
/// </summary>
|
||||
public TNode FirstOrDefault()
|
||||
{
|
||||
if (this.Any())
|
||||
{
|
||||
return this[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The last node in the list.
|
||||
/// </summary>
|
||||
public TNode Last()
|
||||
{
|
||||
return this[Count - 1];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The last node in the list or default if the list is empty.
|
||||
/// </summary>
|
||||
public TNode LastOrDefault()
|
||||
{
|
||||
if (Any())
|
||||
{
|
||||
return this[Count - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if the list has at least one node.
|
||||
/// </summary>
|
||||
public bool Any()
|
||||
{
|
||||
Debug.Assert(Node == null || Count != 0);
|
||||
return Node != null;
|
||||
}
|
||||
|
||||
// for debugging
|
||||
private TNode[] Nodes
|
||||
{
|
||||
get { return this.ToArray(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get's the enumerator for this list.
|
||||
/// </summary>
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(in this);
|
||||
}
|
||||
|
||||
IEnumerator<TNode> IEnumerable<TNode>.GetEnumerator()
|
||||
{
|
||||
if (this.Any())
|
||||
{
|
||||
return new EnumeratorImpl(this);
|
||||
}
|
||||
|
||||
return SpecializedCollections.EmptyEnumerator<TNode>();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
if (this.Any())
|
||||
{
|
||||
return new EnumeratorImpl(this);
|
||||
}
|
||||
|
||||
return SpecializedCollections.EmptyEnumerator<TNode>();
|
||||
}
|
||||
|
||||
public static bool operator ==(SyntaxList<TNode> left, SyntaxList<TNode> right)
|
||||
{
|
||||
return left.Node == right.Node;
|
||||
}
|
||||
|
||||
public static bool operator !=(SyntaxList<TNode> left, SyntaxList<TNode> right)
|
||||
{
|
||||
return left.Node != right.Node;
|
||||
}
|
||||
|
||||
public bool Equals(SyntaxList<TNode> other)
|
||||
{
|
||||
return Node == other.Node;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is SyntaxList<TNode> && Equals((SyntaxList<TNode>)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Node?.GetHashCode() ?? 0;
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxList<TNode>(SyntaxList<SyntaxNode> nodes)
|
||||
{
|
||||
return new SyntaxList<TNode>(nodes.Node);
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxList<SyntaxNode>(SyntaxList<TNode> nodes)
|
||||
{
|
||||
return new SyntaxList<SyntaxNode>(nodes.Node);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The index of the node in this list, or -1 if the node is not in the list.
|
||||
/// </summary>
|
||||
public int IndexOf(TNode node)
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var child in this)
|
||||
{
|
||||
if (object.Equals(child, node))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int IndexOf(Func<TNode, bool> predicate)
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var child in this)
|
||||
{
|
||||
if (predicate(child))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
internal int IndexOf(SyntaxKind kind)
|
||||
{
|
||||
var index = 0;
|
||||
foreach (var child in this)
|
||||
{
|
||||
if (child.Kind == kind)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int LastIndexOf(TNode node)
|
||||
{
|
||||
for (var i = Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (object.Equals(this[i], node))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int LastIndexOf(Func<TNode, bool> predicate)
|
||||
{
|
||||
for (var i = Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (predicate(this[i]))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public struct Enumerator
|
||||
{
|
||||
private readonly SyntaxList<TNode> _list;
|
||||
private int _index;
|
||||
|
||||
internal Enumerator(in SyntaxList<TNode> list)
|
||||
{
|
||||
_list = list;
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
var newIndex = _index + 1;
|
||||
if (newIndex < _list.Count)
|
||||
{
|
||||
_index = newIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public TNode Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return (TNode)_list.ItemInternal(_index);
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
private class EnumeratorImpl : IEnumerator<TNode>
|
||||
{
|
||||
private Enumerator _e;
|
||||
|
||||
internal EnumeratorImpl(in SyntaxList<TNode> list)
|
||||
{
|
||||
_e = new Enumerator(in list);
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
return _e.MoveNext();
|
||||
}
|
||||
|
||||
public TNode Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return _e.Current;
|
||||
}
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return _e.Current;
|
||||
}
|
||||
}
|
||||
|
||||
void IEnumerator.Reset()
|
||||
{
|
||||
_e.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,252 @@
|
|||
// 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.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal abstract class SyntaxNode
|
||||
{
|
||||
public SyntaxNode(GreenNode green, SyntaxNode parent, int position)
|
||||
{
|
||||
Green = green;
|
||||
Parent = parent;
|
||||
Position = position;
|
||||
}
|
||||
|
||||
internal GreenNode Green { get; }
|
||||
|
||||
public SyntaxNode Parent { get; }
|
||||
|
||||
public int Position { get; }
|
||||
|
||||
public int EndPosition => Position + FullWidth;
|
||||
|
||||
public SyntaxKind Kind => Green.Kind;
|
||||
|
||||
public int Width => Green.Width;
|
||||
|
||||
public int FullWidth => Green.FullWidth;
|
||||
|
||||
public int SpanStart => Position + Green.GetLeadingTriviaWidth();
|
||||
|
||||
public TextSpan FullSpan => new TextSpan(Position, Green.FullWidth);
|
||||
|
||||
public TextSpan Span
|
||||
{
|
||||
get
|
||||
{
|
||||
// Start with the full span.
|
||||
var start = Position;
|
||||
var width = Green.FullWidth;
|
||||
|
||||
// adjust for preceding trivia (avoid calling this twice, do not call Green.Width)
|
||||
var precedingWidth = Green.GetLeadingTriviaWidth();
|
||||
start += precedingWidth;
|
||||
width -= precedingWidth;
|
||||
|
||||
// adjust for following trivia width
|
||||
width -= Green.GetTrailingTriviaWidth();
|
||||
|
||||
Debug.Assert(width >= 0);
|
||||
return new TextSpan(start, width);
|
||||
}
|
||||
}
|
||||
|
||||
internal int SlotCount => Green.SlotCount;
|
||||
|
||||
public bool IsList => Green.IsList;
|
||||
|
||||
public bool IsMissing => Green.IsMissing;
|
||||
|
||||
public bool HasLeadingTrivia
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetLeadingTrivia().Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasTrailingTrivia
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetTrailingTrivia().Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ContainsDiagnostics => Green.ContainsDiagnostics;
|
||||
|
||||
public bool ContainsAnnotations => Green.ContainsAnnotations;
|
||||
|
||||
internal abstract SyntaxNode Accept(SyntaxVisitor visitor);
|
||||
|
||||
internal abstract SyntaxNode GetNodeSlot(int index);
|
||||
|
||||
internal abstract SyntaxNode GetCachedSlot(int index);
|
||||
|
||||
internal SyntaxNode GetRed(ref SyntaxNode field, int slot)
|
||||
{
|
||||
var result = field;
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
var green = Green.GetSlot(slot);
|
||||
if (green != null)
|
||||
{
|
||||
Interlocked.CompareExchange(ref field, green.CreateRed(this, GetChildPosition(slot)), null);
|
||||
result = field;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected T GetRed<T>(ref T field, int slot) where T : SyntaxNode
|
||||
{
|
||||
var result = field;
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
var green = Green.GetSlot(slot);
|
||||
if (green != null)
|
||||
{
|
||||
Interlocked.CompareExchange(ref field, (T)green.CreateRed(this, this.GetChildPosition(slot)), null);
|
||||
result = field;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal SyntaxNode GetRedElement(ref SyntaxNode element, int slot)
|
||||
{
|
||||
Debug.Assert(IsList);
|
||||
|
||||
var result = element;
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
var green = Green.GetSlot(slot);
|
||||
// passing list's parent
|
||||
Interlocked.CompareExchange(ref element, green.CreateRed(Parent, GetChildPosition(slot)), null);
|
||||
result = element;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal virtual int GetChildPosition(int index)
|
||||
{
|
||||
var offset = 0;
|
||||
var green = Green;
|
||||
while (index > 0)
|
||||
{
|
||||
index--;
|
||||
var prevSibling = GetCachedSlot(index);
|
||||
if (prevSibling != null)
|
||||
{
|
||||
return prevSibling.EndPosition + offset;
|
||||
}
|
||||
var greenChild = green.GetSlot(index);
|
||||
if (greenChild != null)
|
||||
{
|
||||
offset += greenChild.FullWidth;
|
||||
}
|
||||
}
|
||||
|
||||
return Position + offset;
|
||||
}
|
||||
|
||||
public virtual SyntaxTriviaList GetLeadingTrivia()
|
||||
{
|
||||
var firstToken = GetFirstToken();
|
||||
return firstToken != null ? firstToken.GetLeadingTrivia() : default(SyntaxTriviaList);
|
||||
}
|
||||
|
||||
public virtual SyntaxTriviaList GetTrailingTrivia()
|
||||
{
|
||||
var lastToken = GetLastToken();
|
||||
return lastToken != null ? lastToken.GetTrailingTrivia() : default(SyntaxTriviaList);
|
||||
}
|
||||
|
||||
internal SyntaxToken GetFirstToken()
|
||||
{
|
||||
return ((SyntaxToken)GetFirstTerminal());
|
||||
}
|
||||
|
||||
internal SyntaxToken GetLastToken()
|
||||
{
|
||||
return ((SyntaxToken)GetLastTerminal());
|
||||
}
|
||||
|
||||
public SyntaxNode GetFirstTerminal()
|
||||
{
|
||||
var node = this;
|
||||
|
||||
do
|
||||
{
|
||||
var foundChild = false;
|
||||
for (int i = 0, n = node.SlotCount; i < n; i++)
|
||||
{
|
||||
var child = node.GetNodeSlot(i);
|
||||
if (child != null)
|
||||
{
|
||||
node = child;
|
||||
foundChild = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundChild)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
while (node.SlotCount != 0);
|
||||
|
||||
return node == this ? this : node;
|
||||
}
|
||||
|
||||
public SyntaxNode GetLastTerminal()
|
||||
{
|
||||
var node = this;
|
||||
|
||||
do
|
||||
{
|
||||
for (var i = node.SlotCount - 1; i >= 0; i--)
|
||||
{
|
||||
var child = node.GetNodeSlot(i);
|
||||
if (child != null)
|
||||
{
|
||||
node = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (node.SlotCount != 0);
|
||||
|
||||
return node == this ? this : node;
|
||||
}
|
||||
|
||||
public RazorDiagnostic[] GetDiagnostics()
|
||||
{
|
||||
return Green.GetDiagnostics();
|
||||
}
|
||||
|
||||
public SyntaxAnnotation[] GetAnnotations()
|
||||
{
|
||||
return Green.GetAnnotations();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Green.ToString();
|
||||
}
|
||||
|
||||
public virtual string ToFullString()
|
||||
{
|
||||
return Green.ToFullString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal abstract class SyntaxToken : SyntaxNode
|
||||
{
|
||||
internal SyntaxToken(GreenNode green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
internal new InternalSyntax.SyntaxToken Green => (InternalSyntax.SyntaxToken)base.Green;
|
||||
|
||||
public string Text => Green.Text;
|
||||
|
||||
internal override sealed SyntaxNode GetCachedSlot(int index)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
internal override sealed SyntaxNode GetNodeSlot(int slot)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
internal override SyntaxNode Accept(SyntaxVisitor visitor)
|
||||
{
|
||||
return visitor.VisitSyntaxToken(this);
|
||||
}
|
||||
|
||||
internal abstract SyntaxToken WithLeadingTriviaCore(SyntaxNode trivia);
|
||||
|
||||
internal abstract SyntaxToken WithTrailingTriviaCore(SyntaxNode trivia);
|
||||
|
||||
public SyntaxToken WithLeadingTrivia(SyntaxNode trivia) => WithLeadingTriviaCore(trivia);
|
||||
|
||||
public SyntaxToken WithTrailingTrivia(SyntaxNode trivia) => WithTrailingTriviaCore(trivia);
|
||||
|
||||
public SyntaxToken WithLeadingTrivia(IEnumerable<SyntaxTrivia> trivia)
|
||||
{
|
||||
var greenList = trivia?.Select(t => t.Green);
|
||||
return WithLeadingTriviaCore(Green.CreateList(greenList)?.CreateRed());
|
||||
}
|
||||
|
||||
public SyntaxToken WithTrailingTrivia(IEnumerable<SyntaxTrivia> trivia)
|
||||
{
|
||||
var greenList = trivia?.Select(t => t.Green);
|
||||
return WithTrailingTriviaCore(Green.CreateList(greenList)?.CreateRed());
|
||||
}
|
||||
|
||||
public override SyntaxTriviaList GetLeadingTrivia()
|
||||
{
|
||||
if (Green.LeadingTrivia == null)
|
||||
{
|
||||
return default(SyntaxTriviaList);
|
||||
}
|
||||
|
||||
return new SyntaxTriviaList(Green.LeadingTrivia.CreateRed(this, Position), Position);
|
||||
}
|
||||
|
||||
public override SyntaxTriviaList GetTrailingTrivia()
|
||||
{
|
||||
var trailingGreen = Green.TrailingTrivia;
|
||||
if (trailingGreen == null)
|
||||
{
|
||||
return default(SyntaxTriviaList);
|
||||
}
|
||||
|
||||
var leading = Green.LeadingTrivia;
|
||||
int index = 0;
|
||||
if (leading != null)
|
||||
{
|
||||
index = leading.IsList ? leading.SlotCount : 1;
|
||||
}
|
||||
int trailingPosition = Position + FullWidth;
|
||||
trailingPosition -= trailingGreen.FullWidth;
|
||||
|
||||
return new SyntaxTriviaList(trailingGreen.CreateRed(this, trailingPosition), trailingPosition, index);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal class SyntaxTrivia : SyntaxNode
|
||||
{
|
||||
internal SyntaxTrivia(GreenNode green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
internal new InternalSyntax.SyntaxTrivia Green => (InternalSyntax.SyntaxTrivia)base.Green;
|
||||
|
||||
public string Text => Green.Text;
|
||||
|
||||
internal override sealed SyntaxNode GetCachedSlot(int index)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
internal override sealed SyntaxNode GetNodeSlot(int slot)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
internal override SyntaxNode Accept(SyntaxVisitor visitor)
|
||||
{
|
||||
return visitor.VisitSyntaxTrivia(this);
|
||||
}
|
||||
|
||||
public sealed override SyntaxTriviaList GetTrailingTrivia()
|
||||
{
|
||||
return default(SyntaxTriviaList);
|
||||
}
|
||||
|
||||
public sealed override SyntaxTriviaList GetLeadingTrivia()
|
||||
{
|
||||
return default(SyntaxTriviaList);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Text;
|
||||
}
|
||||
|
||||
public sealed override string ToFullString()
|
||||
{
|
||||
return Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,785 @@
|
|||
// 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;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
internal readonly struct SyntaxTriviaList : IEquatable<SyntaxTriviaList>, IReadOnlyList<SyntaxTrivia>
|
||||
{
|
||||
public static SyntaxTriviaList Empty => default(SyntaxTriviaList);
|
||||
|
||||
internal SyntaxTriviaList(SyntaxNode node, int position, int index = 0)
|
||||
{
|
||||
Node = node;
|
||||
Position = position;
|
||||
Index = index;
|
||||
}
|
||||
|
||||
internal SyntaxTriviaList(SyntaxNode node)
|
||||
{
|
||||
Node = node;
|
||||
Position = node.Position;
|
||||
Index = 0;
|
||||
}
|
||||
|
||||
public SyntaxTriviaList(SyntaxTrivia trivia)
|
||||
{
|
||||
Node = trivia;
|
||||
Position = 0;
|
||||
Index = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a list of trivia.
|
||||
/// </summary>
|
||||
/// <param name="trivias">An array of trivia.</param>
|
||||
public SyntaxTriviaList(params SyntaxTrivia[] trivias)
|
||||
: this(CreateNode(trivias), 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a list of trivia.
|
||||
/// </summary>
|
||||
/// <param name="trivias">A sequence of trivia.</param>
|
||||
public SyntaxTriviaList(IEnumerable<SyntaxTrivia> trivias)
|
||||
: this(SyntaxTriviaListBuilder.Create(trivias).Node, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
private static SyntaxNode CreateNode(SyntaxTrivia[] trivias)
|
||||
{
|
||||
if (trivias == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var builder = new SyntaxTriviaListBuilder(trivias.Length);
|
||||
builder.Add(trivias);
|
||||
return builder.ToList().Node;
|
||||
}
|
||||
|
||||
internal SyntaxNode Node { get; }
|
||||
|
||||
internal int Position { get; }
|
||||
|
||||
internal int Index { get; }
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return Node == null ? 0 : (Node.IsList ? Node.SlotCount : 1); }
|
||||
}
|
||||
|
||||
public SyntaxTrivia ElementAt(int index)
|
||||
{
|
||||
return this[index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the trivia at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based index of the trivia to get.</param>
|
||||
/// <returns>The token at the specified index.</returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// <paramref name="index" /> is less than 0.-or-<paramref name="index" /> is equal to or greater than <see cref="Count" />. </exception>
|
||||
public SyntaxTrivia this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Node != null)
|
||||
{
|
||||
if (Node.IsList)
|
||||
{
|
||||
if (unchecked((uint)index < (uint)Node.SlotCount))
|
||||
{
|
||||
return Node.GetNodeSlot(index) as SyntaxTrivia;
|
||||
}
|
||||
}
|
||||
else if (index == 0)
|
||||
{
|
||||
return Node as SyntaxTrivia;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The absolute span of the list elements in characters, including the leading and trailing trivia of the first and last elements.
|
||||
/// </summary>
|
||||
public TextSpan FullSpan
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Node == null)
|
||||
{
|
||||
return default(TextSpan);
|
||||
}
|
||||
|
||||
return new TextSpan(Position, Node.FullWidth);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The absolute span of the list elements in characters, not including the leading and trailing trivia of the first and last elements.
|
||||
/// </summary>
|
||||
public TextSpan Span
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Node == null)
|
||||
{
|
||||
return default(TextSpan);
|
||||
}
|
||||
|
||||
return TextSpan.FromBounds(Position + Node.Green.GetLeadingTriviaWidth(),
|
||||
Position + Node.FullWidth - Node.Green.GetTrailingTriviaWidth());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first trivia in the list.
|
||||
/// </summary>
|
||||
/// <returns>The first trivia in the list.</returns>
|
||||
/// <exception cref="InvalidOperationException">The list is empty.</exception>
|
||||
public SyntaxTrivia First()
|
||||
{
|
||||
if (Any())
|
||||
{
|
||||
return this[0];
|
||||
}
|
||||
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the last trivia in the list.
|
||||
/// </summary>
|
||||
/// <returns>The last trivia in the list.</returns>
|
||||
/// <exception cref="InvalidOperationException">The list is empty.</exception>
|
||||
public SyntaxTrivia Last()
|
||||
{
|
||||
if (Any())
|
||||
{
|
||||
return this[Count - 1];
|
||||
}
|
||||
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does this list have any items.
|
||||
/// </summary>
|
||||
public bool Any()
|
||||
{
|
||||
return Node != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list which contains all elements of <see cref="SyntaxTriviaList"/> in reversed order.
|
||||
/// </summary>
|
||||
/// <returns><see cref="Reversed"/> which contains all elements of <see cref="SyntaxTriviaList"/> in reversed order</returns>
|
||||
public Reversed Reverse()
|
||||
{
|
||||
return new Reversed(this);
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
public int IndexOf(SyntaxTrivia triviaInList)
|
||||
{
|
||||
for (int i = 0, n = Count; i < n; i++)
|
||||
{
|
||||
var trivia = this[i];
|
||||
if (trivia == triviaInList)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
internal int IndexOf(SyntaxKind kind)
|
||||
{
|
||||
for (int i = 0, n = Count; i < n; i++)
|
||||
{
|
||||
if (this[i].Kind == kind)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="SyntaxTriviaList"/> with the specified trivia added to the end.
|
||||
/// </summary>
|
||||
/// <param name="trivia">The trivia to add.</param>
|
||||
public SyntaxTriviaList Add(SyntaxTrivia trivia)
|
||||
{
|
||||
return Insert(Count, trivia);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="SyntaxTriviaList"/> with the specified trivia added to the end.
|
||||
/// </summary>
|
||||
/// <param name="trivia">The trivia to add.</param>
|
||||
public SyntaxTriviaList AddRange(IEnumerable<SyntaxTrivia> trivia)
|
||||
{
|
||||
return InsertRange(Count, trivia);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="SyntaxTriviaList"/> with the specified trivia inserted at the index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index in the list to insert the trivia at.</param>
|
||||
/// <param name="trivia">The trivia to insert.</param>
|
||||
public SyntaxTriviaList Insert(int index, SyntaxTrivia trivia)
|
||||
{
|
||||
if (trivia == default(SyntaxTrivia))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(trivia));
|
||||
}
|
||||
|
||||
return InsertRange(index, new[] { trivia });
|
||||
}
|
||||
|
||||
private static readonly ObjectPool<SyntaxTriviaListBuilder> s_builderPool =
|
||||
new ObjectPool<SyntaxTriviaListBuilder>(() => SyntaxTriviaListBuilder.Create());
|
||||
|
||||
private static SyntaxTriviaListBuilder GetBuilder()
|
||||
=> s_builderPool.Allocate();
|
||||
|
||||
private static void ClearAndFreeBuilder(SyntaxTriviaListBuilder builder)
|
||||
{
|
||||
// It's possible someone might create a list with a huge amount of trivia
|
||||
// in it. We don't want to hold onto such items forever. So only cache
|
||||
// reasonably sized lists. In IDE testing, around 99% of all trivia lists
|
||||
// were 16 or less elements.
|
||||
const int MaxBuilderCount = 16;
|
||||
if (builder.Count <= MaxBuilderCount)
|
||||
{
|
||||
builder.Clear();
|
||||
s_builderPool.Free(builder);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="SyntaxTriviaList"/> with the specified trivia inserted at the index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index in the list to insert the trivia at.</param>
|
||||
/// <param name="trivia">The trivia to insert.</param>
|
||||
public SyntaxTriviaList InsertRange(int index, IEnumerable<SyntaxTrivia> trivia)
|
||||
{
|
||||
var thisCount = Count;
|
||||
if (index < 0 || index > thisCount)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
if (trivia == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(trivia));
|
||||
}
|
||||
|
||||
// Just return ourselves if we're not being asked to add anything.
|
||||
if (trivia is ICollection<SyntaxTrivia> triviaCollection && triviaCollection.Count == 0)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
var builder = GetBuilder();
|
||||
try
|
||||
{
|
||||
for (var i = 0; i < index; i++)
|
||||
{
|
||||
builder.Add(this[i]);
|
||||
}
|
||||
|
||||
builder.AddRange(trivia);
|
||||
|
||||
for (var i = index; i < thisCount; i++)
|
||||
{
|
||||
builder.Add(this[i]);
|
||||
}
|
||||
|
||||
return builder.Count == thisCount ? this : builder.ToList();
|
||||
}
|
||||
finally
|
||||
{
|
||||
ClearAndFreeBuilder(builder);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="SyntaxTriviaList"/> with the element at the specified index removed.
|
||||
/// </summary>
|
||||
/// <param name="index">The index identifying the element to remove.</param>
|
||||
public SyntaxTriviaList RemoveAt(int index)
|
||||
{
|
||||
if (index < 0 || index >= Count)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
var list = this.ToList();
|
||||
list.RemoveAt(index);
|
||||
return new SyntaxTriviaList(list);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="SyntaxTriviaList"/> with the specified element removed.
|
||||
/// </summary>
|
||||
/// <param name="triviaInList">The trivia element to remove.</param>
|
||||
public SyntaxTriviaList Remove(SyntaxTrivia triviaInList)
|
||||
{
|
||||
var index = IndexOf(triviaInList);
|
||||
if (index >= 0 && index < Count)
|
||||
{
|
||||
return RemoveAt(index);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="SyntaxTriviaList"/> with the specified element replaced with new trivia.
|
||||
/// </summary>
|
||||
/// <param name="triviaInList">The trivia element to replace.</param>
|
||||
/// <param name="newTrivia">The trivia to replace the element with.</param>
|
||||
public SyntaxTriviaList Replace(SyntaxTrivia triviaInList, SyntaxTrivia newTrivia)
|
||||
{
|
||||
if (newTrivia == default(SyntaxTrivia))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(newTrivia));
|
||||
}
|
||||
|
||||
return ReplaceRange(triviaInList, new[] { newTrivia });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="SyntaxTriviaList"/> with the specified element replaced with new trivia.
|
||||
/// </summary>
|
||||
/// <param name="triviaInList">The trivia element to replace.</param>
|
||||
/// <param name="newTrivia">The trivia to replace the element with.</param>
|
||||
public SyntaxTriviaList ReplaceRange(SyntaxTrivia triviaInList, IEnumerable<SyntaxTrivia> newTrivia)
|
||||
{
|
||||
var index = IndexOf(triviaInList);
|
||||
if (index >= 0 && index < Count)
|
||||
{
|
||||
var list = this.ToList();
|
||||
list.RemoveAt(index);
|
||||
list.InsertRange(index, newTrivia);
|
||||
return new SyntaxTriviaList(list);
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(triviaInList));
|
||||
}
|
||||
|
||||
// for debugging
|
||||
private SyntaxTrivia[] Nodes => this.ToArray();
|
||||
|
||||
IEnumerator<SyntaxTrivia> IEnumerable<SyntaxTrivia>.GetEnumerator()
|
||||
{
|
||||
if (Node == null)
|
||||
{
|
||||
return SpecializedCollections.EmptyEnumerator<SyntaxTrivia>();
|
||||
}
|
||||
|
||||
return new EnumeratorImpl(this);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
if (Node == null)
|
||||
{
|
||||
return SpecializedCollections.EmptyEnumerator<SyntaxTrivia>();
|
||||
}
|
||||
|
||||
return new EnumeratorImpl(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// get the green node at the specific slot
|
||||
/// </summary>
|
||||
private SyntaxNode GetNodeAt(int i)
|
||||
{
|
||||
return GetNodeAt(Node, i);
|
||||
}
|
||||
|
||||
private static SyntaxNode GetNodeAt(SyntaxNode node, int i)
|
||||
{
|
||||
Debug.Assert(node.IsList || (i == 0 && !node.IsList));
|
||||
return node.IsList ? node.GetNodeSlot(i) : node;
|
||||
}
|
||||
|
||||
public bool Equals(SyntaxTriviaList other)
|
||||
{
|
||||
return Node == other.Node && Index == other.Index;
|
||||
}
|
||||
|
||||
public static bool operator ==(SyntaxTriviaList left, SyntaxTriviaList right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(SyntaxTriviaList left, SyntaxTriviaList right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return (obj is SyntaxTriviaList) && Equals((SyntaxTriviaList)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hash = HashCodeCombiner.Start();
|
||||
hash.Add(Node);
|
||||
hash.Add(Index);
|
||||
return hash.CombinedHash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy <paramref name="count"/> number of items starting at <paramref name="offset"/> from this list into <paramref name="array"/> starting at <paramref name="arrayOffset"/>.
|
||||
/// </summary>
|
||||
internal void CopyTo(int offset, SyntaxTrivia[] array, int arrayOffset, int count)
|
||||
{
|
||||
if (offset < 0 || count < 0 || Count < offset + count)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// get first one without creating any red node
|
||||
var first = this[offset];
|
||||
array[arrayOffset] = first;
|
||||
|
||||
// calculate trivia position from the first ourselves from now on
|
||||
var position = first.Position;
|
||||
var current = first;
|
||||
|
||||
for (var i = 1; i < count; i++)
|
||||
{
|
||||
position += current.FullWidth;
|
||||
current = GetNodeAt(offset + i) as SyntaxTrivia;
|
||||
|
||||
array[arrayOffset + i] = current;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Node != null ? Node.ToString() : string.Empty;
|
||||
}
|
||||
|
||||
public string ToFullString()
|
||||
{
|
||||
return Node != null ? Node.ToFullString() : string.Empty;
|
||||
}
|
||||
|
||||
public static SyntaxTriviaList Create(SyntaxTrivia trivia)
|
||||
{
|
||||
return new SyntaxTriviaList(trivia);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reversed enumerable.
|
||||
/// </summary>
|
||||
public struct Reversed : IEnumerable<SyntaxTrivia>, IEquatable<Reversed>
|
||||
{
|
||||
private SyntaxTriviaList _list;
|
||||
|
||||
public Reversed(in SyntaxTriviaList list)
|
||||
{
|
||||
_list = list;
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(in _list);
|
||||
}
|
||||
|
||||
IEnumerator<SyntaxTrivia> IEnumerable<SyntaxTrivia>.GetEnumerator()
|
||||
{
|
||||
if (_list.Count == 0)
|
||||
{
|
||||
return SpecializedCollections.EmptyEnumerator<SyntaxTrivia>();
|
||||
}
|
||||
|
||||
return new ReversedEnumeratorImpl(in _list);
|
||||
}
|
||||
|
||||
IEnumerator
|
||||
IEnumerable.GetEnumerator()
|
||||
{
|
||||
if (_list.Count == 0)
|
||||
{
|
||||
return SpecializedCollections.EmptyEnumerator<SyntaxTrivia>();
|
||||
}
|
||||
|
||||
return new ReversedEnumeratorImpl(in _list);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _list.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is Reversed && Equals((Reversed)obj);
|
||||
}
|
||||
|
||||
public bool Equals(Reversed other)
|
||||
{
|
||||
return _list.Equals(other._list);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct Enumerator
|
||||
{
|
||||
private readonly SyntaxNode _singleNodeOrList;
|
||||
private readonly int _baseIndex;
|
||||
private readonly int _count;
|
||||
|
||||
private int _index;
|
||||
private SyntaxNode _current;
|
||||
private int _position;
|
||||
|
||||
public Enumerator(in SyntaxTriviaList list)
|
||||
: this()
|
||||
{
|
||||
if (list.Any())
|
||||
{
|
||||
_singleNodeOrList = list.Node;
|
||||
_baseIndex = list.Index;
|
||||
_count = list.Count;
|
||||
|
||||
_index = _count;
|
||||
_current = null;
|
||||
|
||||
var last = list.Last();
|
||||
_position = last.Position + last.FullWidth;
|
||||
}
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (_count == 0 || _index <= 0)
|
||||
{
|
||||
_current = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
_index--;
|
||||
|
||||
_current = GetNodeAt(_singleNodeOrList, _index);
|
||||
_position -= _current.FullWidth;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public SyntaxTrivia Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_current == null)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
return (SyntaxTrivia)_current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ReversedEnumeratorImpl : IEnumerator<SyntaxTrivia>
|
||||
{
|
||||
private Enumerator _enumerator;
|
||||
|
||||
// SyntaxTriviaList is a relatively big struct so is passed as ref
|
||||
internal ReversedEnumeratorImpl(in SyntaxTriviaList list)
|
||||
{
|
||||
_enumerator = new Enumerator(in list);
|
||||
}
|
||||
|
||||
public SyntaxTrivia Current => _enumerator.Current;
|
||||
|
||||
object IEnumerator.Current => _enumerator.Current;
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
return _enumerator.MoveNext();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct Enumerator
|
||||
{
|
||||
private SyntaxNode _singleNodeOrList;
|
||||
private int _baseIndex;
|
||||
private int _count;
|
||||
|
||||
private int _index;
|
||||
private SyntaxNode _current;
|
||||
private int _position;
|
||||
|
||||
internal Enumerator(in SyntaxTriviaList list)
|
||||
{
|
||||
_singleNodeOrList = list.Node;
|
||||
_baseIndex = list.Index;
|
||||
_count = list.Count;
|
||||
|
||||
_index = -1;
|
||||
_current = null;
|
||||
_position = list.Position;
|
||||
}
|
||||
|
||||
private void InitializeFrom(SyntaxNode node, int index, int position)
|
||||
{
|
||||
_singleNodeOrList = node;
|
||||
_baseIndex = index;
|
||||
_count = node.IsList ? node.SlotCount : 1;
|
||||
|
||||
_index = -1;
|
||||
_current = null;
|
||||
_position = position;
|
||||
}
|
||||
|
||||
// PERF: Used to initialize an enumerator for leading trivia directly from a token.
|
||||
// This saves constructing an intermediate SyntaxTriviaList. Also, passing token
|
||||
// by ref since it's a non-trivial struct
|
||||
internal void InitializeFromLeadingTrivia(in SyntaxToken token)
|
||||
{
|
||||
InitializeFrom(token.GetLeadingTrivia().Node, 0, token.Position);
|
||||
}
|
||||
|
||||
// PERF: Used to initialize an enumerator for trailing trivia directly from a token.
|
||||
// This saves constructing an intermediate SyntaxTriviaList. Also, passing token
|
||||
// by ref since it's a non-trivial struct
|
||||
internal void InitializeFromTrailingTrivia(in SyntaxToken token)
|
||||
{
|
||||
var leading = token.GetLeadingTrivia().Node;
|
||||
var index = 0;
|
||||
if (leading != null)
|
||||
{
|
||||
index = leading.IsList ? leading.SlotCount : 1;
|
||||
}
|
||||
|
||||
var trailing = token.GetTrailingTrivia().Node;
|
||||
var trailingPosition = token.Position + token.FullWidth;
|
||||
if (trailing != null)
|
||||
{
|
||||
trailingPosition -= trailing.FullWidth;
|
||||
}
|
||||
|
||||
InitializeFrom(trailing, index, trailingPosition);
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
var newIndex = _index + 1;
|
||||
if (newIndex >= _count)
|
||||
{
|
||||
// invalidate iterator
|
||||
_current = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
_index = newIndex;
|
||||
|
||||
if (_current != null)
|
||||
{
|
||||
_position += _current.FullWidth;
|
||||
}
|
||||
|
||||
_current = GetNodeAt(_singleNodeOrList, newIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
public SyntaxTrivia Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_current == null)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
return _current as SyntaxTrivia;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool TryMoveNextAndGetCurrent(out SyntaxTrivia current)
|
||||
{
|
||||
if (!MoveNext())
|
||||
{
|
||||
current = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
current = _current as SyntaxTrivia;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class EnumeratorImpl : IEnumerator<SyntaxTrivia>
|
||||
{
|
||||
private Enumerator _enumerator;
|
||||
|
||||
// SyntaxTriviaList is a relatively big struct so is passed as ref
|
||||
internal EnumeratorImpl(in SyntaxTriviaList list)
|
||||
{
|
||||
_enumerator = new Enumerator(list);
|
||||
}
|
||||
|
||||
public SyntaxTrivia Current => _enumerator.Current;
|
||||
|
||||
object IEnumerator.Current => _enumerator.Current;
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
return _enumerator.MoveNext();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal class SyntaxTriviaListBuilder
|
||||
{
|
||||
private SyntaxTrivia[] _nodes;
|
||||
|
||||
public SyntaxTriviaListBuilder(int size)
|
||||
{
|
||||
_nodes = new SyntaxTrivia[size];
|
||||
}
|
||||
|
||||
public static SyntaxTriviaListBuilder Create()
|
||||
{
|
||||
return new SyntaxTriviaListBuilder(4);
|
||||
}
|
||||
|
||||
public static SyntaxTriviaList Create(IEnumerable<SyntaxTrivia> trivia)
|
||||
{
|
||||
if (trivia == null)
|
||||
{
|
||||
return new SyntaxTriviaList();
|
||||
}
|
||||
|
||||
var builder = Create();
|
||||
builder.AddRange(trivia);
|
||||
return builder.ToList();
|
||||
}
|
||||
|
||||
public int Count { get; private set; }
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
public SyntaxTrivia this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index < 0 || index > Count)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
return _nodes[index];
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRange(IEnumerable<SyntaxTrivia> items)
|
||||
{
|
||||
if (items != null)
|
||||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SyntaxTriviaListBuilder Add(SyntaxTrivia item)
|
||||
{
|
||||
if (_nodes == null || Count >= _nodes.Length)
|
||||
{
|
||||
Grow(Count == 0 ? 8 : _nodes.Length * 2);
|
||||
}
|
||||
|
||||
_nodes[Count++] = item;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Add(SyntaxTrivia[] items)
|
||||
{
|
||||
Add(items, 0, items.Length);
|
||||
}
|
||||
|
||||
public void Add(SyntaxTrivia[] items, int offset, int length)
|
||||
{
|
||||
if (_nodes == null || Count + length > _nodes.Length)
|
||||
{
|
||||
Grow(Count + length);
|
||||
}
|
||||
|
||||
Array.Copy(items, offset, _nodes, Count, length);
|
||||
Count += length;
|
||||
}
|
||||
|
||||
public void Add(in SyntaxTriviaList list)
|
||||
{
|
||||
Add(list, 0, list.Count);
|
||||
}
|
||||
|
||||
public void Add(in SyntaxTriviaList list, int offset, int length)
|
||||
{
|
||||
if (_nodes == null || Count + length > _nodes.Length)
|
||||
{
|
||||
Grow(Count + length);
|
||||
}
|
||||
|
||||
list.CopyTo(offset, _nodes, Count, length);
|
||||
Count += length;
|
||||
}
|
||||
|
||||
private void Grow(int size)
|
||||
{
|
||||
var tmp = new SyntaxTrivia[size];
|
||||
Array.Copy(_nodes, tmp, _nodes.Length);
|
||||
_nodes = tmp;
|
||||
}
|
||||
|
||||
public static implicit operator SyntaxTriviaList(SyntaxTriviaListBuilder builder)
|
||||
{
|
||||
return builder.ToList();
|
||||
}
|
||||
|
||||
public SyntaxTriviaList ToList()
|
||||
{
|
||||
if (Count > 0)
|
||||
{
|
||||
var tmp = new ArrayElement<GreenNode>[Count];
|
||||
for (var i = 0; i < Count; i++)
|
||||
{
|
||||
tmp[i].Value = _nodes[i].Green;
|
||||
}
|
||||
return new SyntaxTriviaList(InternalSyntax.SyntaxList.List(tmp).CreateRed(), position: 0, index: 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return default(SyntaxTriviaList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal abstract class SyntaxVisitor
|
||||
{
|
||||
public virtual SyntaxNode Visit(SyntaxNode node)
|
||||
{
|
||||
if (node != null)
|
||||
{
|
||||
return node.Accept(this);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual SyntaxNode VisitSyntaxNode(SyntaxNode node)
|
||||
{
|
||||
return node;
|
||||
}
|
||||
|
||||
public virtual SyntaxNode VisitHtmlNode(HtmlNodeSyntax node)
|
||||
{
|
||||
return VisitSyntaxNode(node);
|
||||
}
|
||||
|
||||
public virtual SyntaxNode VisitHtmlText(HtmlTextSyntax node)
|
||||
{
|
||||
return VisitHtmlNode(node);
|
||||
}
|
||||
|
||||
public virtual SyntaxToken VisitSyntaxToken(SyntaxToken token)
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
public virtual SyntaxTrivia VisitSyntaxTrivia(SyntaxTrivia trivia)
|
||||
{
|
||||
return trivia;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,261 @@
|
|||
// 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;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
/// <summary>
|
||||
/// Immutable abstract representation of a span of text. For example, in an error diagnostic that reports a
|
||||
/// location, it could come from a parsed string, text from a tool editor buffer, etc.
|
||||
/// </summary>
|
||||
internal readonly struct TextSpan : IEquatable<TextSpan>, IComparable<TextSpan>
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a TextSpan instance beginning with the position Start and having the Length
|
||||
/// specified with <paramref name="length" />.
|
||||
/// </summary>
|
||||
public TextSpan(int start, int length)
|
||||
{
|
||||
if (start < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(start));
|
||||
}
|
||||
|
||||
if (start + length < start)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(length));
|
||||
}
|
||||
|
||||
Start = start;
|
||||
Length = length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start point of the span.
|
||||
/// </summary>
|
||||
public int Start { get; }
|
||||
|
||||
/// <summary>
|
||||
/// End of the span.
|
||||
/// </summary>
|
||||
public int End => Start + Length;
|
||||
|
||||
/// <summary>
|
||||
/// Length of the span.
|
||||
/// </summary>
|
||||
public int Length { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether or not the span is empty.
|
||||
/// </summary>
|
||||
public bool IsEmpty => Length == 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the position lies within the span.
|
||||
/// </summary>
|
||||
/// <param name="position">
|
||||
/// The position to check.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the position is greater than or equal to Start and strictly less
|
||||
/// than End, otherwise <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Contains(int position)
|
||||
{
|
||||
return unchecked((uint)(position - Start) < (uint)Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether <paramref name="span"/> falls completely within this span.
|
||||
/// </summary>
|
||||
/// <param name="span">
|
||||
/// The span to check.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified span falls completely within this span, otherwise <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Contains(TextSpan span)
|
||||
{
|
||||
return span.Start >= Start && span.End <= End;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether <paramref name="span"/> overlaps this span. Two spans are considered to overlap
|
||||
/// if they have positions in common and neither is empty. Empty spans do not overlap with any
|
||||
/// other span.
|
||||
/// </summary>
|
||||
/// <param name="span">
|
||||
/// The span to check.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the spans overlap, otherwise <c>false</c>.
|
||||
/// </returns>
|
||||
public bool OverlapsWith(TextSpan span)
|
||||
{
|
||||
var overlapStart = Math.Max(Start, span.Start);
|
||||
var overlapEnd = Math.Min(End, span.End);
|
||||
|
||||
return overlapStart < overlapEnd;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the overlap with the given span, or null if there is no overlap.
|
||||
/// </summary>
|
||||
/// <param name="span">
|
||||
/// The span to check.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The overlap of the spans, or null if the overlap is empty.
|
||||
/// </returns>
|
||||
public TextSpan? Overlap(TextSpan span)
|
||||
{
|
||||
var overlapStart = Math.Max(Start, span.Start);
|
||||
var overlapEnd = Math.Min(End, span.End);
|
||||
|
||||
return overlapStart < overlapEnd
|
||||
? FromBounds(overlapStart, overlapEnd)
|
||||
: (TextSpan?)null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether <paramref name="span"/> intersects this span. Two spans are considered to
|
||||
/// intersect if they have positions in common or the end of one span
|
||||
/// coincides with the start of the other span.
|
||||
/// </summary>
|
||||
/// <param name="span">
|
||||
/// The span to check.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the spans intersect, otherwise <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IntersectsWith(TextSpan span)
|
||||
{
|
||||
return span.Start <= End && span.End >= Start;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether <paramref name="position"/> intersects this span.
|
||||
/// A position is considered to intersect if it is between the start and
|
||||
/// end positions (inclusive) of this span.
|
||||
/// </summary>
|
||||
/// <param name="position">
|
||||
/// The position to check.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the position intersects, otherwise <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IntersectsWith(int position)
|
||||
{
|
||||
return unchecked((uint)(position - Start) <= (uint)Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the intersection with the given span, or null if there is no intersection.
|
||||
/// </summary>
|
||||
/// <param name="span">
|
||||
/// The span to check.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The intersection of the spans, or null if the intersection is empty.
|
||||
/// </returns>
|
||||
public TextSpan? Intersection(TextSpan span)
|
||||
{
|
||||
var intersectStart = Math.Max(Start, span.Start);
|
||||
var intersectEnd = Math.Min(End, span.End);
|
||||
|
||||
return intersectStart <= intersectEnd
|
||||
? FromBounds(intersectStart, intersectEnd)
|
||||
: (TextSpan?)null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="TextSpan"/> from <paramref name="start" /> and <paramref
|
||||
/// name="end"/> positions as opposed to a position and length.
|
||||
///
|
||||
/// The returned TextSpan contains the range with <paramref name="start"/> inclusive,
|
||||
/// and <paramref name="end"/> exclusive.
|
||||
/// </summary>
|
||||
public static TextSpan FromBounds(int start, int end)
|
||||
{
|
||||
if (start < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(start), "start must not be negative");
|
||||
}
|
||||
|
||||
if (end < start)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(end), "end must not be less than start");
|
||||
}
|
||||
|
||||
return new TextSpan(start, end - start);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if two instances of <see cref="TextSpan"/> are the same.
|
||||
/// </summary>
|
||||
public static bool operator ==(TextSpan left, TextSpan right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if two instances of <see cref="TextSpan"/> are different.
|
||||
/// </summary>
|
||||
public static bool operator !=(TextSpan left, TextSpan right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if current instance of <see cref="TextSpan"/> is equal to another.
|
||||
/// </summary>
|
||||
public bool Equals(TextSpan other)
|
||||
{
|
||||
return Start == other.Start && Length == other.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if current instance of <see cref="TextSpan"/> is equal to another.
|
||||
/// </summary>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is TextSpan && Equals((TextSpan)obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Produces a hash code for <see cref="TextSpan"/>.
|
||||
/// </summary>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var combiner = new HashCodeCombiner();
|
||||
combiner.Add(Start);
|
||||
combiner.Add(Length);
|
||||
|
||||
return combiner.CombinedHash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides a string representation for <see cref="TextSpan"/>.
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[{Start}..{End})";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares current instance of <see cref="TextSpan"/> with another.
|
||||
/// </summary>
|
||||
public int CompareTo(TextSpan other)
|
||||
{
|
||||
var diff = Start - other.Start;
|
||||
if (diff != 0)
|
||||
{
|
||||
return diff;
|
||||
}
|
||||
|
||||
return Length - other.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal class UnknownTokenSyntax : SyntaxToken
|
||||
{
|
||||
internal UnknownTokenSyntax(GreenNode green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
internal new InternalSyntax.UnknownTokenSyntax Green => (InternalSyntax.UnknownTokenSyntax)base.Green;
|
||||
|
||||
public string Value => Text;
|
||||
|
||||
internal override SyntaxToken WithLeadingTriviaCore(SyntaxNode trivia)
|
||||
{
|
||||
return new InternalSyntax.UnknownTokenSyntax(Text, trivia?.Green, GetTrailingTrivia().Node?.Green).CreateRed(Parent, Position) as UnknownTokenSyntax;
|
||||
}
|
||||
|
||||
internal override SyntaxToken WithTrailingTriviaCore(SyntaxNode trivia)
|
||||
{
|
||||
return new InternalSyntax.UnknownTokenSyntax(Text, GetLeadingTrivia().Node?.Green, trivia?.Green).CreateRed(Parent, Position) as UnknownTokenSyntax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||
{
|
||||
internal class WhitespaceTokenSyntax : SyntaxToken
|
||||
{
|
||||
internal WhitespaceTokenSyntax(GreenNode green, SyntaxNode parent, int position)
|
||||
: base(green, parent, position)
|
||||
{
|
||||
}
|
||||
|
||||
internal new InternalSyntax.WhitespaceTokenSyntax Green => (InternalSyntax.WhitespaceTokenSyntax)base.Green;
|
||||
|
||||
public string Value => Text;
|
||||
|
||||
internal override SyntaxToken WithLeadingTriviaCore(SyntaxNode trivia)
|
||||
{
|
||||
return new InternalSyntax.WhitespaceTokenSyntax(Text, trivia?.Green, GetTrailingTrivia().Node?.Green).CreateRed(Parent, Position) as WhitespaceTokenSyntax;
|
||||
}
|
||||
|
||||
internal override SyntaxToken WithTrailingTriviaCore(SyntaxNode trivia)
|
||||
{
|
||||
return new InternalSyntax.WhitespaceTokenSyntax(Text, GetLeadingTrivia().Node?.Green, trivia?.Green).CreateRed(Parent, Position) as WhitespaceTokenSyntax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,8 +19,8 @@ Directive block - Gen<Directive:{section;RazorBlock;Unrestricted} [RZ1006(16:0,1
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[p];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [Foo] - SpanEditHandler;Accepts:Any - (22:1,3) - Tokens:1
|
||||
HtmlTokenType.Text;[Foo];
|
||||
SyntaxKind.HtmlText - [Foo] - [22..25) - FullWidth: 3 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[Foo];
|
||||
Tag block - Gen<None> - 4 - (25:1,6)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (25:1,6) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -51,12 +51,13 @@ Markup block - Gen<None> - 130 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[p];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [This is extra] - SpanEditHandler;Accepts:Any - (113:5,3) - Tokens:5
|
||||
HtmlTokenType.Text;[This];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[is];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[extra];
|
||||
SyntaxKind.HtmlText - [This is extra] - [113..126) - FullWidth: 13 - Slots: 1
|
||||
SyntaxKind.List - [This is extra] - [113..126) - FullWidth: 13 - Slots: 5
|
||||
SyntaxKind.HtmlTextLiteralToken;[This];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[is];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[extra];
|
||||
Tag block - Gen<None> - 4 - (126:5,16)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (126:5,16) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -19,12 +19,13 @@ Directive block - Gen<Directive:{custom;RazorBlock;Unrestricted}> - 33 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[p];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [F{o}o] - SpanEditHandler;Accepts:Any - (22:0,22) - Tokens:5
|
||||
HtmlTokenType.Text;[F];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.Text;[o];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.Text;[o];
|
||||
SyntaxKind.HtmlText - [F{o}o] - [22..27) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.List - [F{o}o] - [22..27) - FullWidth: 5 - Slots: 5
|
||||
SyntaxKind.HtmlTextLiteralToken;[F];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.HtmlTextLiteralToken;[o];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.HtmlTextLiteralToken;[o];
|
||||
Tag block - Gen<None> - 4 - (27:0,27)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (27:0,27) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -19,12 +19,13 @@ Directive block - Gen<Directive:{section;RazorBlock;Unrestricted}> - 32 - (0:0,0
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[p];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [F{o}o] - SpanEditHandler;Accepts:Any - (21:0,21) - Tokens:5
|
||||
HtmlTokenType.Text;[F];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.Text;[o];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.Text;[o];
|
||||
SyntaxKind.HtmlText - [F{o}o] - [21..26) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.List - [F{o}o] - [21..26) - FullWidth: 5 - Slots: 5
|
||||
SyntaxKind.HtmlTextLiteralToken;[F];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.HtmlTextLiteralToken;[o];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.HtmlTextLiteralToken;[o];
|
||||
Tag block - Gen<None> - 4 - (26:0,26)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (26:0,26) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ Markup block - Gen<None> - 45 - (0:0,0)
|
|||
HtmlTokenType.RazorCommentTransition;[@];
|
||||
Markup span - Gen<None> - [LF] - SpanEditHandler;Accepts:Any - (37:5,2) - Tokens:1
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
Markup span - Gen<Markup> - [LF] - SpanEditHandler;Accepts:Any - (39:6,0) - Tokens:1
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [LF] - [39..41) - FullWidth: 2 - Slots: 1
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 4 - (41:7,0)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (41:7,0) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ Markup block - Gen<None> - 42 - (0:0,0)
|
|||
HtmlTokenType.RazorCommentStar;[*];
|
||||
Transition span - Gen<None> - [@] - SpanEditHandler;Accepts:None - (35:1,30) - Tokens:1
|
||||
HtmlTokenType.RazorCommentTransition;[@];
|
||||
Markup span - Gen<Markup> - [LF] - SpanEditHandler;Accepts:Any - (36:1,31) - Tokens:1
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [LF] - [36..38) - FullWidth: 2 - Slots: 1
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 4 - (38:2,0)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (38:2,0) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ Markup block - Gen<None> - 46 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[p];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [Foo] - SpanEditHandler;Accepts:Any - (36:7,3) - Tokens:1
|
||||
HtmlTokenType.Text;[Foo];
|
||||
SyntaxKind.HtmlText - [Foo] - [36..39) - FullWidth: 3 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[Foo];
|
||||
Tag block - Gen<None> - 4 - (39:7,6)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (39:7,6) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ Markup block - Gen<None> - 26 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[p];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [Foo] - SpanEditHandler;Accepts:Any - (17:0,17) - Tokens:1
|
||||
HtmlTokenType.Text;[Foo];
|
||||
SyntaxKind.HtmlText - [Foo] - [17..20) - FullWidth: 3 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[Foo];
|
||||
Tag block - Gen<None> - 4 - (20:0,20)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (20:0,20) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -22,10 +22,11 @@ Markup block - Gen<None> - 27 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[p];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [Foo{}] - SpanEditHandler;Accepts:Any - (18:0,18) - Tokens:3
|
||||
HtmlTokenType.Text;[Foo];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.Text;[}];
|
||||
SyntaxKind.HtmlText - [Foo{}] - [18..23) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.List - [Foo{}] - [18..23) - FullWidth: 5 - Slots: 3
|
||||
SyntaxKind.HtmlTextLiteralToken;[Foo];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
Tag block - Gen<None> - 4 - (23:0,23)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (23:0,23) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ Markup block - Gen<None> - 44 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[p];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [Foo] - SpanEditHandler;Accepts:Any - (33:0,33) - Tokens:1
|
||||
HtmlTokenType.Text;[Foo];
|
||||
SyntaxKind.HtmlText - [Foo] - [33..36) - FullWidth: 3 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[Foo];
|
||||
Tag block - Gen<None> - 4 - (36:0,36)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (36:0,36) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ Markup block - Gen<None> - 27 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[p];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [Foo] - SpanEditHandler;Accepts:Any - (18:0,18) - Tokens:1
|
||||
HtmlTokenType.Text;[Foo];
|
||||
SyntaxKind.HtmlText - [Foo] - [18..21) - FullWidth: 3 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[Foo];
|
||||
Tag block - Gen<None> - 4 - (21:0,21)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (21:0,21) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ Markup block - Gen<None> - 25 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[p];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [Foo] - SpanEditHandler;Accepts:Any - (16:0,16) - Tokens:1
|
||||
HtmlTokenType.Text;[Foo];
|
||||
SyntaxKind.HtmlText - [Foo] - [16..19) - FullWidth: 3 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[Foo];
|
||||
Tag block - Gen<None> - 4 - (19:0,19)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (19:0,19) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ Markup block - Gen<None> - 31 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[p];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [Foo] - SpanEditHandler;Accepts:Any - (22:0,22) - Tokens:1
|
||||
HtmlTokenType.Text;[Foo];
|
||||
SyntaxKind.HtmlText - [Foo] - [22..25) - FullWidth: 3 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[Foo];
|
||||
Tag block - Gen<None> - 4 - (25:0,25)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ Markup block - Gen<None> - 165 - (0:0,0)
|
|||
HtmlTokenType.ForwardSlash;[/];
|
||||
HtmlTokenType.Text;[div];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [LF] - SpanEditHandler;Accepts:Any - (33:0,33) - Tokens:1
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [LF] - [33..35) - FullWidth: 2 - Slots: 1
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 5 - (35:1,0)
|
||||
Markup span - Gen<Markup> - [<div>] - SpanEditHandler;Accepts:Any - (35:1,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -55,8 +55,8 @@ Markup block - Gen<None> - 165 - (0:0,0)
|
|||
HtmlTokenType.ForwardSlash;[/];
|
||||
HtmlTokenType.Text;[div];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [LF] - SpanEditHandler;Accepts:Any - (70:1,35) - Tokens:1
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [LF] - [70..72) - FullWidth: 2 - Slots: 1
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 5 - (72:2,0)
|
||||
Markup span - Gen<Markup> - [<div>] - SpanEditHandler;Accepts:Any - (72:2,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -86,8 +86,8 @@ Markup block - Gen<None> - 165 - (0:0,0)
|
|||
HtmlTokenType.ForwardSlash;[/];
|
||||
HtmlTokenType.Text;[div];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [LF] - SpanEditHandler;Accepts:Any - (109:2,37) - Tokens:1
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [LF] - [109..111) - FullWidth: 2 - Slots: 1
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 5 - (111:3,0)
|
||||
Markup span - Gen<Markup> - [<div>] - SpanEditHandler;Accepts:Any - (111:3,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -23,10 +23,11 @@ Markup block - Gen<None> - 39 - (0:0,0)
|
|||
HtmlTokenType.SingleQuote;['];
|
||||
Markup span - Gen<Markup> - [>] - SpanEditHandler;Accepts:Any - (22:0,22) - Tokens:1
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ Foo ] - SpanEditHandler;Accepts:Any - (23:0,23) - Tokens:3
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[Foo];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [ Foo ] - [23..28) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.List - [ Foo ] - [23..28) - FullWidth: 5 - Slots: 3
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[Foo];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<None> - 4 - (28:0,28)
|
||||
Markup span - Gen<Markup> - [</p>] - SpanEditHandler;Accepts:Any - (28:0,28) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -18,9 +18,10 @@ Markup block - Gen<None> - 31 - (0:0,0)
|
|||
CSharpTokenType.WhiteSpace;[ ];
|
||||
CSharpTokenType.LeftBrace;[{];
|
||||
CSharpTokenType.RightBrace;[}];
|
||||
Markup span - Gen<Markup> - [ Bar] - SpanEditHandler;Accepts:Any - (21:0,21) - Tokens:2
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[Bar];
|
||||
SyntaxKind.HtmlText - [ Bar] - [21..25) - FullWidth: 4 - Slots: 1
|
||||
SyntaxKind.List - [ Bar] - [21..25) - FullWidth: 4 - Slots: 2
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[Bar];
|
||||
Tag block - Gen<None> - 6 - (25:0,25)
|
||||
Markup span - Gen<Markup> - [</div>] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -15,10 +15,11 @@ Markup block - Gen<None> - 51 - (0:0,0)
|
|||
HtmlTokenType.DoubleQuote;["];
|
||||
Markup span - Gen<Markup> - [>] - SpanEditHandler;Accepts:Any - (38:0,38) - Tokens:1
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [Email me] - SpanEditHandler;Accepts:Any - (39:0,39) - Tokens:3
|
||||
HtmlTokenType.Text;[Email];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[me];
|
||||
SyntaxKind.HtmlText - [Email me] - [39..47) - FullWidth: 8 - Slots: 1
|
||||
SyntaxKind.List - [Email me] - [39..47) - FullWidth: 8 - Slots: 3
|
||||
SyntaxKind.HtmlTextLiteralToken;[Email];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[me];
|
||||
Tag block - Gen<None> - 4 - (47:0,47)
|
||||
Markup span - Gen<Markup> - [</a>] - SpanEditHandler;Accepts:Any - (47:0,47) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ Markup block - Gen<None> - 17 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[foo];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [${bar}] - SpanEditHandler;Accepts:Any - (5:0,5) - Tokens:1
|
||||
HtmlTokenType.Text;[${bar}];
|
||||
SyntaxKind.HtmlText - [${bar}] - [5..11) - FullWidth: 6 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[${bar}];
|
||||
Tag block - Gen<None> - 6 - (11:0,11)
|
||||
Markup span - Gen<Markup> - [</foo>] - SpanEditHandler;Accepts:Any - (11:0,11) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ Markup block - Gen<None> - 20 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[text];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [Foo] - SpanEditHandler;Accepts:Any - (10:0,10) - Tokens:1
|
||||
HtmlTokenType.Text;[Foo];
|
||||
SyntaxKind.HtmlText - [Foo] - [10..13) - FullWidth: 3 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[Foo];
|
||||
Tag block - Gen<None> - 7 - (13:0,13)
|
||||
Markup span - Gen<Markup> - [</text>] - SpanEditHandler;Accepts:Any - (13:0,13) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -12,20 +12,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (16:1,13) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [16..38) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [16..38) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 6 - (38:4,0)
|
||||
Markup span - Gen<Markup> - [<base>] - SpanEditHandler;Accepts:Any - (38:4,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -36,20 +37,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (51:4,13) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [51..73) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [51..73) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 4 - (73:7,0)
|
||||
Markup span - Gen<Markup> - [<br>] - SpanEditHandler;Accepts:Any - (73:7,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -60,20 +62,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (84:7,11) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [84..106) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [84..106) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 5 - (106:10,0)
|
||||
Markup span - Gen<Markup> - [<col>] - SpanEditHandler;Accepts:Any - (106:10,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -84,20 +87,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (118:10,12) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [118..140) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [118..140) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 9 - (140:13,0)
|
||||
Markup span - Gen<Markup> - [<command>] - SpanEditHandler;Accepts:Any - (140:13,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -108,20 +112,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (156:13,16) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [156..178) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [156..178) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 7 - (178:16,0)
|
||||
Markup span - Gen<Markup> - [<embed>] - SpanEditHandler;Accepts:Any - (178:16,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -132,20 +137,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (192:16,14) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [192..214) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [192..214) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 4 - (214:19,0)
|
||||
Markup span - Gen<Markup> - [<hr>] - SpanEditHandler;Accepts:Any - (214:19,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -156,20 +162,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (225:19,11) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [225..247) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [225..247) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 5 - (247:22,0)
|
||||
Markup span - Gen<Markup> - [<img>] - SpanEditHandler;Accepts:Any - (247:22,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -180,20 +187,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (259:22,12) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [259..281) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [259..281) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 7 - (281:25,0)
|
||||
Markup span - Gen<Markup> - [<input>] - SpanEditHandler;Accepts:Any - (281:25,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -204,20 +212,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (295:25,14) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [295..317) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [295..317) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 8 - (317:28,0)
|
||||
Markup span - Gen<Markup> - [<keygen>] - SpanEditHandler;Accepts:Any - (317:28,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -228,20 +237,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (332:28,15) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [332..354) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [332..354) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 6 - (354:31,0)
|
||||
Markup span - Gen<Markup> - [<link>] - SpanEditHandler;Accepts:Any - (354:31,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -252,20 +262,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (367:31,13) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [367..389) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [367..389) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 6 - (389:34,0)
|
||||
Markup span - Gen<Markup> - [<meta>] - SpanEditHandler;Accepts:Any - (389:34,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -276,20 +287,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (402:34,13) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [402..424) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [402..424) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 7 - (424:37,0)
|
||||
Markup span - Gen<Markup> - [<param>] - SpanEditHandler;Accepts:Any - (424:37,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -300,20 +312,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (438:37,14) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [438..460) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [438..460) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 8 - (460:40,0)
|
||||
Markup span - Gen<Markup> - [<source>] - SpanEditHandler;Accepts:Any - (460:40,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -324,20 +337,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (475:40,15) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [475..497) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [475..497) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 7 - (497:43,0)
|
||||
Markup span - Gen<Markup> - [<track>] - SpanEditHandler;Accepts:Any - (497:43,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -348,20 +362,21 @@ Markup block - Gen<None> - 564 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.Text;[other];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ var x = true;LF}LF{LF] - SpanEditHandler;Accepts:Any - (511:43,14) - Tokens:13
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[var];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[x];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Equals;[=];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[true;];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[}];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
HtmlTokenType.Text;[{];
|
||||
HtmlTokenType.NewLine;[LF];
|
||||
SyntaxKind.HtmlText - [ var x = true;LF}LF{LF] - [511..533) - FullWidth: 22 - Slots: 1
|
||||
SyntaxKind.List - [ var x = true;LF}LF{LF] - [511..533) - FullWidth: 22 - Slots: 13
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[var];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[x];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.Equals;[=];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[true;];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[}];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
SyntaxKind.HtmlTextLiteralToken;[{];
|
||||
SyntaxKind.NewLine;[LF];
|
||||
Tag block - Gen<None> - 5 - (533:46,0)
|
||||
Markup span - Gen<Markup> - [<wbr>] - SpanEditHandler;Accepts:Any - (533:46,0) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ Markup block - Gen<None> - 95 - (0:0,0)
|
|||
CSharpTokenType.WhiteSpace;[ ];
|
||||
CSharpTokenType.RightBrace;[}];
|
||||
CSharpTokenType.NewLine;[LF];
|
||||
Markup span - Gen<Markup> - [ ] - SpanEditHandler;Accepts:Any - (86:4,0) - Tokens:1
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [ ] - [86..90) - FullWidth: 4 - Slots: 1
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<None> - 5 - (90:4,4)
|
||||
Markup span - Gen<Markup> - [</ul>] - SpanEditHandler;Accepts:Any - (90:4,4) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@ Markup block - Gen<None> - 16 - (0:0,0)
|
|||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<None> - [@] - SpanEditHandler;Accepts:Any - (5:0,5) - Tokens:1
|
||||
HtmlTokenType.Transition;[@];
|
||||
Markup span - Gen<Markup> - [@bar] - SpanEditHandler;Accepts:Any - (6:0,6) - Tokens:2
|
||||
HtmlTokenType.Transition;[@];
|
||||
HtmlTokenType.Text;[bar];
|
||||
SyntaxKind.HtmlText - [@bar] - [6..10) - FullWidth: 4 - Slots: 1
|
||||
SyntaxKind.List - [@bar] - [6..10) - FullWidth: 4 - Slots: 2
|
||||
SyntaxKind.Transition;[@];
|
||||
SyntaxKind.HtmlTextLiteralToken;[bar];
|
||||
Tag block - Gen<None> - 6 - (10:0,10)
|
||||
Markup span - Gen<Markup> - [</foo>] - SpanEditHandler;Accepts:Any - (10:0,10) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -24,9 +24,10 @@ Markup block - Gen<None> - 33 - (0:0,0)
|
|||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<None> - [@] - SpanEditHandler;Accepts:Any - (20:0,20) - Tokens:1
|
||||
HtmlTokenType.Transition;[@];
|
||||
Markup span - Gen<Markup> - [@bar] - SpanEditHandler;Accepts:Any - (21:0,21) - Tokens:2
|
||||
HtmlTokenType.Transition;[@];
|
||||
HtmlTokenType.Text;[bar];
|
||||
SyntaxKind.HtmlText - [@bar] - [21..25) - FullWidth: 4 - Slots: 1
|
||||
SyntaxKind.List - [@bar] - [21..25) - FullWidth: 4 - Slots: 2
|
||||
SyntaxKind.Transition;[@];
|
||||
SyntaxKind.HtmlTextLiteralToken;[bar];
|
||||
Tag block - Gen<None> - 6 - (25:0,25)
|
||||
Markup span - Gen<Markup> - [</foo>] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ Markup block - Gen<None> - 127 - (0:0,0)
|
|||
CSharpTokenType.WhiteSpace;[ ];
|
||||
CSharpTokenType.RightBrace;[}];
|
||||
CSharpTokenType.NewLine;[LF];
|
||||
Markup span - Gen<Markup> - [ ] - SpanEditHandler;Accepts:Any - (115:5,0) - Tokens:1
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [ ] - [115..119) - FullWidth: 4 - Slots: 1
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<None> - 5 - (119:5,4)
|
||||
Markup span - Gen<Markup> - [</ul>] - SpanEditHandler;Accepts:Any - (119:5,4) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ Markup block - Gen<None> - 55 - (0:0,0)
|
|||
(click) - SingleQuotes
|
||||
Code span - Gen<Expr> - [doSomething()] - ImplicitExpressionEditHandler;Accepts:AnyExceptNewline;ImplicitExpression[ATD];K14 - (23:0,23) - Tokens:1
|
||||
HtmlTokenType.Text;[doSomething()];
|
||||
Markup span - Gen<Markup> - [Click Me] - SpanEditHandler;Accepts:Any - (38:0,38) - Tokens:3
|
||||
HtmlTokenType.Text;[Click];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[Me];
|
||||
SyntaxKind.HtmlText - [Click Me] - [38..46) - FullWidth: 8 - Slots: 1
|
||||
SyntaxKind.List - [Click Me] - [38..46) - FullWidth: 8 - Slots: 3
|
||||
SyntaxKind.HtmlTextLiteralToken;[Click];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[Me];
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ Markup block - Gen<None> - 56 - (0:0,0)
|
|||
(^click) - SingleQuotes
|
||||
Code span - Gen<Expr> - [doSomething()] - ImplicitExpressionEditHandler;Accepts:AnyExceptNewline;ImplicitExpression[ATD];K14 - (24:0,24) - Tokens:1
|
||||
HtmlTokenType.Text;[doSomething()];
|
||||
Markup span - Gen<Markup> - [Click Me] - SpanEditHandler;Accepts:Any - (39:0,39) - Tokens:3
|
||||
HtmlTokenType.Text;[Click];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[Me];
|
||||
SyntaxKind.HtmlText - [Click Me] - [39..47) - FullWidth: 8 - Slots: 1
|
||||
SyntaxKind.List - [Click Me] - [39..47) - FullWidth: 8 - Slots: 3
|
||||
SyntaxKind.HtmlTextLiteralToken;[Click];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[Me];
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ Markup block - Gen<None> - 16 - (0:0,0)
|
|||
HtmlTokenType.ForwardSlash;[/];
|
||||
HtmlTokenType.Text;[strong];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [ ] - SpanEditHandler;Accepts:Any - (11:0,11) - Tokens:1
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [ ] - [11..12) - FullWidth: 1 - Slots: 1
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<None> - 1 - (12:0,12)
|
||||
Markup span - Gen<Markup> - [<] - SpanEditHandler;Accepts:Any - (12:0,12) - Tokens:1
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@ Markup block - Gen<None> - 16 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
Tag block - Gen<TagHelper> - 14 - (2:0,2) - strong - strongtaghelper
|
||||
StartTagAndEndTag - <strong>
|
||||
Markup span - Gen<Markup> - [> ] - SpanEditHandler;Accepts:Any - (10:0,10) - Tokens:2
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [> ] - [10..12) - FullWidth: 2 - Slots: 1
|
||||
SyntaxKind.List - [> ] - [10..12) - FullWidth: 2 - Slots: 2
|
||||
SyntaxKind.CloseAngle;[>];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<None> - 1 - (12:0,12)
|
||||
Markup span - Gen<Markup> - [<] - SpanEditHandler;Accepts:Any - (12:0,12) - Tokens:1
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ Markup block - Gen<None> - 11 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
Tag block - Gen<TagHelper> - 9 - (2:0,2) - p - ptaghelper
|
||||
StartTagAndEndTag - <p> ... </p>
|
||||
Markup span - Gen<Markup> - [>>] - SpanEditHandler;Accepts:Any - (5:0,5) - Tokens:2
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
SyntaxKind.HtmlText - [>>] - [5..7) - FullWidth: 2 - Slots: 1
|
||||
SyntaxKind.List - [>>] - [5..7) - FullWidth: 2 - Slots: 2
|
||||
SyntaxKind.CloseAngle;[>];
|
||||
SyntaxKind.CloseAngle;[>];
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ Markup block - Gen<None> - 42 - (0:0,0)
|
|||
CSharpTokenType.Identifier;[DateTime];
|
||||
CSharpTokenType.Dot;[.];
|
||||
CSharpTokenType.Identifier;[Now];
|
||||
Markup span - Gen<Markup> - [ >] - SpanEditHandler;Accepts:Any - (36:0,36) - Tokens:2
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
SyntaxKind.HtmlText - [ >] - [36..38) - FullWidth: 2 - Slots: 1
|
||||
SyntaxKind.List - [ >] - [36..38) - FullWidth: 2 - Slots: 2
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.CloseAngle;[>];
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@ Markup block - Gen<None> - 13 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
Tag block - Gen<TagHelper> - 9 - (3:0,3) - p - ptaghelper
|
||||
StartTagAndEndTag - <p> ... </p>
|
||||
Markup span - Gen<Markup> - [/>] - SpanEditHandler;Accepts:Any - (6:0,6) - Tokens:2
|
||||
HtmlTokenType.ForwardSlash;[/];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
SyntaxKind.HtmlText - [/>] - [6..8) - FullWidth: 2 - Slots: 1
|
||||
SyntaxKind.List - [/>] - [6..8) - FullWidth: 2 - Slots: 2
|
||||
SyntaxKind.ForwardSlash;[/];
|
||||
SyntaxKind.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [>] - SpanEditHandler;Accepts:Any - (12:0,12) - Tokens:1
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
|
|
|
|||
|
|
@ -8,9 +8,10 @@ Markup block - Gen<None> - 21 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
Tag block - Gen<TagHelper> - 17 - (3:0,3) - p - ptaghelper
|
||||
StartTagAndEndTag - <p> ... </p>
|
||||
Markup span - Gen<Markup> - [/>] - SpanEditHandler;Accepts:Any - (6:0,6) - Tokens:2
|
||||
HtmlTokenType.ForwardSlash;[/];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
SyntaxKind.HtmlText - [/>] - [6..8) - FullWidth: 2 - Slots: 1
|
||||
SyntaxKind.List - [/>] - [6..8) - FullWidth: 2 - Slots: 2
|
||||
SyntaxKind.ForwardSlash;[/];
|
||||
SyntaxKind.CloseAngle;[>];
|
||||
Tag block - Gen<None> - 8 - (8:0,8)
|
||||
Markup span - Gen<Markup> - [<strong>] - SpanEditHandler;Accepts:Any - (8:0,8) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@ Markup block - Gen<None> - 34 - (0:0,0)
|
|||
CSharpTokenType.Identifier;[DateTime];
|
||||
CSharpTokenType.Dot;[.];
|
||||
CSharpTokenType.Identifier;[Now];
|
||||
Markup span - Gen<Markup> - [/>] - SpanEditHandler;Accepts:Any - (19:0,19) - Tokens:2
|
||||
HtmlTokenType.ForwardSlash;[/];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
SyntaxKind.HtmlText - [/>] - [19..21) - FullWidth: 2 - Slots: 1
|
||||
SyntaxKind.List - [/>] - [19..21) - FullWidth: 2 - Slots: 2
|
||||
SyntaxKind.ForwardSlash;[/];
|
||||
SyntaxKind.CloseAngle;[>];
|
||||
Tag block - Gen<None> - 8 - (21:0,21)
|
||||
Markup span - Gen<Markup> - [<strong>] - SpanEditHandler;Accepts:Any - (21:0,21) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ Markup block - Gen<None> - 52 - (0:0,0)
|
|||
HtmlTokenType.OpenAngle;[<];
|
||||
HtmlTokenType.ForwardSlash;[/];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
Markup span - Gen<Markup> - [/] - SpanEditHandler;Accepts:Any - (4:0,4) - Tokens:1
|
||||
HtmlTokenType.ForwardSlash;[/];
|
||||
SyntaxKind.HtmlText - [/] - [4..5) - FullWidth: 1 - Slots: 1
|
||||
SyntaxKind.ForwardSlash;[/];
|
||||
Tag block - Gen<None> - 4 - (5:0,5)
|
||||
Markup span - Gen<Markup> - [< >] - SpanEditHandler;Accepts:Any - (5:0,5) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -20,11 +20,12 @@ Markup block - Gen<None> - 52 - (0:0,0)
|
|||
CSharpTokenType.Identifier;[DateTime];
|
||||
CSharpTokenType.Dot;[.];
|
||||
CSharpTokenType.Identifier;[Now];
|
||||
Markup span - Gen<Markup> - [ / >] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:4
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.ForwardSlash;[/];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
SyntaxKind.HtmlText - [ / >] - [25..29) - FullWidth: 4 - Slots: 1
|
||||
SyntaxKind.List - [ / >] - [25..29) - FullWidth: 4 - Slots: 4
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.ForwardSlash;[/];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.CloseAngle;[>];
|
||||
Tag block - Gen<None> - 8 - (29:0,29)
|
||||
Markup span - Gen<Markup> - [<strong>] - SpanEditHandler;Accepts:Any - (29:0,29) - Tokens:3
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@ Markup block - Gen<None> - 42 - (0:0,0)
|
|||
HtmlTokenType.CloseAngle;[>];
|
||||
Tag block - Gen<TagHelper> - 37 - (5:0,5) - p - ptaghelper
|
||||
StartTagAndEndTag - <p>
|
||||
Markup span - Gen<Markup> - [Hello ] - SpanEditHandler;Accepts:Any - (8:0,8) - Tokens:2
|
||||
HtmlTokenType.Text;[Hello];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [Hello ] - [8..14) - FullWidth: 6 - Slots: 1
|
||||
SyntaxKind.List - [Hello ] - [8..14) - FullWidth: 6 - Slots: 2
|
||||
SyntaxKind.HtmlTextLiteralToken;[Hello];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<TagHelper> - 22 - (14:0,14) - strong - strongtaghelper
|
||||
StartTagAndEndTag - <strong> ... </strong>
|
||||
Markup span - Gen<Markup> - [World] - SpanEditHandler;Accepts:Any - (22:0,22) - Tokens:1
|
||||
HtmlTokenType.Text;[World];
|
||||
SyntaxKind.HtmlText - [World] - [22..27) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[World];
|
||||
Tag block - Gen<None> - 6 - (36:0,36)
|
||||
Markup span - Gen<Markup> - [</div>] - SpanEditHandler;Accepts:Any - (36:0,36) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@ Markup block - Gen<None> - 33 - (0:0,0)
|
|||
HtmlTokenType.CloseAngle;[>];
|
||||
Tag block - Gen<TagHelper> - 28 - (5:0,5) - p - ptaghelper
|
||||
StartTagAndEndTag - <p>
|
||||
Markup span - Gen<Markup> - [Hello ] - SpanEditHandler;Accepts:Any - (8:0,8) - Tokens:2
|
||||
HtmlTokenType.Text;[Hello];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [Hello ] - [8..14) - FullWidth: 6 - Slots: 1
|
||||
SyntaxKind.List - [Hello ] - [8..14) - FullWidth: 6 - Slots: 2
|
||||
SyntaxKind.HtmlTextLiteralToken;[Hello];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<TagHelper> - 19 - (14:0,14) - strong - strongtaghelper
|
||||
StartTagAndEndTag - <strong>
|
||||
Markup span - Gen<Markup> - [World] - SpanEditHandler;Accepts:Any - (22:0,22) - Tokens:1
|
||||
HtmlTokenType.Text;[World];
|
||||
SyntaxKind.HtmlText - [World] - [22..27) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[World];
|
||||
Tag block - Gen<None> - 6 - (27:0,27)
|
||||
Markup span - Gen<Markup> - [</div>] - SpanEditHandler;Accepts:Any - (27:0,27) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@ Markup block - Gen<None> - 52 - (0:0,0)
|
|||
class - DoubleQuotes
|
||||
Markup span - Gen<Markup> - [foo] - SpanEditHandler;Accepts:Any - (10:0,10) - Tokens:1
|
||||
HtmlTokenType.Text;[foo];
|
||||
Markup span - Gen<Markup> - [Hello ] - SpanEditHandler;Accepts:Any - (15:0,15) - Tokens:2
|
||||
HtmlTokenType.Text;[Hello];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [Hello ] - [15..21) - FullWidth: 6 - Slots: 1
|
||||
SyntaxKind.List - [Hello ] - [15..21) - FullWidth: 6 - Slots: 2
|
||||
SyntaxKind.HtmlTextLiteralToken;[Hello];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<TagHelper> - 31 - (21:0,21) - p - ptaghelper
|
||||
StartTagAndEndTag - <p style="color:red;"> ... </p>
|
||||
style - DoubleQuotes
|
||||
Markup span - Gen<Markup> - [color:red;] - SpanEditHandler;Accepts:Any - (31:0,31) - Tokens:1
|
||||
HtmlTokenType.Text;[color:red;];
|
||||
Markup span - Gen<Markup> - [World] - SpanEditHandler;Accepts:Any - (43:0,43) - Tokens:1
|
||||
HtmlTokenType.Text;[World];
|
||||
SyntaxKind.HtmlText - [World] - [43..48) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[World];
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ Markup block - Gen<None> - 62 - (0:0,0)
|
|||
CSharpTokenType.Identifier;[DateTime];
|
||||
CSharpTokenType.Dot;[.];
|
||||
CSharpTokenType.Identifier;[Now];
|
||||
Markup span - Gen<Markup> - [Hello World] - SpanEditHandler;Accepts:Any - (47:0,47) - Tokens:3
|
||||
HtmlTokenType.Text;[Hello];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[World];
|
||||
SyntaxKind.HtmlText - [Hello World] - [47..58) - FullWidth: 11 - Slots: 1
|
||||
SyntaxKind.List - [Hello World] - [47..58) - FullWidth: 11 - Slots: 3
|
||||
SyntaxKind.HtmlTextLiteralToken;[Hello];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[World];
|
||||
|
|
|
|||
|
|
@ -103,7 +103,8 @@ Markup block - Gen<None> - 164 - (0:0,0)
|
|||
CSharpTokenType.GreaterThan;[>];
|
||||
CSharpTokenType.RightParenthesis;[)];
|
||||
CSharpTokenType.Semicolon;[;];
|
||||
Markup span - Gen<Markup> - [Hello World] - SpanEditHandler;Accepts:Any - (149:0,149) - Tokens:3
|
||||
HtmlTokenType.Text;[Hello];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[World];
|
||||
SyntaxKind.HtmlText - [Hello World] - [149..160) - FullWidth: 11 - Slots: 1
|
||||
SyntaxKind.List - [Hello World] - [149..160) - FullWidth: 11 - Slots: 3
|
||||
SyntaxKind.HtmlTextLiteralToken;[Hello];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[World];
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ Markup block - Gen<None> - 69 - (0:0,0)
|
|||
CSharpTokenType.Identifier;[DateTime];
|
||||
CSharpTokenType.Dot;[.];
|
||||
CSharpTokenType.Identifier;[Now];
|
||||
Markup span - Gen<Markup> - [Hello] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:1
|
||||
HtmlTokenType.Text;[Hello];
|
||||
Markup span - Gen<Markup> - [ ] - SpanEditHandler;Accepts:Any - (34:0,34) - Tokens:1
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [Hello] - [25..30) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[Hello];
|
||||
SyntaxKind.HtmlText - [ ] - [34..35) - FullWidth: 1 - Slots: 1
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<TagHelper> - 34 - (35:0,35) - p - ptaghelper
|
||||
StartTagAndEndTag - <p style='@DateTime.Now'> ... </p>
|
||||
style - SingleQuotes
|
||||
|
|
@ -27,5 +27,5 @@ Markup block - Gen<None> - 69 - (0:0,0)
|
|||
CSharpTokenType.Identifier;[DateTime];
|
||||
CSharpTokenType.Dot;[.];
|
||||
CSharpTokenType.Identifier;[Now];
|
||||
Markup span - Gen<Markup> - [World] - SpanEditHandler;Accepts:Any - (60:0,60) - Tokens:1
|
||||
HtmlTokenType.Text;[World];
|
||||
SyntaxKind.HtmlText - [World] - [60..65) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[World];
|
||||
|
|
|
|||
|
|
@ -52,10 +52,10 @@ Markup block - Gen<None> - 171 - (0:0,0)
|
|||
CSharpTokenType.GreaterThan;[>];
|
||||
CSharpTokenType.RightParenthesis;[)];
|
||||
CSharpTokenType.Semicolon;[;];
|
||||
Markup span - Gen<Markup> - [Hello] - SpanEditHandler;Accepts:Any - (76:0,76) - Tokens:1
|
||||
HtmlTokenType.Text;[Hello];
|
||||
Markup span - Gen<Markup> - [ ] - SpanEditHandler;Accepts:Any - (85:0,85) - Tokens:1
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [Hello] - [76..81) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[Hello];
|
||||
SyntaxKind.HtmlText - [ ] - [85..86) - FullWidth: 1 - Slots: 1
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<TagHelper> - 85 - (86:0,86) - p - ptaghelper
|
||||
StartTagAndEndTag - <p style='@do { var foo = bar; <text>Foo</text> foo++; } while (foo<bar>);'> ... </p>
|
||||
style - SingleQuotes
|
||||
|
|
@ -109,5 +109,5 @@ Markup block - Gen<None> - 171 - (0:0,0)
|
|||
CSharpTokenType.GreaterThan;[>];
|
||||
CSharpTokenType.RightParenthesis;[)];
|
||||
CSharpTokenType.Semicolon;[;];
|
||||
Markup span - Gen<Markup> - [World] - SpanEditHandler;Accepts:Any - (162:0,162) - Tokens:1
|
||||
HtmlTokenType.Text;[World];
|
||||
SyntaxKind.HtmlText - [World] - [162..167) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[World];
|
||||
|
|
|
|||
|
|
@ -21,11 +21,12 @@ Markup block - Gen<None> - 122 - (0:0,0)
|
|||
CSharpTokenType.Identifier;[DateTime];
|
||||
CSharpTokenType.Dot;[.];
|
||||
CSharpTokenType.Identifier;[Now];
|
||||
Markup span - Gen<Markup> - [Hello World ] - SpanEditHandler;Accepts:Any - (47:0,47) - Tokens:4
|
||||
HtmlTokenType.Text;[Hello];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[World];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [Hello World ] - [47..59) - FullWidth: 12 - Slots: 1
|
||||
SyntaxKind.List - [Hello World ] - [47..59) - FullWidth: 12 - Slots: 4
|
||||
SyntaxKind.HtmlTextLiteralToken;[Hello];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[World];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<None> - 30 - (59:0,59)
|
||||
Markup span - Gen<Markup> - [<strong] - SpanEditHandler;Accepts:Any - (59:0,59) - Tokens:2
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
@ -48,14 +49,15 @@ Markup block - Gen<None> - 122 - (0:0,0)
|
|||
HtmlTokenType.DoubleQuote;["];
|
||||
Markup span - Gen<Markup> - [>] - SpanEditHandler;Accepts:Any - (88:0,88) - Tokens:1
|
||||
HtmlTokenType.CloseAngle;[>];
|
||||
Markup span - Gen<Markup> - [inside of strong tag] - SpanEditHandler;Accepts:Any - (89:0,89) - Tokens:7
|
||||
HtmlTokenType.Text;[inside];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[of];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[strong];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[tag];
|
||||
SyntaxKind.HtmlText - [inside of strong tag] - [89..109) - FullWidth: 20 - Slots: 1
|
||||
SyntaxKind.List - [inside of strong tag] - [89..109) - FullWidth: 20 - Slots: 7
|
||||
SyntaxKind.HtmlTextLiteralToken;[inside];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[of];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[strong];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[tag];
|
||||
Tag block - Gen<None> - 9 - (109:0,109)
|
||||
Markup span - Gen<Markup> - [</strong>] - SpanEditHandler;Accepts:Any - (109:0,109) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ Markup block - Gen<None> - 41 - (0:0,0)
|
|||
CSharpTokenType.Identifier;[DateTime];
|
||||
CSharpTokenType.Dot;[.];
|
||||
CSharpTokenType.Identifier;[Now];
|
||||
Markup span - Gen<Markup> - [ ] - SpanEditHandler;Accepts:Any - (20:0,20) - Tokens:1
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [ ] - [20..21) - FullWidth: 1 - Slots: 1
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<TagHelper> - 20 - (21:0,21) - p - ptaghelper
|
||||
StartTagAndEndTag - <p> ... </p>
|
||||
Expression block - Gen<Expr> - 13 - (24:0,24)
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ Markup block - Gen<None> - 131 - (0:0,0)
|
|||
CSharpTokenType.GreaterThan;[>];
|
||||
CSharpTokenType.RightParenthesis;[)];
|
||||
CSharpTokenType.Semicolon;[;];
|
||||
Markup span - Gen<Markup> - [ ] - SpanEditHandler;Accepts:Any - (65:0,65) - Tokens:1
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [ ] - [65..66) - FullWidth: 1 - Slots: 1
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<TagHelper> - 65 - (66:0,66) - p - ptaghelper
|
||||
StartTagAndEndTag - <p> ... </p>
|
||||
Statement block - Gen<None> - 58 - (69:0,69)
|
||||
|
|
|
|||
|
|
@ -28,11 +28,12 @@ Markup block - Gen<None> - 77 - (0:0,0)
|
|||
CSharpTokenType.Identifier;[DateTime];
|
||||
CSharpTokenType.Dot;[.];
|
||||
CSharpTokenType.Identifier;[Now];
|
||||
Markup span - Gen<Markup> - [ strong tag] - SpanEditHandler;Accepts:Any - (53:0,53) - Tokens:4
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[strong];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[tag];
|
||||
SyntaxKind.HtmlText - [ strong tag] - [53..64) - FullWidth: 11 - Slots: 1
|
||||
SyntaxKind.List - [ strong tag] - [53..64) - FullWidth: 11 - Slots: 4
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[strong];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[tag];
|
||||
Tag block - Gen<None> - 9 - (64:0,64)
|
||||
Markup span - Gen<Markup> - [</strong>] - SpanEditHandler;Accepts:Any - (64:0,64) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -96,11 +96,12 @@ Markup block - Gen<None> - 167 - (0:0,0)
|
|||
CSharpTokenType.GreaterThan;[>];
|
||||
CSharpTokenType.RightParenthesis;[)];
|
||||
CSharpTokenType.Semicolon;[;];
|
||||
Markup span - Gen<Markup> - [ strong tag] - SpanEditHandler;Accepts:Any - (143:0,143) - Tokens:4
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[strong];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[tag];
|
||||
SyntaxKind.HtmlText - [ strong tag] - [143..154) - FullWidth: 11 - Slots: 1
|
||||
SyntaxKind.List - [ strong tag] - [143..154) - FullWidth: 11 - Slots: 4
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[strong];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[tag];
|
||||
Tag block - Gen<None> - 9 - (154:0,154)
|
||||
Markup span - Gen<Markup> - [</strong>] - SpanEditHandler;Accepts:Any - (154:0,154) - Tokens:4
|
||||
HtmlTokenType.OpenAngle;[<];
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ Markup block - Gen<None> - 77 - (0:0,0)
|
|||
HtmlTokenType.Text;[;];
|
||||
Markup span - Gen<Markup> - [ ] - SpanEditHandler;Accepts:Any - (53:0,53) - Tokens:1
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
Markup span - Gen<Markup> - [Hello World] - SpanEditHandler;Accepts:Any - (62:0,62) - Tokens:3
|
||||
HtmlTokenType.Text;[Hello];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[World];
|
||||
SyntaxKind.HtmlText - [Hello World] - [62..73) - FullWidth: 11 - Slots: 1
|
||||
SyntaxKind.List - [Hello World] - [62..73) - FullWidth: 11 - Slots: 3
|
||||
SyntaxKind.HtmlTextLiteralToken;[Hello];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[World];
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ Markup block - Gen<None> - 73 - (0:0,0)
|
|||
HtmlTokenType.Text;[foo];
|
||||
Markup span - Gen<Markup> - [ ] - SpanEditHandler;Accepts:Any - (20:0,20) - Tokens:1
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
Markup span - Gen<Markup> - [Hello] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:1
|
||||
HtmlTokenType.Text;[Hello];
|
||||
Markup span - Gen<Markup> - [ ] - SpanEditHandler;Accepts:Any - (34:0,34) - Tokens:1
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [Hello] - [25..30) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[Hello];
|
||||
SyntaxKind.HtmlText - [ ] - [34..35) - FullWidth: 1 - Slots: 1
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<TagHelper> - 38 - (35:0,35) - p - ptaghelper
|
||||
StartTagAndEndTag - <p style=" color:red; " > ... </p>
|
||||
style - DoubleQuotes
|
||||
|
|
@ -21,5 +21,5 @@ Markup block - Gen<None> - 73 - (0:0,0)
|
|||
HtmlTokenType.Text;[color:red;];
|
||||
Markup span - Gen<Markup> - [ ] - SpanEditHandler;Accepts:Any - (60:0,60) - Tokens:1
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
Markup span - Gen<Markup> - [World] - SpanEditHandler;Accepts:Any - (64:0,64) - Tokens:1
|
||||
HtmlTokenType.Text;[World];
|
||||
SyntaxKind.HtmlText - [World] - [64..69) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[World];
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
Markup block - Gen<None> - 18 - (0:0,0)
|
||||
Tag block - Gen<TagHelper> - 18 - (0:0,0) - p - ptaghelper
|
||||
StartTagAndEndTag - <p> ... </p>
|
||||
Markup span - Gen<Markup> - [Hello World] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:3
|
||||
HtmlTokenType.Text;[Hello];
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
HtmlTokenType.Text;[World];
|
||||
SyntaxKind.HtmlText - [Hello World] - [3..14) - FullWidth: 11 - Slots: 1
|
||||
SyntaxKind.List - [Hello World] - [3..14) - FullWidth: 11 - Slots: 3
|
||||
SyntaxKind.HtmlTextLiteralToken;[Hello];
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
SyntaxKind.HtmlTextLiteralToken;[World];
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
Markup block - Gen<None> - 25 - (0:0,0)
|
||||
Tag block - Gen<TagHelper> - 12 - (0:0,0) - p - ptaghelper
|
||||
StartTagAndEndTag - <p> ... </p>
|
||||
Markup span - Gen<Markup> - [Hello] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:1
|
||||
HtmlTokenType.Text;[Hello];
|
||||
Markup span - Gen<Markup> - [ ] - SpanEditHandler;Accepts:Any - (12:0,12) - Tokens:1
|
||||
HtmlTokenType.WhiteSpace;[ ];
|
||||
SyntaxKind.HtmlText - [Hello] - [3..8) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[Hello];
|
||||
SyntaxKind.HtmlText - [ ] - [12..13) - FullWidth: 1 - Slots: 1
|
||||
SyntaxKind.Whitespace;[ ];
|
||||
Tag block - Gen<TagHelper> - 12 - (13:0,13) - p - ptaghelper
|
||||
StartTagAndEndTag - <p> ... </p>
|
||||
Markup span - Gen<Markup> - [World] - SpanEditHandler;Accepts:Any - (16:0,16) - Tokens:1
|
||||
HtmlTokenType.Text;[World];
|
||||
SyntaxKind.HtmlText - [World] - [16..21) - FullWidth: 5 - Slots: 1
|
||||
SyntaxKind.HtmlTextLiteralToken;[World];
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue