diff --git a/.travis.yml b/.travis.yml index e75fe73221..d56301c453 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ os: osx_image: xcode8.2 branches: only: - - dev + - master - /^release\/.*$/ - /^(.*\/)?ci-.*$/ before_install: diff --git a/.vsts-pipelines/builds/ci-internal.yml b/.vsts-pipelines/builds/ci-internal.yml index dc7b8a3cb9..c2c5336fd0 100644 --- a/.vsts-pipelines/builds/ci-internal.yml +++ b/.vsts-pipelines/builds/ci-internal.yml @@ -7,7 +7,7 @@ resources: - repository: buildtools type: git name: aspnet-BuildTools - ref: refs/heads/release/2.2 + ref: refs/heads/master phases: - template: .vsts-pipelines/templates/project-ci.yml@buildtools diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 64ff041d5c..eac4268e4c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ Contributing ====== -Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo. +Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/master/CONTRIBUTING.md) in the Home repo. diff --git a/build/dependencies.props b/build/dependencies.props index a81f4a3dec..cffc8e9cee 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -4,20 +4,20 @@ 0.10.13 - 2.2.0-preview1-20180807.2 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 + 3.0.0-alpha1-20180810.1 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 15.6.82 15.6.82 15.6.82 2.8.0 2.8.0 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 - 2.1.0 - 2.2.0-preview1-34967 - 2.2.0-preview1-34967 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-preview1-26810-02 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 2.0.9 2.1.2 2.2.0-preview1-26618-02 @@ -25,6 +25,7 @@ 15.0.26606 15.6.161-preview 15.6.161-preview + 15.8.519 7.10.6070 15.3.224 2.0.6142705 @@ -42,10 +43,10 @@ 4.7.49 2.0.3 11.0.2 - 1.1.92 - 4.5.0 + 1.3.23 + 4.6.0-preview1-26807-04 4.3.0 - 4.5.0 + 4.6.0-preview1-26807-04 9.0.1 2.9.0-beta4-62911-02 2.9.0-beta4-62911-02 diff --git a/build/repo.props b/build/repo.props index def34f0b6f..fef2fdc0eb 100644 --- a/build/repo.props +++ b/build/repo.props @@ -21,7 +21,6 @@ Internal.AspNetCore.Universe.Lineup - 2.2.0-* https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 29a57027f1..c53be3fca9 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:2.2.0-preview1-20180807.2 -commithash:11495dbd236104434e08cb1152fcb58cf2a20923 +version:3.0.0-alpha1-20180810.1 +commithash:45c32b4f020e14a9295be31866051a18d293309d diff --git a/korebuild.json b/korebuild.json index e9b03c2768..cb46ef120b 100644 --- a/korebuild.json +++ b/korebuild.json @@ -1,6 +1,6 @@ { - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.2/tools/korebuild.schema.json", - "channel": "release/2.2", + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json", + "channel": "master", "toolsets": { "visualstudio": { "required": false, diff --git a/run.ps1 b/run.ps1 index 3b27382468..34604c7175 100644 --- a/run.ps1 +++ b/run.ps1 @@ -52,8 +52,8 @@ in the file are overridden by command line parameters. Example config file: ```json { - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/dev/tools/korebuild.schema.json", - "channel": "dev", + "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json", + "channel": "master", "toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools" } ``` @@ -192,7 +192,7 @@ if (!$DotNetHome) { else { Join-Path $PSScriptRoot '.dotnet'} } -if (!$Channel) { $Channel = 'dev' } +if (!$Channel) { $Channel = 'master' } if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' } # Execute diff --git a/run.sh b/run.sh index 02aac15874..61f7a53385 100755 --- a/run.sh +++ b/run.sh @@ -248,7 +248,7 @@ if [ -f "$config_file" ]; then [ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source" fi -[ -z "$channel" ] && channel='dev' +[ -z "$channel" ] && channel='master' [ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' get_korebuild diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpToken.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpToken.cs index c928f0880e..02428c2691 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpToken.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpToken.cs @@ -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; diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlMarkupParser.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlMarkupParser.cs index cbf0c1021a..c1292b44bd 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlMarkupParser.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlMarkupParser.cs @@ -856,7 +856,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // Capture whitespace var whitespace = ReadWhile(token => token.Type == HtmlTokenType.WhiteSpace || token.Type == HtmlTokenType.NewLine); - if (At(HtmlTokenType.Transition)) + if (At(HtmlTokenType.Transition) || At(HtmlTokenType.RazorCommentTransition)) { // Transition outside of attribute value => Switch to recovery mode Accept(whitespace); @@ -931,7 +931,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy { // First, determine if this is a 'data-' attribute (since those can't use conditional attributes) var name = string.Concat(nameTokens.Select(s => s.Content)); - var attributeCanBeConditional = + var attributeCanBeConditional = Context.FeatureFlags.EXPERIMENTAL_AllowConditionalDataDashAttributes || !name.StartsWith("data-", StringComparison.OrdinalIgnoreCase); @@ -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 = '';" 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: '

' or '

' 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); diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlToken.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlToken.cs index 2d52ed14e2..9659d85360 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlToken.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/HtmlToken.cs @@ -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()); + } + } } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/IToken.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/IToken.cs index 2f8eb1214d..a57f9dbf4d 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/IToken.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/IToken.cs @@ -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; } } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/Span.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/Span.cs index fbf9f9f2c2..ec448d0dc4 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/Span.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/Span.cs @@ -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 (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(textResult.Node)); + } + + return null; + } } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/TokenBase.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/TokenBase.cs index 562a41f5bc..ade6bfc95c 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/TokenBase.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/TokenBase.cs @@ -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; - return other != null && + return obj is TokenBase other && string.Equals(Content, other.Content, StringComparison.Ordinal) && Type.Equals(other.Type); } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/TokenizerBackedParser.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/TokenizerBackedParser.cs index af5a08831f..f7b054ecff 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/TokenizerBackedParser.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/TokenizerBackedParser.cs @@ -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 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); diff --git a/src/Microsoft.AspNetCore.Razor.Language/Properties/AssemblyInfo.cs b/src/Microsoft.AspNetCore.Razor.Language/Properties/AssemblyInfo.cs index 7214d8baca..e47484c273 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Properties/AssemblyInfo.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Runtime.CompilerServices; +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Performance, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/ArrayElement.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/ArrayElement.cs new file mode 100644 index 0000000000..85345e657b --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/ArrayElement.cs @@ -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 + { + public T Value; + + public static implicit operator T(ArrayElement element) + { + return element.Value; + } + + //NOTE: there is no opposite conversion operator T -> ArrayElement + // + // 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)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[] MakeElementArray(T[] items) + { + if (items == null) + { + return null; + } + + var array = new ArrayElement[items.Length]; + for (var i = 0; i < items.Length; i++) + { + array[i].Value = items[i]; + } + + return array; + } + + public static T[] MakeArray(ArrayElement[] 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; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/GreenNode.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/GreenNode.cs new file mode 100644 index 0000000000..e90374ad2b --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/GreenNode.cs @@ -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(); + private static readonly SyntaxAnnotation[] EmptyAnnotations = Array.Empty(); + private static readonly ConditionalWeakTable DiagnosticsTable = + new ConditionalWeakTable(); + private static readonly ConditionalWeakTable AnnotationsTable = + new ConditionalWeakTable(); + + 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(); + 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 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 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 + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/HtmlNodeSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/HtmlNodeSyntax.cs new file mode 100644 index 0000000000..c247183c1d --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/HtmlNodeSyntax.cs @@ -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); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/HtmlTextSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/HtmlTextSyntax.cs new file mode 100644 index 0000000000..a28dc9bbdd --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/HtmlTextSyntax.cs @@ -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 TextTokens => new SyntaxList(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; + } + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/HtmlTextTokenSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/HtmlTextTokenSyntax.cs new file mode 100644 index 0000000000..9130b5c5d4 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/HtmlTextTokenSyntax.cs @@ -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; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/HtmlNodeSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/HtmlNodeSyntax.cs new file mode 100644 index 0000000000..4289dfa683 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/HtmlNodeSyntax.cs @@ -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); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/HtmlTextSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/HtmlTextSyntax.cs new file mode 100644 index 0000000000..57e3c4f113 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/HtmlTextSyntax.cs @@ -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 TextTokens => new SyntaxList(_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); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/HtmlTextTokenSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/HtmlTextTokenSyntax.cs new file mode 100644 index 0000000000..68d6eecd97 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/HtmlTextTokenSyntax.cs @@ -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); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/NewLineTokenSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/NewLineTokenSyntax.cs new file mode 100644 index 0000000000..97d47e9fb9 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/NewLineTokenSyntax.cs @@ -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); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/PunctuationSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/PunctuationSyntax.cs new file mode 100644 index 0000000000..0c2bb06b61 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/PunctuationSyntax.cs @@ -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); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxFactory.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxFactory.cs new file mode 100644 index 0000000000..a6f5ce2e1f --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxFactory.cs @@ -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 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); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxList.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxList.cs new file mode 100644 index 0000000000..cd6270b599 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxList.cs @@ -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[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[] 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[] 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[left.SlotCount + right.SlotCount]; + leftList.CopyTo(tmp, 0); + rightList.CopyTo(tmp, left.SlotCount); + return List(tmp); + } + else + { + var tmp = new ArrayElement[left.SlotCount + 1]; + leftList.CopyTo(tmp, 0); + tmp[left.SlotCount].Value = right; + return List(tmp); + } + } + else if (rightList != null) + { + var tmp = new ArrayElement[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[] 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[] 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[] children; + + internal WithManyChildrenBase(ArrayElement[] children) + { + this.children = children; + this.InitializeChildren(); + } + + internal WithManyChildrenBase(RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations, ArrayElement[] 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[] 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[] children) + : base(children) + { + } + + internal WithManyChildren(RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations, ArrayElement[] 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[] children) + : base(children) + { + _childOffsets = CalculateOffsets(children); + } + + internal WithLotsOfChildren(RazorDiagnostic[] diagnostics, SyntaxAnnotation[] annotations, ArrayElement[] children, int[] childOffsets) + : base(diagnostics, annotations, children) + { + _childOffsets = childOffsets; + } + + public override int GetSlotOffset(int index) + { + return _childOffsets[index]; + } + + /// + /// Find the slot that contains the given offset. + /// + /// The target offset. Must be between 0 and . + /// The slot index of the slot containing the given offset. + /// + /// This implementation uses a binary search to find the first slot that contains + /// the given offset. + /// + public override int FindSlotIndexContainingOffset(int offset) + { + Debug.Assert(offset >= 0 && offset < FullWidth); + return BinarySearchUpperBound(_childOffsets, offset) - 1; + } + + private static int[] CalculateOffsets(ArrayElement[] 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); + } + + /// + /// Search a sorted integer array for the target value in O(log N) time. + /// + /// The array of integers which must be sorted in ascending order. + /// The target value. + /// An index in the array pointing to the position where should be + /// inserted in order to maintain the sorted order. All values to the right of this position will be + /// strictly greater than . Note that this may return a position off the end + /// of the array if all elements are less than or equal to . + 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; + } + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxListBuilder.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxListBuilder.cs new file mode 100644 index 0000000000..fae8e718a7 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxListBuilder.cs @@ -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[] _nodes; + + public int Count { get; private set; } + + public SyntaxListBuilder(int size) + { + _nodes = new ArrayElement[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 list) + { + this.AddRange(list, 0, list.Count); + } + + public void AddRange(SyntaxList 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(SyntaxList list) where TNode : GreenNode + { + this.AddRange(list, 0, list.Count); + } + + public void AddRange(SyntaxList list, int offset, int length) where TNode : GreenNode + { + AddRange(new SyntaxList(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[Count]; + Array.Copy(_nodes, tmp, Count); + return SyntaxList.List(tmp); + } + } + + public SyntaxList ToList() + { + return new SyntaxList(ToListNode()); + } + + public SyntaxList ToList() where TNode : GreenNode + { + return new SyntaxList(ToListNode()); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxListBuilderOfT.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxListBuilderOfT.cs new file mode 100644 index 0000000000..65a11313f6 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxListBuilderOfT.cs @@ -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 where TNode : GreenNode + { + private readonly SyntaxListBuilder _builder; + + public SyntaxListBuilder(int size) + : this(new SyntaxListBuilder(size)) + { + } + + public static SyntaxListBuilder Create() + { + return new SyntaxListBuilder(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 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 nodes) + { + _builder.AddRange(nodes); + } + + public void AddRange(SyntaxList nodes, int offset, int length) + { + _builder.AddRange(nodes, offset, length); + } + + public bool Any(SyntaxKind kind) + { + return _builder.Any(kind); + } + + public SyntaxList ToList() + { + return _builder.ToList(); + } + + public GreenNode ToListNode() + { + return _builder.ToListNode(); + } + + public static implicit operator SyntaxListBuilder(SyntaxListBuilder builder) + { + return builder._builder; + } + + public static implicit operator SyntaxList(SyntaxListBuilder builder) + { + if (builder._builder != null) + { + return builder.ToList(); + } + + return default(SyntaxList); + } + + public SyntaxList ToList() where TDerived : GreenNode + { + return new SyntaxList(ToListNode()); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxListOfT.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxListOfT.cs new file mode 100644 index 0000000000..945781978d --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxListOfT.cs @@ -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 + 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 left, SyntaxList right) + { + return (left._node == right._node); + } + + public static bool operator !=(SyntaxList left, SyntaxList right) + { + return !(left._node == right._node); + } + + public override bool Equals(object obj) + { + return (obj is SyntaxList && (_node == ((SyntaxList)obj)._node)); + } + + public override int GetHashCode() + { + return _node != null ? _node.GetHashCode() : 0; + } + + public static implicit operator SyntaxList(TNode node) + { + return new SyntaxList(node); + } + + public static implicit operator SyntaxList(SyntaxList nodes) + { + return new SyntaxList(nodes._node); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxToken.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxToken.cs new file mode 100644 index 0000000000..d9167704b5 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxToken.cs @@ -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; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxTrivia.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxTrivia.cs new file mode 100644 index 0000000000..6618b20c69 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxTrivia.cs @@ -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); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxVisitor.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxVisitor.cs new file mode 100644 index 0000000000..5e54b752f3 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/SyntaxVisitor.cs @@ -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; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/UnknownTokenSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/UnknownTokenSyntax.cs new file mode 100644 index 0000000000..4c6cd4608b --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/UnknownTokenSyntax.cs @@ -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); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/WhitespaceTokenSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/WhitespaceTokenSyntax.cs new file mode 100644 index 0000000000..b576b60e3a --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/InternalSyntax/WhitespaceTokenSyntax.cs @@ -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); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/NewLineTokenSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/NewLineTokenSyntax.cs new file mode 100644 index 0000000000..d164f069e9 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/NewLineTokenSyntax.cs @@ -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; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/NodeFlags.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/NodeFlags.cs new file mode 100644 index 0000000000..5dd4850e58 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/NodeFlags.cs @@ -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, + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/ObjectPool.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/ObjectPool.cs new file mode 100644 index 0000000000..2df35b64ac --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/ObjectPool.cs @@ -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 +{ + /// + /// 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". + /// + internal class ObjectPool where T : class + { + private struct Element + { + internal T Value; + } + + /// + /// Not using because this file is linked into the (debugger) Formatter, + /// which does not have that type (since it compiles against .NET 2.0). + /// + 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 leakTrackers = new ConditionalWeakTable(); + + 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; + } + + /// + /// Produces an instance. + /// + /// + /// 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. + /// + 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; + } + + /// + /// Returns objects to the pool. + /// + /// + /// 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. + /// + 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; + } + } + } + + /// + /// 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. + /// + [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?"); + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/ParserState.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/ParserState.cs new file mode 100644 index 0000000000..adb81967dd --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/ParserState.cs @@ -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, + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/PunctuationSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/PunctuationSyntax.cs new file mode 100644 index 0000000000..0f25740ecd --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/PunctuationSyntax.cs @@ -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; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SpecializedCollections.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SpecializedCollections.cs new file mode 100644 index 0000000000..3e1094003f --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SpecializedCollections.cs @@ -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 EmptyEnumerator() + { + return Empty.Enumerator.Instance; + } + + public static IEnumerable EmptyEnumerable() + { + return Empty.List.Instance; + } + + public static ICollection EmptyCollection() + { + return Empty.List.Instance; + } + + public static IList EmptyList() + { + return Empty.List.Instance; + } + + public static IReadOnlyList EmptyReadOnlyList() + { + return Empty.List.Instance; + } + + private class Empty + { + internal class Enumerator : Enumerator, IEnumerator + { + public static new readonly IEnumerator Instance = new Enumerator(); + + 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 : IEnumerable + { + // 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 _enumerator = Enumerator.Instance; + + public IEnumerator GetEnumerator() + { + return _enumerator; + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + internal class Collection : Enumerable, ICollection + { + public static readonly ICollection Instance = new Collection(); + + 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 : Collection, IList, IReadOnlyList + { + public static readonly new List Instance = new List(); + + 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(); + } + } + } + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxAnnotation.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxAnnotation.cs new file mode 100644 index 0000000000..dbb72fb1ae --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxAnnotation.cs @@ -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 +{ + /// + /// 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. + /// + [DebuggerDisplay("{GetDebuggerDisplay(), nq}")] + internal sealed class SyntaxAnnotation : IEquatable + { + // 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(); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxKind.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxKind.cs new file mode 100644 index 0000000000..46dad28dee --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxKind.cs @@ -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, + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxList.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxList.cs new file mode 100644 index 0000000000..e57b65599f --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxList.cs @@ -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[] _children; + + internal WithManyChildren(InternalSyntax.SyntaxList green, SyntaxNode parent, int position) + : base(green, parent, position) + { + _children = new ArrayElement[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]; + } + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxListBuilder.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxListBuilder.cs new file mode 100644 index 0000000000..415b8352bb --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxListBuilder.cs @@ -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[] _nodes; + + public int Count { get; private set; } + + public SyntaxListBuilder(int size) + { + _nodes = new ArrayElement[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 list) + { + AddRange(list, 0, list.Count); + } + + public void AddRange(SyntaxList 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(SyntaxList list) where TNode : SyntaxNode + { + AddRange(list, 0, list.Count); + } + + public void AddRange(SyntaxList list, int offset, int count) where TNode : SyntaxNode + { + AddRange(new SyntaxList(list.Node), offset, count); + } + + private void Grow(int size) + { + var tmp = new ArrayElement[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[Count]; + for (var i = 0; i < Count; i++) + { + tmp[i].Value = _nodes[i].Value; + } + + return InternalSyntax.SyntaxList.List(tmp); + } + } + + public static implicit operator SyntaxList(SyntaxListBuilder builder) + { + if (builder == null) + { + return default(SyntaxList); + } + + return builder.ToList(); + } + + internal void RemoveLast() + { + Count -= 1; + _nodes[Count] = default(ArrayElement); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxListBuilderExtensions.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxListBuilderExtensions.cs new file mode 100644 index 0000000000..5b813c05b1 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxListBuilderExtensions.cs @@ -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 ToList(this SyntaxListBuilder builder) + { + if (builder == null || builder.Count == 0) + { + return default(SyntaxList); + } + + return new SyntaxList(builder.ToListNode().CreateRed()); + } + + public static SyntaxList ToList(this SyntaxListBuilder builder) + where TNode : SyntaxNode + { + if (builder == null || builder.Count == 0) + { + return new SyntaxList(); + } + + return new SyntaxList(builder.ToListNode().CreateRed()); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxListBuilderOfT.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxListBuilderOfT.cs new file mode 100644 index 0000000000..8fcd9f2b3a --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxListBuilderOfT.cs @@ -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 + where TNode : SyntaxNode + { + private readonly SyntaxListBuilder _builder; + + public SyntaxListBuilder(int size) + : this(new SyntaxListBuilder(size)) + { + } + + public static SyntaxListBuilder Create() + { + return new SyntaxListBuilder(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 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 nodes) + { + _builder.AddRange(nodes); + } + + public void AddRange(SyntaxList nodes, int offset, int length) + { + _builder.AddRange(nodes, offset, length); + } + + public bool Any(SyntaxKind kind) + { + return _builder.Any(kind); + } + + public SyntaxList ToList() + { + return _builder.ToList(); + } + + public static implicit operator SyntaxListBuilder(SyntaxListBuilder builder) + { + return builder._builder; + } + + public static implicit operator SyntaxList(SyntaxListBuilder builder) + { + if (builder._builder != null) + { + return builder.ToList(); + } + + return default(SyntaxList); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxListOfT.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxListOfT.cs new file mode 100644 index 0000000000..158e82859f --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxListOfT.cs @@ -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 : IReadOnlyList, IEquatable> + where TNode : SyntaxNode + { + public SyntaxList(SyntaxNode node) + { + Node = node; + } + + /// + /// Creates a singleton list of syntax nodes. + /// + /// The single element node. + public SyntaxList(TNode node) + : this((SyntaxNode)node) + { + } + + /// + /// Creates a list of syntax nodes. + /// + /// A sequence of element nodes. + public SyntaxList(IEnumerable nodes) + : this(CreateNode(nodes)) + { + } + + private static SyntaxNode CreateNode(IEnumerable nodes) + { + if (nodes == null) + { + return null; + } + + var builder = (nodes is ICollection collection) ? new SyntaxListBuilder(collection.Count) : SyntaxListBuilder.Create(); + + foreach (var node in nodes) + { + builder.Add(node); + } + + return builder.ToList().Node; + } + + internal SyntaxNode Node { get; } + + /// + /// The number of nodes in the list. + /// + public int Count + { + get + { + return Node == null ? 0 : (Node.IsList ? Node.SlotCount : 1); + } + } + + /// + /// Gets the node at the specified index. + /// + /// The zero-based index of the node to get or set. + /// The node at the specified index. + 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; + } + + /// + /// The absolute span of the list elements in characters, including the leading and trailing trivia of the first and last elements. + /// + public TextSpan FullSpan + { + get + { + if (Count == 0) + { + return default(TextSpan); + } + else + { + return TextSpan.FromBounds(this[0].FullSpan.Start, this[Count - 1].FullSpan.End); + } + } + } + + /// + /// The absolute span of the list elements in characters, not including the leading and trailing trivia of the first and last elements. + /// + public TextSpan Span + { + get + { + if (Count == 0) + { + return default(TextSpan); + } + else + { + return TextSpan.FromBounds(this[0].Span.Start, this[Count - 1].Span.End); + } + } + } + + /// + /// 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. + /// + /// + /// The string representation of the nodes in this list, not including + /// the first node's leading trivia and the last node's trailing trivia. + /// + public override string ToString() + { + return Node != null ? Node.ToString() : string.Empty; + } + + /// + /// 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. + /// + /// + /// The full string representation of the nodes in this list including + /// the first node's leading trivia and the last node's trailing trivia. + /// + public string ToFullString() + { + return Node != null ? Node.ToFullString() : string.Empty; + } + + /// + /// Creates a new list with the specified node added at the end. + /// + /// The node to add. + public SyntaxList Add(TNode node) + { + return Insert(Count, node); + } + + /// + /// Creates a new list with the specified nodes added at the end. + /// + /// The nodes to add. + public SyntaxList AddRange(IEnumerable nodes) + { + return InsertRange(Count, nodes); + } + + /// + /// Creates a new list with the specified node inserted at the index. + /// + /// The index to insert at. + /// The node to insert. + public SyntaxList Insert(int index, TNode node) + { + if (node == null) + { + throw new ArgumentNullException(nameof(node)); + } + + return InsertRange(index, new[] { node }); + } + + /// + /// Creates a new list with the specified nodes inserted at the index. + /// + /// The index to insert at. + /// The nodes to insert. + public SyntaxList InsertRange(int index, IEnumerable 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); + } + } + + /// + /// Creates a new list with the element at specified index removed. + /// + /// The index of the element to remove. + public SyntaxList RemoveAt(int index) + { + if (index < 0 || index > Count) + { + throw new ArgumentOutOfRangeException(nameof(index)); + } + + return Remove(this[index]); + } + + /// + /// Creates a new list with the element removed. + /// + /// The element to remove. + public SyntaxList Remove(TNode node) + { + return CreateList(this.Where(x => x != node).ToList()); + } + + /// + /// Creates a new list with the specified element replaced with the new node. + /// + /// The element to replace. + /// The new node. + public SyntaxList Replace(TNode nodeInList, TNode newNode) + { + return ReplaceRange(nodeInList, new[] { newNode }); + } + + /// + /// Creates a new list with the specified element replaced with new nodes. + /// + /// The element to replace. + /// The new nodes. + public SyntaxList ReplaceRange(TNode nodeInList, IEnumerable 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 CreateList(List items) + { + if (items.Count == 0) + { + return default(SyntaxList); + } + else + { + return CreateList(items[0].Green, items); + } + } + + static SyntaxList CreateList(GreenNode creator, List items) + { + if (items.Count == 0) + { + return default(SyntaxList); + } + + var newGreen = creator.CreateList(items.Select(n => n.Green)); + return new SyntaxList(newGreen.CreateRed()); + } + + /// + /// The first node in the list. + /// + public TNode First() + { + return this[0]; + } + + /// + /// The first node in the list or default if the list is empty. + /// + public TNode FirstOrDefault() + { + if (this.Any()) + { + return this[0]; + } + else + { + return null; + } + } + + /// + /// The last node in the list. + /// + public TNode Last() + { + return this[Count - 1]; + } + + /// + /// The last node in the list or default if the list is empty. + /// + public TNode LastOrDefault() + { + if (Any()) + { + return this[Count - 1]; + } + else + { + return null; + } + } + + /// + /// True if the list has at least one node. + /// + public bool Any() + { + Debug.Assert(Node == null || Count != 0); + return Node != null; + } + + // for debugging + private TNode[] Nodes + { + get { return this.ToArray(); } + } + + /// + /// Get's the enumerator for this list. + /// + public Enumerator GetEnumerator() + { + return new Enumerator(in this); + } + + IEnumerator IEnumerable.GetEnumerator() + { + if (this.Any()) + { + return new EnumeratorImpl(this); + } + + return SpecializedCollections.EmptyEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + if (this.Any()) + { + return new EnumeratorImpl(this); + } + + return SpecializedCollections.EmptyEnumerator(); + } + + public static bool operator ==(SyntaxList left, SyntaxList right) + { + return left.Node == right.Node; + } + + public static bool operator !=(SyntaxList left, SyntaxList right) + { + return left.Node != right.Node; + } + + public bool Equals(SyntaxList other) + { + return Node == other.Node; + } + + public override bool Equals(object obj) + { + return obj is SyntaxList && Equals((SyntaxList)obj); + } + + public override int GetHashCode() + { + return Node?.GetHashCode() ?? 0; + } + + public static implicit operator SyntaxList(SyntaxList nodes) + { + return new SyntaxList(nodes.Node); + } + + public static implicit operator SyntaxList(SyntaxList nodes) + { + return new SyntaxList(nodes.Node); + } + + /// + /// The index of the node in this list, or -1 if the node is not in the list. + /// + 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 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 predicate) + { + for (var i = Count - 1; i >= 0; i--) + { + if (predicate(this[i])) + { + return i; + } + } + + return -1; + } + + public struct Enumerator + { + private readonly SyntaxList _list; + private int _index; + + internal Enumerator(in SyntaxList 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 + { + private Enumerator _e; + + internal EnumeratorImpl(in SyntaxList 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(); + } + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxNode.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxNode.cs new file mode 100644 index 0000000000..d55504d46e --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxNode.cs @@ -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(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(); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxToken.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxToken.cs new file mode 100644 index 0000000000..d3ffa0096c --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxToken.cs @@ -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 trivia) + { + var greenList = trivia?.Select(t => t.Green); + return WithLeadingTriviaCore(Green.CreateList(greenList)?.CreateRed()); + } + + public SyntaxToken WithTrailingTrivia(IEnumerable 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; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxTrivia.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxTrivia.cs new file mode 100644 index 0000000000..c576fee3d0 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxTrivia.cs @@ -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; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxTriviaList.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxTriviaList.cs new file mode 100644 index 0000000000..2097e9391c --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxTriviaList.cs @@ -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, IReadOnlyList + { + 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; + } + + /// + /// Creates a list of trivia. + /// + /// An array of trivia. + public SyntaxTriviaList(params SyntaxTrivia[] trivias) + : this(CreateNode(trivias), 0, 0) + { + } + + /// + /// Creates a list of trivia. + /// + /// A sequence of trivia. + public SyntaxTriviaList(IEnumerable 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]; + } + + /// + /// Gets the trivia at the specified index. + /// + /// The zero-based index of the trivia to get. + /// The token at the specified index. + /// + /// is less than 0.-or- is equal to or greater than . + 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)); + } + } + + /// + /// The absolute span of the list elements in characters, including the leading and trailing trivia of the first and last elements. + /// + public TextSpan FullSpan + { + get + { + if (Node == null) + { + return default(TextSpan); + } + + return new TextSpan(Position, Node.FullWidth); + } + } + + /// + /// The absolute span of the list elements in characters, not including the leading and trailing trivia of the first and last elements. + /// + public TextSpan Span + { + get + { + if (Node == null) + { + return default(TextSpan); + } + + return TextSpan.FromBounds(Position + Node.Green.GetLeadingTriviaWidth(), + Position + Node.FullWidth - Node.Green.GetTrailingTriviaWidth()); + } + } + + /// + /// Returns the first trivia in the list. + /// + /// The first trivia in the list. + /// The list is empty. + public SyntaxTrivia First() + { + if (Any()) + { + return this[0]; + } + + throw new InvalidOperationException(); + } + + /// + /// Returns the last trivia in the list. + /// + /// The last trivia in the list. + /// The list is empty. + public SyntaxTrivia Last() + { + if (Any()) + { + return this[Count - 1]; + } + + throw new InvalidOperationException(); + } + + /// + /// Does this list have any items. + /// + public bool Any() + { + return Node != null; + } + + /// + /// Returns a list which contains all elements of in reversed order. + /// + /// which contains all elements of in reversed order + 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; + } + + /// + /// Creates a new with the specified trivia added to the end. + /// + /// The trivia to add. + public SyntaxTriviaList Add(SyntaxTrivia trivia) + { + return Insert(Count, trivia); + } + + /// + /// Creates a new with the specified trivia added to the end. + /// + /// The trivia to add. + public SyntaxTriviaList AddRange(IEnumerable trivia) + { + return InsertRange(Count, trivia); + } + + /// + /// Creates a new with the specified trivia inserted at the index. + /// + /// The index in the list to insert the trivia at. + /// The trivia to insert. + 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 s_builderPool = + new ObjectPool(() => 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); + } + } + + /// + /// Creates a new with the specified trivia inserted at the index. + /// + /// The index in the list to insert the trivia at. + /// The trivia to insert. + public SyntaxTriviaList InsertRange(int index, IEnumerable 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 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); + } + } + + /// + /// Creates a new with the element at the specified index removed. + /// + /// The index identifying the element to remove. + 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); + } + + /// + /// Creates a new with the specified element removed. + /// + /// The trivia element to remove. + public SyntaxTriviaList Remove(SyntaxTrivia triviaInList) + { + var index = IndexOf(triviaInList); + if (index >= 0 && index < Count) + { + return RemoveAt(index); + } + + return this; + } + + /// + /// Creates a new with the specified element replaced with new trivia. + /// + /// The trivia element to replace. + /// The trivia to replace the element with. + public SyntaxTriviaList Replace(SyntaxTrivia triviaInList, SyntaxTrivia newTrivia) + { + if (newTrivia == default(SyntaxTrivia)) + { + throw new ArgumentOutOfRangeException(nameof(newTrivia)); + } + + return ReplaceRange(triviaInList, new[] { newTrivia }); + } + + /// + /// Creates a new with the specified element replaced with new trivia. + /// + /// The trivia element to replace. + /// The trivia to replace the element with. + public SyntaxTriviaList ReplaceRange(SyntaxTrivia triviaInList, IEnumerable 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 IEnumerable.GetEnumerator() + { + if (Node == null) + { + return SpecializedCollections.EmptyEnumerator(); + } + + return new EnumeratorImpl(this); + } + + IEnumerator IEnumerable.GetEnumerator() + { + if (Node == null) + { + return SpecializedCollections.EmptyEnumerator(); + } + + return new EnumeratorImpl(this); + } + + /// + /// get the green node at the specific slot + /// + 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; + } + + /// + /// Copy number of items starting at from this list into starting at . + /// + 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); + } + + /// + /// Reversed enumerable. + /// + public struct Reversed : IEnumerable, IEquatable + { + private SyntaxTriviaList _list; + + public Reversed(in SyntaxTriviaList list) + { + _list = list; + } + + public Enumerator GetEnumerator() + { + return new Enumerator(in _list); + } + + IEnumerator IEnumerable.GetEnumerator() + { + if (_list.Count == 0) + { + return SpecializedCollections.EmptyEnumerator(); + } + + return new ReversedEnumeratorImpl(in _list); + } + + IEnumerator + IEnumerable.GetEnumerator() + { + if (_list.Count == 0) + { + return SpecializedCollections.EmptyEnumerator(); + } + + 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 + { + 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 + { + 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() + { + } + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxTriviaListBuilder.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxTriviaListBuilder.cs new file mode 100644 index 0000000000..aa0a8caaec --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxTriviaListBuilder.cs @@ -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 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 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[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); + } + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxVisitor.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxVisitor.cs new file mode 100644 index 0000000000..08d833e515 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/SyntaxVisitor.cs @@ -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; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/TextSpan.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/TextSpan.cs new file mode 100644 index 0000000000..e80562b01b --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/TextSpan.cs @@ -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 +{ + /// + /// 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. + /// + internal readonly struct TextSpan : IEquatable, IComparable + { + /// + /// Creates a TextSpan instance beginning with the position Start and having the Length + /// specified with . + /// + 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; + } + + /// + /// Start point of the span. + /// + public int Start { get; } + + /// + /// End of the span. + /// + public int End => Start + Length; + + /// + /// Length of the span. + /// + public int Length { get; } + + /// + /// Determines whether or not the span is empty. + /// + public bool IsEmpty => Length == 0; + + /// + /// Determines whether the position lies within the span. + /// + /// + /// The position to check. + /// + /// + /// true if the position is greater than or equal to Start and strictly less + /// than End, otherwise false. + /// + public bool Contains(int position) + { + return unchecked((uint)(position - Start) < (uint)Length); + } + + /// + /// Determines whether falls completely within this span. + /// + /// + /// The span to check. + /// + /// + /// true if the specified span falls completely within this span, otherwise false. + /// + public bool Contains(TextSpan span) + { + return span.Start >= Start && span.End <= End; + } + + /// + /// Determines whether 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. + /// + /// + /// The span to check. + /// + /// + /// true if the spans overlap, otherwise false. + /// + public bool OverlapsWith(TextSpan span) + { + var overlapStart = Math.Max(Start, span.Start); + var overlapEnd = Math.Min(End, span.End); + + return overlapStart < overlapEnd; + } + + /// + /// Returns the overlap with the given span, or null if there is no overlap. + /// + /// + /// The span to check. + /// + /// + /// The overlap of the spans, or null if the overlap is empty. + /// + 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; + } + + /// + /// Determines whether 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. + /// + /// + /// The span to check. + /// + /// + /// true if the spans intersect, otherwise false. + /// + public bool IntersectsWith(TextSpan span) + { + return span.Start <= End && span.End >= Start; + } + + /// + /// Determines whether intersects this span. + /// A position is considered to intersect if it is between the start and + /// end positions (inclusive) of this span. + /// + /// + /// The position to check. + /// + /// + /// true if the position intersects, otherwise false. + /// + public bool IntersectsWith(int position) + { + return unchecked((uint)(position - Start) <= (uint)Length); + } + + /// + /// Returns the intersection with the given span, or null if there is no intersection. + /// + /// + /// The span to check. + /// + /// + /// The intersection of the spans, or null if the intersection is empty. + /// + 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; + } + + /// + /// Creates a new from and positions as opposed to a position and length. + /// + /// The returned TextSpan contains the range with inclusive, + /// and exclusive. + /// + 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); + } + + /// + /// Determines if two instances of are the same. + /// + public static bool operator ==(TextSpan left, TextSpan right) + { + return left.Equals(right); + } + + /// + /// Determines if two instances of are different. + /// + public static bool operator !=(TextSpan left, TextSpan right) + { + return !left.Equals(right); + } + + /// + /// Determines if current instance of is equal to another. + /// + public bool Equals(TextSpan other) + { + return Start == other.Start && Length == other.Length; + } + + /// + /// Determines if current instance of is equal to another. + /// + public override bool Equals(object obj) + { + return obj is TextSpan && Equals((TextSpan)obj); + } + + /// + /// Produces a hash code for . + /// + public override int GetHashCode() + { + var combiner = new HashCodeCombiner(); + combiner.Add(Start); + combiner.Add(Length); + + return combiner.CombinedHash; + } + + /// + /// Provides a string representation for . + /// + public override string ToString() + { + return $"[{Start}..{End})"; + } + + /// + /// Compares current instance of with another. + /// + public int CompareTo(TextSpan other) + { + var diff = Start - other.Start; + if (diff != 0) + { + return diff; + } + + return Length - other.Length; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/UnknownTokenSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/UnknownTokenSyntax.cs new file mode 100644 index 0000000000..238b36d1af --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/UnknownTokenSyntax.cs @@ -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; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Syntax/WhitespaceTokenSyntax.cs b/src/Microsoft.AspNetCore.Razor.Language/Syntax/WhitespaceTokenSyntax.cs new file mode 100644 index 0000000000..5a8222f802 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/Syntax/WhitespaceTokenSyntax.cs @@ -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; + } + } +} diff --git a/src/Microsoft.CodeAnalysis.Razor.Workspaces/Properties/AssemblyInfo.cs b/src/Microsoft.CodeAnalysis.Razor.Workspaces/Properties/AssemblyInfo.cs index fefb5cd1de..36e4a39988 100644 --- a/src/Microsoft.CodeAnalysis.Razor.Workspaces/Properties/AssemblyInfo.cs +++ b/src/Microsoft.CodeAnalysis.Razor.Workspaces/Properties/AssemblyInfo.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Runtime.CompilerServices; +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.LiveShare.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.LiveShare.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Performance, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/src/Microsoft.CodeAnalysis.Razor/Properties/AssemblyInfo.cs b/src/Microsoft.CodeAnalysis.Razor/Properties/AssemblyInfo.cs index 0de18b91dc..b19b6cc23a 100644 --- a/src/Microsoft.CodeAnalysis.Razor/Properties/AssemblyInfo.cs +++ b/src/Microsoft.CodeAnalysis.Razor/Properties/AssemblyInfo.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Runtime.CompilerServices; - +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.LiveShare.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.LiveShare.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/src/Microsoft.VisualStudio.Editor.Razor/DefaultRazorCompletionFactsService.cs b/src/Microsoft.VisualStudio.Editor.Razor/DefaultRazorCompletionFactsService.cs new file mode 100644 index 0000000000..57ac8ddb8d --- /dev/null +++ b/src/Microsoft.VisualStudio.Editor.Razor/DefaultRazorCompletionFactsService.cs @@ -0,0 +1,98 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Legacy; + +namespace Microsoft.VisualStudio.Editor.Razor +{ + [System.Composition.Shared] + [Export(typeof(RazorCompletionFactsService))] + internal class DefaultRazorCompletionFactsService : RazorCompletionFactsService + { + private static readonly IEnumerable DefaultDirectives = new[] + { + CSharpCodeParser.AddTagHelperDirectiveDescriptor, + CSharpCodeParser.RemoveTagHelperDirectiveDescriptor, + CSharpCodeParser.TagHelperPrefixDirectiveDescriptor, + }; + + public override IReadOnlyList GetCompletionItems(RazorSyntaxTree syntaxTree, SourceSpan location) + { + var completionItems = new List(); + + if (AtDirectiveCompletionPoint(syntaxTree, location)) + { + var directiveCompletions = GetDirectiveCompletionItems(syntaxTree); + completionItems.AddRange(directiveCompletions); + } + + return completionItems; + } + + // Internal for testing + internal static List GetDirectiveCompletionItems(RazorSyntaxTree syntaxTree) + { + var directives = syntaxTree.Options.Directives.Concat(DefaultDirectives); + var completionItems = new List(); + foreach (var directive in directives) + { + var completionDisplayText = directive.DisplayName ?? directive.Directive; + var completionItem = new RazorCompletionItem( + completionDisplayText, + directive.Directive, + directive.Description, + RazorCompletionItemKind.Directive); + completionItems.Add(completionItem); + } + + return completionItems; + } + + // Internal for testing + internal static bool AtDirectiveCompletionPoint(RazorSyntaxTree syntaxTree, SourceSpan location) + { + if (syntaxTree == null) + { + return false; + } + + var change = new SourceChange(location, string.Empty); + var owner = syntaxTree.Root.LocateOwner(change); + + if (owner == null) + { + return false; + } + + if (owner.ChunkGenerator is ExpressionChunkGenerator && + owner.Tokens.All(IsDirectiveCompletableToken) && + // Do not provide IntelliSense for explicit expressions. Explicit expressions will usually look like: + // [@] [(] [DateTime.Now] [)] + owner.Parent?.Children.Count > 1 && + owner.Parent.Children[1] == owner) + { + return true; + } + + return false; + } + + // Internal for testing + internal static bool IsDirectiveCompletableToken(IToken token) + { + if (!(token is CSharpToken csharpToken)) + { + return false; + } + + return csharpToken.Type == CSharpTokenType.Identifier || + // Marker symbol + csharpToken.Type == CSharpTokenType.Unknown; + } + } +} diff --git a/src/Microsoft.VisualStudio.Editor.Razor/Microsoft.VisualStudio.Editor.Razor.csproj b/src/Microsoft.VisualStudio.Editor.Razor/Microsoft.VisualStudio.Editor.Razor.csproj index aa50d39965..0022ff4c94 100644 --- a/src/Microsoft.VisualStudio.Editor.Razor/Microsoft.VisualStudio.Editor.Razor.csproj +++ b/src/Microsoft.VisualStudio.Editor.Razor/Microsoft.VisualStudio.Editor.Razor.csproj @@ -9,7 +9,9 @@ - + + + diff --git a/src/Microsoft.VisualStudio.Editor.Razor/Properties/AssemblyInfo.cs b/src/Microsoft.VisualStudio.Editor.Razor/Properties/AssemblyInfo.cs index 47ff95c911..b862d878ba 100644 --- a/src/Microsoft.VisualStudio.Editor.Razor/Properties/AssemblyInfo.cs +++ b/src/Microsoft.VisualStudio.Editor.Razor/Properties/AssemblyInfo.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Runtime.CompilerServices; +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.LanguageServer.StrongNamed, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.LiveShare.Razor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.LiveShare.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/src/Microsoft.VisualStudio.Editor.Razor/RazorCompletionFactsService.cs b/src/Microsoft.VisualStudio.Editor.Razor/RazorCompletionFactsService.cs new file mode 100644 index 0000000000..2995b49007 --- /dev/null +++ b/src/Microsoft.VisualStudio.Editor.Razor/RazorCompletionFactsService.cs @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Microsoft.AspNetCore.Razor.Language; + +namespace Microsoft.VisualStudio.Editor.Razor +{ + public abstract class RazorCompletionFactsService + { + public abstract IReadOnlyList GetCompletionItems(RazorSyntaxTree syntaxTree, SourceSpan location); + } +} diff --git a/src/Microsoft.VisualStudio.Editor.Razor/RazorCompletionItem.cs b/src/Microsoft.VisualStudio.Editor.Razor/RazorCompletionItem.cs new file mode 100644 index 0000000000..6b88af94f3 --- /dev/null +++ b/src/Microsoft.VisualStudio.Editor.Razor/RazorCompletionItem.cs @@ -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. + +using System; + +namespace Microsoft.VisualStudio.Editor.Razor +{ + public sealed class RazorCompletionItem + { + public RazorCompletionItem( + string displayText, + string insertText, + string description, + RazorCompletionItemKind kind) + { + if (displayText == null) + { + throw new ArgumentNullException(nameof(displayText)); + } + + if (insertText == null) + { + throw new ArgumentNullException(nameof(insertText)); + } + + if (description == null) + { + throw new ArgumentNullException(nameof(description)); + } + + DisplayText = displayText; + InsertText = insertText; + Description = description; + Kind = kind; + } + + public string DisplayText { get; } + + public string InsertText { get; } + + public string Description { get; } + + public RazorCompletionItemKind Kind { get; } + } +} diff --git a/src/Microsoft.VisualStudio.Editor.Razor/RazorCompletionItemKind.cs b/src/Microsoft.VisualStudio.Editor.Razor/RazorCompletionItemKind.cs new file mode 100644 index 0000000000..89ed05205e --- /dev/null +++ b/src/Microsoft.VisualStudio.Editor.Razor/RazorCompletionItemKind.cs @@ -0,0 +1,10 @@ +// 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.VisualStudio.Editor.Razor +{ + public enum RazorCompletionItemKind + { + Directive + } +} diff --git a/src/Microsoft.VisualStudio.Editor.Razor/RazorDirectiveCompletionProvider.cs b/src/Microsoft.VisualStudio.Editor.Razor/RazorDirectiveCompletionProvider.cs index 6a2d017716..607270c978 100644 --- a/src/Microsoft.VisualStudio.Editor.Razor/RazorDirectiveCompletionProvider.cs +++ b/src/Microsoft.VisualStudio.Editor.Razor/RazorDirectiveCompletionProvider.cs @@ -13,9 +13,9 @@ using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Legacy; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Completion; -using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Tags; using Microsoft.CodeAnalysis.Text; +using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Projection; @@ -36,16 +36,41 @@ namespace Microsoft.VisualStudio.Editor.Razor CSharpCodeParser.TagHelperPrefixDirectiveDescriptor, }; private readonly Lazy _codeDocumentProvider; + private readonly Lazy _completionFactsService; + private readonly IAsyncCompletionBroker _asyncCompletionBroker; + private readonly RazorTextBufferProvider _textBufferProvider; [ImportingConstructor] - public RazorDirectiveCompletionProvider([Import(typeof(RazorCodeDocumentProvider))] Lazy codeDocumentProvider) + public RazorDirectiveCompletionProvider( + [Import(typeof(RazorCodeDocumentProvider))] Lazy codeDocumentProvider, + [Import(typeof(RazorCompletionFactsService))] Lazy completionFactsService, + IAsyncCompletionBroker asyncCompletionBroker, + RazorTextBufferProvider textBufferProvider) { if (codeDocumentProvider == null) { throw new ArgumentNullException(nameof(codeDocumentProvider)); } + if (completionFactsService == null) + { + throw new ArgumentNullException(nameof(completionFactsService)); + } + + if (asyncCompletionBroker == null) + { + throw new ArgumentNullException(nameof(asyncCompletionBroker)); + } + + if (textBufferProvider == null) + { + throw new ArgumentNullException(nameof(textBufferProvider)); + } + _codeDocumentProvider = codeDocumentProvider; + _completionFactsService = completionFactsService; + _asyncCompletionBroker = asyncCompletionBroker; + _textBufferProvider = textBufferProvider; } public override Task GetDescriptionAsync(Document document, CompletionItem item, CancellationToken cancellationToken) @@ -86,6 +111,13 @@ namespace Microsoft.VisualStudio.Editor.Razor return Task.CompletedTask; } + if (!_textBufferProvider.TryGetFromDocument(context.Document, out var textBuffer) || + !_asyncCompletionBroker.IsCompletionSupported(textBuffer.ContentType)) + { + // Completion is not supported. + return Task.CompletedTask; + } + var result = AddCompletionItems(context); return result; @@ -109,70 +141,41 @@ namespace Microsoft.VisualStudio.Editor.Razor return Task.CompletedTask; } - if (!AtDirectiveCompletionPoint(syntaxTree, context)) + if (!TryGetRazorSnapshotPoint(context, out var razorSnapshotPoint)) { - // Can't have a valid directive at the current location. + // Could not find associated Razor location. return Task.CompletedTask; } - var completionItems = GetCompletionItems(syntaxTree); - context.AddItems(completionItems); + var location = new SourceSpan(razorSnapshotPoint.Position, 0); + var razorCompletionItems = _completionFactsService.Value.GetCompletionItems(syntaxTree, location); - return Task.CompletedTask; - } - - // Internal virtual for testing - internal virtual IEnumerable GetCompletionItems(RazorSyntaxTree syntaxTree) - { - var directives = syntaxTree.Options.Directives.Concat(DefaultDirectives); - var completionItems = new List(); - foreach (var directive in directives) + foreach (var razorCompletionItem in razorCompletionItems) { - var propertyDictionary = new Dictionary(StringComparer.Ordinal); - - if (!string.IsNullOrEmpty(directive.Description)) + if (razorCompletionItem.Kind != RazorCompletionItemKind.Directive) { - propertyDictionary[DescriptionKey] = directive.Description; + // Don't support any other types of completion kinds other than directives. + continue; + } + + var propertyDictionary = new Dictionary(StringComparer.Ordinal); + if (!string.IsNullOrEmpty(razorCompletionItem.Description)) + { + propertyDictionary[DescriptionKey] = razorCompletionItem.Description; } var completionItem = CompletionItem.Create( - directive.Directive, + razorCompletionItem.InsertText, // This groups all Razor directives together sortText: "_RazorDirective_", rules: CompletionItemRules.Create(formatOnCommit: false), tags: ImmutableArray.Create(WellKnownTags.Intrinsic), properties: propertyDictionary.ToImmutableDictionary()); - completionItems.Add(completionItem); + + context.AddItem(completionItem); } - return completionItems; - } - - // Internal for testing - internal bool AtDirectiveCompletionPoint(RazorSyntaxTree syntaxTree, CompletionContext context) - { - if (TryGetRazorSnapshotPoint(context, out var razorSnapshotPoint)) - { - var change = new SourceChange(razorSnapshotPoint.Position, 0, string.Empty); - var owner = syntaxTree.Root.LocateOwner(change); - - if (owner == null) - { - return false; - } - - if (owner.ChunkGenerator is ExpressionChunkGenerator && - owner.Tokens.All(IsDirectiveCompletableSymbol) && - // Do not provide IntelliSense for explicit expressions. Explicit expressions will usually look like: - // [@] [(] [DateTime.Now] [)] - owner.Parent?.Children.Count > 1 && - owner.Parent.Children[1] == owner) - { - return true; - } - } - - return false; + return Task.CompletedTask; } protected virtual bool TryGetRazorSnapshotPoint(CompletionContext context, out SnapshotPoint snapshotPoint) diff --git a/src/Microsoft.VisualStudio.Editor.Razor/RazorDirectiveCompletionSource.cs b/src/Microsoft.VisualStudio.Editor.Razor/RazorDirectiveCompletionSource.cs new file mode 100644 index 0000000000..6224fc43d4 --- /dev/null +++ b/src/Microsoft.VisualStudio.Editor.Razor/RazorDirectiveCompletionSource.cs @@ -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.Collections.Immutable; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.CodeAnalysis.Razor; +using Microsoft.VisualStudio.Core.Imaging; +using Microsoft.VisualStudio.Imaging; +using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion; +using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion.Data; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Adornments; + +namespace Microsoft.VisualStudio.Editor.Razor +{ + internal class RazorDirectiveCompletionSource : IAsyncCompletionSource + { + // Internal for testing + internal static readonly object DescriptionKey = new object(); + internal static readonly ImageElement DirectiveImageGlyph = new ImageElement( + new ImageId(KnownImageIds.ImageCatalogGuid, KnownImageIds.Type), + "Razor Directive."); + internal static readonly ImmutableArray DirectiveCompletionFilters = new[] { + new CompletionFilter("Razor Directive", "r", DirectiveImageGlyph) + }.ToImmutableArray(); + + // Internal for testing + internal readonly VisualStudioRazorParser _parser; + private readonly RazorCompletionFactsService _completionFactsService; + private readonly ForegroundDispatcher _foregroundDispatcher; + + public RazorDirectiveCompletionSource( + ForegroundDispatcher foregroundDispatcher, + VisualStudioRazorParser parser, + RazorCompletionFactsService completionFactsService) + { + if (foregroundDispatcher == null) + { + throw new ArgumentNullException(nameof(foregroundDispatcher)); + } + + if (parser == null) + { + throw new ArgumentNullException(nameof(parser)); + } + + if (completionFactsService == null) + { + throw new ArgumentNullException(nameof(completionFactsService)); + } + + _foregroundDispatcher = foregroundDispatcher; + _parser = parser; + _completionFactsService = completionFactsService; + } + + public Task GetCompletionContextAsync( + InitialTrigger trigger, + SnapshotPoint triggerLocation, + SnapshotSpan applicableSpan, + CancellationToken token) + { + _foregroundDispatcher.AssertBackgroundThread(); + + var syntaxTree = _parser.CodeDocument?.GetSyntaxTree(); + var location = new SourceSpan(applicableSpan.Start.Position, applicableSpan.Length); + var razorCompletionItems = _completionFactsService.GetCompletionItems(syntaxTree, location); + + var completionItems = new List(); + foreach (var razorCompletionItem in razorCompletionItems) + { + if (razorCompletionItem.Kind != RazorCompletionItemKind.Directive) + { + // Don't support any other types of completion kinds other than directives. + continue; + } + + var completionItem = new CompletionItem( + displayText: razorCompletionItem.DisplayText, + filterText: razorCompletionItem.DisplayText, + insertText: razorCompletionItem.InsertText, + source: this, + icon: DirectiveImageGlyph, + filters: DirectiveCompletionFilters, + suffix: string.Empty, + sortText: razorCompletionItem.DisplayText, + attributeIcons: ImmutableArray.Empty); + completionItem.Properties.AddProperty(DescriptionKey, razorCompletionItem.Description); + completionItems.Add(completionItem); + } + var context = new CompletionContext(completionItems.ToImmutableArray()); + return Task.FromResult(context); + } + + public Task GetDescriptionAsync(CompletionItem item, CancellationToken token) + { + if (!item.Properties.TryGetProperty(DescriptionKey, out var directiveDescription)) + { + directiveDescription = string.Empty; + } + + return Task.FromResult(directiveDescription); + } + + public bool TryGetApplicableToSpan(char typeChar, SnapshotPoint triggerLocation, out SnapshotSpan applicableToSpan, CancellationToken token) + { + // The applicable span for completion is the piece of text a completion is for. For example: + // @Date|Time.Now + // If you trigger completion at the | then the applicable span is the region of 'DateTime'; however, Razor + // doesn't know this information so we rely on Roslyn to define what the applicable span for a completion is. + applicableToSpan = default(SnapshotSpan); + return false; + } + } +} diff --git a/src/Microsoft.VisualStudio.Editor.Razor/RazorDirectiveCompletionSourceProvider.cs b/src/Microsoft.VisualStudio.Editor.Razor/RazorDirectiveCompletionSourceProvider.cs new file mode 100644 index 0000000000..0c9e40a38f --- /dev/null +++ b/src/Microsoft.VisualStudio.Editor.Razor/RazorDirectiveCompletionSourceProvider.cs @@ -0,0 +1,73 @@ +// 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.ComponentModel.Composition; +using System.Linq; +using Microsoft.CodeAnalysis.Razor; +using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Editor; +using Microsoft.VisualStudio.Utilities; + +namespace Microsoft.VisualStudio.Editor.Razor +{ + [System.Composition.Shared] + [Export(typeof(IAsyncCompletionSourceProvider))] + [Name("Razor directive completion provider.")] + [ContentType(RazorLanguage.CoreContentType)] + internal class RazorDirectiveCompletionSourceProvider : IAsyncCompletionSourceProvider + { + private readonly ForegroundDispatcher _foregroundDispatcher; + private readonly RazorCompletionFactsService _completionFactsService; + + [ImportingConstructor] + public RazorDirectiveCompletionSourceProvider( + ForegroundDispatcher foregroundDispatcher, + RazorCompletionFactsService completionFactsService) + { + if (foregroundDispatcher == null) + { + throw new ArgumentNullException(nameof(foregroundDispatcher)); + } + + if (completionFactsService == null) + { + throw new ArgumentNullException(nameof(completionFactsService)); + } + + _foregroundDispatcher = foregroundDispatcher; + _completionFactsService = completionFactsService; + } + + public IAsyncCompletionSource GetOrCreate(ITextView textView) + { + if (textView == null) + { + throw new ArgumentNullException(nameof(textView)); + } + + var razorBuffer = textView.BufferGraph.GetRazorBuffers().FirstOrDefault(); + if (!razorBuffer.Properties.TryGetProperty(typeof(RazorDirectiveCompletionSource), out IAsyncCompletionSource completionSource)) + { + completionSource = CreateCompletionSource(razorBuffer); + razorBuffer.Properties.AddProperty(typeof(RazorDirectiveCompletionSource), completionSource); + } + + return completionSource; + } + + // Internal for testing + internal IAsyncCompletionSource CreateCompletionSource(ITextBuffer razorBuffer) + { + if (!razorBuffer.Properties.TryGetProperty(typeof(VisualStudioRazorParser), out VisualStudioRazorParser parser)) + { + // Parser hasn't been associated with the text buffer yet. + return null; + } + + var completionSource = new RazorDirectiveCompletionSource(_foregroundDispatcher, parser, _completionFactsService); + return completionSource; + } + } +} diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpRazorCommentsTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpRazorCommentsTest.cs index bcc8974b86..af280d67f0 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpRazorCommentsTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpRazorCommentsTest.cs @@ -42,6 +42,18 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy + "}"); } + [Fact] + public void RazorCommentInOpeningTagBlock() + { + ParseDocumentTest(""); + } + + [Fact] + public void RazorCommentInClosingTagBlock() + { + ParseDocumentTest(""); + } + [Fact] public void UnterminatedRazorCommentInVerbatimBlock() { diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml index bd4820f914..1edd2fcc49 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml @@ -13,3 +13,6 @@

But this should show the comment syntax: @bar

@(a@**@b) + + + diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.ir.txt index e75591ec2d..5853591fb0 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.ir.txt @@ -38,5 +38,14 @@ Document - CSharpExpression - (323:14,2 [2] RazorComments.cshtml) IntermediateToken - (323:14,2 [1] RazorComments.cshtml) - CSharp - a IntermediateToken - (328:14,7 [1] RazorComments.cshtml) - CSharp - b - HtmlContent - (330:14,9 [2] RazorComments.cshtml) - IntermediateToken - (330:14,9 [2] RazorComments.cshtml) - Html - \n + HtmlContent - (330:14,9 [85] RazorComments.cshtml) + IntermediateToken - (330:14,9 [4] RazorComments.cshtml) - Html - \n\n + IntermediateToken - (334:16,0 [6] RazorComments.cshtml) - Html - + IntermediateToken - (406:16,72 [2] RazorComments.cshtml) - Html - \n + IntermediateToken - (408:17,0 [7] RazorComments.cshtml) - Html - + IntermediateToken - (473:17,65 [2] RazorComments.cshtml) - Html - \n diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.codegen.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.codegen.cs index d9b27a45c7..7579c50719 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.codegen.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.codegen.cs @@ -1,11 +1,11 @@ -#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "051345e2cc0313fea445db2f6cf48fe28b0b4edf" +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "4d553281e07fafc67ca0139b27ee95724a37f162" // #pragma warning disable 1591 [assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorComments_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml")] namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles { #line hidden - [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"051345e2cc0313fea445db2f6cf48fe28b0b4edf", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml")] + [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"4d553281e07fafc67ca0139b27ee95724a37f162", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml")] public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorComments_Runtime { #pragma warning disable 1998 @@ -45,7 +45,8 @@ Write(ab); #line default #line hidden - WriteLiteral("\r\n"); + WriteLiteral("\r\n\r\n\r\n\r\n"); } #pragma warning restore 1998 } diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.ir.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.ir.txt index e05218677f..47c3a144f1 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.ir.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.ir.txt @@ -33,5 +33,14 @@ Document - CSharpExpression - (323:14,2 [2] RazorComments.cshtml) IntermediateToken - (323:14,2 [1] RazorComments.cshtml) - CSharp - a IntermediateToken - (328:14,7 [1] RazorComments.cshtml) - CSharp - b - HtmlContent - (330:14,9 [2] RazorComments.cshtml) - IntermediateToken - (330:14,9 [2] RazorComments.cshtml) - Html - \n + HtmlContent - (330:14,9 [85] RazorComments.cshtml) + IntermediateToken - (330:14,9 [4] RazorComments.cshtml) - Html - \n\n + IntermediateToken - (334:16,0 [6] RazorComments.cshtml) - Html - + IntermediateToken - (406:16,72 [2] RazorComments.cshtml) - Html - \n + IntermediateToken - (408:17,0 [7] RazorComments.cshtml) - Html - + IntermediateToken - (473:17,65 [2] RazorComments.cshtml) - Html - \n diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpAutoCompleteTest/SectionDirectiveAutoCompleteAtStartOfFile.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpAutoCompleteTest/SectionDirectiveAutoCompleteAtStartOfFile.stree.txt index cab4006af3..d59300fc29 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpAutoCompleteTest/SectionDirectiveAutoCompleteAtStartOfFile.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpAutoCompleteTest/SectionDirectiveAutoCompleteAtStartOfFile.stree.txt @@ -19,8 +19,8 @@ Directive block - Gen]; - Markup span - Gen - [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 - 4 - (25:1,6) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (25:1,6) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpDirectivesTest/DirectiveDescriptor_FileScoped_CanBeBeneathOtherWhiteSpaceCommentsAndDirectives.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpDirectivesTest/DirectiveDescriptor_FileScoped_CanBeBeneathOtherWhiteSpaceCommentsAndDirectives.stree.txt index 203fd7aee0..15bd38868f 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpDirectivesTest/DirectiveDescriptor_FileScoped_CanBeBeneathOtherWhiteSpaceCommentsAndDirectives.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpDirectivesTest/DirectiveDescriptor_FileScoped_CanBeBeneathOtherWhiteSpaceCommentsAndDirectives.stree.txt @@ -51,12 +51,13 @@ Markup block - Gen - 130 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[p]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 4 - (126:5,16) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (126:5,16) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpDirectivesTest/DirectiveDescriptor_UnderstandsRazorBlocks.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpDirectivesTest/DirectiveDescriptor_UnderstandsRazorBlocks.stree.txt index c5bde0c85c..fad1a9c949 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpDirectivesTest/DirectiveDescriptor_UnderstandsRazorBlocks.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpDirectivesTest/DirectiveDescriptor_UnderstandsRazorBlocks.stree.txt @@ -19,12 +19,13 @@ Directive block - Gen - 33 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[p]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 4 - (27:0,27) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (27:0,27) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpDirectivesTest/Parse_SectionDirective.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpDirectivesTest/Parse_SectionDirective.stree.txt index 2af805b4b0..77d3e85124 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpDirectivesTest/Parse_SectionDirective.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpDirectivesTest/Parse_SectionDirective.stree.txt @@ -19,12 +19,13 @@ Directive block - Gen - 32 - (0:0,0 HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[p]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 4 - (26:0,26) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (26:0,26) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentInClosingTagBlock.cspans.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentInClosingTagBlock.cspans.txt new file mode 100644 index 0000000000..af3dd82d31 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentInClosingTagBlock.cspans.txt @@ -0,0 +1,8 @@ +Markup span at (0:0,0 [6] ) (Accepts:Any) - Parent: Tag block at (0:0,0 [6] ) +Markup span at (6:0,6 [7] ) (Accepts:Any) - Parent: Tag block at (6:0,6 [7] ) +Transition span at (13:0,13 [1] ) (Accepts:None) - Parent: Comment block at (13:0,13 [19] ) +MetaCode span at (14:0,14 [1] ) (Accepts:None) - Parent: Comment block at (13:0,13 [19] ) +Comment span at (15:0,15 [15] ) (Accepts:Any) - Parent: Comment block at (13:0,13 [19] ) +MetaCode span at (30:0,30 [1] ) (Accepts:None) - Parent: Comment block at (13:0,13 [19] ) +Transition span at (31:0,31 [1] ) (Accepts:None) - Parent: Comment block at (13:0,13 [19] ) +Markup span at (32:0,32 [1] ) (Accepts:Any) - Parent: Markup block at (0:0,0 [33] ) diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentInClosingTagBlock.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentInClosingTagBlock.stree.txt new file mode 100644 index 0000000000..4ac1dd74e2 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentInClosingTagBlock.stree.txt @@ -0,0 +1,25 @@ +Markup block - Gen - 33 - (0:0,0) + Tag block - Gen - 6 - (0:0,0) + Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (0:0,0) - Tokens:3 + HtmlTokenType.OpenAngle;[<]; + HtmlTokenType.Text;[text]; + HtmlTokenType.CloseAngle;[>]; + Tag block - Gen - 7 - (6:0,6) + Markup span - Gen - [ - 19 - (13:0,13) + Transition span - Gen - [@] - SpanEditHandler;Accepts:None - (13:0,13) - Tokens:1 + HtmlTokenType.RazorCommentTransition;[@]; + MetaCode span - Gen - [*] - SpanEditHandler;Accepts:None - (14:0,14) - Tokens:1 + HtmlTokenType.RazorCommentStar;[*]; + Comment span - Gen - [ razor comment ] - SpanEditHandler;Accepts:Any - (15:0,15) - Tokens:1 + HtmlTokenType.RazorComment;[ razor comment ]; + MetaCode span - Gen - [*] - SpanEditHandler;Accepts:None - (30:0,30) - Tokens:1 + HtmlTokenType.RazorCommentStar;[*]; + Transition span - Gen - [@] - SpanEditHandler;Accepts:None - (31:0,31) - Tokens:1 + HtmlTokenType.RazorCommentTransition;[@]; + Markup span - Gen - [>] - SpanEditHandler;Accepts:Any - (32:0,32) - Tokens:1 + HtmlTokenType.CloseAngle;[>]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentInOpeningTagBlock.cspans.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentInOpeningTagBlock.cspans.txt new file mode 100644 index 0000000000..be8102eb0a --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentInOpeningTagBlock.cspans.txt @@ -0,0 +1,8 @@ +Markup span at (0:0,0 [6] ) (Accepts:Any) - Parent: Tag block at (0:0,0 [26] ) +Transition span at (6:0,6 [1] ) (Accepts:None) - Parent: Comment block at (6:0,6 [19] ) +MetaCode span at (7:0,7 [1] ) (Accepts:None) - Parent: Comment block at (6:0,6 [19] ) +Comment span at (8:0,8 [15] ) (Accepts:Any) - Parent: Comment block at (6:0,6 [19] ) +MetaCode span at (23:0,23 [1] ) (Accepts:None) - Parent: Comment block at (6:0,6 [19] ) +Transition span at (24:0,24 [1] ) (Accepts:None) - Parent: Comment block at (6:0,6 [19] ) +Markup span at (25:0,25 [1] ) (Accepts:Any) - Parent: Tag block at (0:0,0 [26] ) +Markup span at (26:0,26 [7] ) (Accepts:Any) - Parent: Tag block at (26:0,26 [7] ) diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentInOpeningTagBlock.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentInOpeningTagBlock.stree.txt new file mode 100644 index 0000000000..2b80249ac8 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentInOpeningTagBlock.stree.txt @@ -0,0 +1,25 @@ +Markup block - Gen - 33 - (0:0,0) + Tag block - Gen - 26 - (0:0,0) + Markup span - Gen - [ - 19 - (6:0,6) + Transition span - Gen - [@] - SpanEditHandler;Accepts:None - (6:0,6) - Tokens:1 + HtmlTokenType.RazorCommentTransition;[@]; + MetaCode span - Gen - [*] - SpanEditHandler;Accepts:None - (7:0,7) - Tokens:1 + HtmlTokenType.RazorCommentStar;[*]; + Comment span - Gen - [ razor comment ] - SpanEditHandler;Accepts:Any - (8:0,8) - Tokens:1 + HtmlTokenType.RazorComment;[ razor comment ]; + MetaCode span - Gen - [*] - SpanEditHandler;Accepts:None - (23:0,23) - Tokens:1 + HtmlTokenType.RazorCommentStar;[*]; + Transition span - Gen - [@] - SpanEditHandler;Accepts:None - (24:0,24) - Tokens:1 + HtmlTokenType.RazorCommentTransition;[@]; + Markup span - Gen - [>] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:1 + HtmlTokenType.CloseAngle;[>]; + Tag block - Gen - 7 - (26:0,26) + Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (26:0,26) - Tokens:4 + HtmlTokenType.OpenAngle;[<]; + HtmlTokenType.ForwardSlash;[/]; + HtmlTokenType.Text;[text]; + HtmlTokenType.CloseAngle;[>]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentWithExtraNewLineInMarkup.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentWithExtraNewLineInMarkup.stree.txt index f1c4b4d734..45a7650f51 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentWithExtraNewLineInMarkup.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentWithExtraNewLineInMarkup.stree.txt @@ -33,8 +33,8 @@ Markup block - Gen - 45 - (0:0,0) HtmlTokenType.RazorCommentTransition;[@]; Markup span - Gen - [LF] - SpanEditHandler;Accepts:Any - (37:5,2) - Tokens:1 HtmlTokenType.NewLine;[LF]; - Markup span - Gen - [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 - 4 - (41:7,0) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (41:7,0) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentsSurroundingMarkup.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentsSurroundingMarkup.stree.txt index b4d122ddd1..c9889ac49d 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentsSurroundingMarkup.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpRazorCommentsTest/RazorCommentsSurroundingMarkup.stree.txt @@ -32,8 +32,8 @@ Markup block - Gen - 42 - (0:0,0) HtmlTokenType.RazorCommentStar;[*]; Transition span - Gen - [@] - SpanEditHandler;Accepts:None - (35:1,30) - Tokens:1 HtmlTokenType.RazorCommentTransition;[@]; - Markup span - Gen - [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 - 4 - (38:2,0) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (38:2,0) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/AcceptsOpenBraceMultipleLinesBelowSectionName.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/AcceptsOpenBraceMultipleLinesBelowSectionName.stree.txt index c601f9eed9..fbbb614257 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/AcceptsOpenBraceMultipleLinesBelowSectionName.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/AcceptsOpenBraceMultipleLinesBelowSectionName.stree.txt @@ -28,8 +28,8 @@ Markup block - Gen - 46 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[p]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 4 - (39:7,6) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (39:7,6) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/DoesNotRequireSpaceBetweenSectionNameAndOpenBrace.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/DoesNotRequireSpaceBetweenSectionNameAndOpenBrace.stree.txt index 55381a524f..9935f5f1ed 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/DoesNotRequireSpaceBetweenSectionNameAndOpenBrace.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/DoesNotRequireSpaceBetweenSectionNameAndOpenBrace.stree.txt @@ -20,8 +20,8 @@ Markup block - Gen - 26 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[p]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 4 - (20:0,20) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (20:0,20) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/HandlesUnterminatedSection.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/HandlesUnterminatedSection.stree.txt index bc5eedd22b..98086ac2d7 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/HandlesUnterminatedSection.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/HandlesUnterminatedSection.stree.txt @@ -22,10 +22,11 @@ Markup block - Gen - 27 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[p]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 4 - (23:0,23) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (23:0,23) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ParserOutputsErrorOnNestedSections.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ParserOutputsErrorOnNestedSections.stree.txt index b8abb7fa56..d7963d4182 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ParserOutputsErrorOnNestedSections.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ParserOutputsErrorOnNestedSections.stree.txt @@ -38,8 +38,8 @@ Markup block - Gen - 44 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[p]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 4 - (36:0,36) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (36:0,36) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ParsesNamedSectionCorrectly.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ParsesNamedSectionCorrectly.stree.txt index 816ec6dd7f..7832e92bdc 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ParsesNamedSectionCorrectly.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ParsesNamedSectionCorrectly.stree.txt @@ -22,8 +22,8 @@ Markup block - Gen - 27 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[p]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 4 - (21:0,21) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (21:0,21) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ReportsErrorAndTerminatesSectionBlockIfKeywordNotFollowedByIdentifierStartChar.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ReportsErrorAndTerminatesSectionBlockIfKeywordNotFollowedByIdentifierStartChar.stree.txt index 2505742c14..67fadc74d1 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ReportsErrorAndTerminatesSectionBlockIfKeywordNotFollowedByIdentifierStartChar.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ReportsErrorAndTerminatesSectionBlockIfKeywordNotFollowedByIdentifierStartChar.stree.txt @@ -18,8 +18,8 @@ Markup block - Gen - 25 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[p]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 4 - (19:0,19) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (19:0,19) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ReportsErrorAndTerminatesSectionBlockIfNameNotFollowedByOpenBrace.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ReportsErrorAndTerminatesSectionBlockIfNameNotFollowedByOpenBrace.stree.txt index f9fea55241..ba78c51800 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ReportsErrorAndTerminatesSectionBlockIfNameNotFollowedByOpenBrace.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/CSharpSectionTest/ReportsErrorAndTerminatesSectionBlockIfNameNotFollowedByOpenBrace.stree.txt @@ -20,8 +20,8 @@ Markup block - Gen - 31 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[p]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 4 - (25:0,25) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlBlockTest/HtmlCommentSupportsMultipleDashes.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlBlockTest/HtmlCommentSupportsMultipleDashes.stree.txt index 5887f79ffc..9209fdbddc 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlBlockTest/HtmlCommentSupportsMultipleDashes.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlBlockTest/HtmlCommentSupportsMultipleDashes.stree.txt @@ -26,8 +26,8 @@ Markup block - Gen - 165 - (0:0,0) HtmlTokenType.ForwardSlash;[/]; HtmlTokenType.Text;[div]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 5 - (35:1,0) Markup span - Gen - [
] - SpanEditHandler;Accepts:Any - (35:1,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -55,8 +55,8 @@ Markup block - Gen - 165 - (0:0,0) HtmlTokenType.ForwardSlash;[/]; HtmlTokenType.Text;[div]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 5 - (72:2,0) Markup span - Gen - [
] - SpanEditHandler;Accepts:Any - (72:2,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -86,8 +86,8 @@ Markup block - Gen - 165 - (0:0,0) HtmlTokenType.ForwardSlash;[/]; HtmlTokenType.Text;[div]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 5 - (111:3,0) Markup span - Gen - [
] - SpanEditHandler;Accepts:Any - (111:3,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/CorrectlyHandlesOddlySpacedHTMLElements.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/CorrectlyHandlesOddlySpacedHTMLElements.stree.txt index 9c1abf332f..da5099b7ee 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/CorrectlyHandlesOddlySpacedHTMLElements.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/CorrectlyHandlesOddlySpacedHTMLElements.stree.txt @@ -23,10 +23,11 @@ Markup block - Gen - 39 - (0:0,0) HtmlTokenType.SingleQuote;[']; Markup span - Gen - [>] - SpanEditHandler;Accepts:Any - (22:0,22) - Tokens:1 HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 4 - (28:0,28) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (28:0,28) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/CorrectlyHandlesSingleLineOfMarkupWithEmbeddedStatement.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/CorrectlyHandlesSingleLineOfMarkupWithEmbeddedStatement.stree.txt index c4571ddfed..04894092c5 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/CorrectlyHandlesSingleLineOfMarkupWithEmbeddedStatement.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/CorrectlyHandlesSingleLineOfMarkupWithEmbeddedStatement.stree.txt @@ -18,9 +18,10 @@ Markup block - Gen - 31 - (0:0,0) CSharpTokenType.WhiteSpace;[ ]; CSharpTokenType.LeftBrace;[{]; CSharpTokenType.RightBrace;[}]; - Markup span - Gen - [ 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 - 6 - (25:0,25) Markup span - Gen - [
] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/DoesNotSwitchToCodeOnEmailAddressInAttribute.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/DoesNotSwitchToCodeOnEmailAddressInAttribute.stree.txt index 1cd8f8d382..49f7bab75a 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/DoesNotSwitchToCodeOnEmailAddressInAttribute.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/DoesNotSwitchToCodeOnEmailAddressInAttribute.stree.txt @@ -15,10 +15,11 @@ Markup block - Gen - 51 - (0:0,0) HtmlTokenType.DoubleQuote;["]; Markup span - Gen - [>] - SpanEditHandler;Accepts:Any - (38:0,38) - Tokens:1 HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 4 - (47:0,47) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (47:0,47) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/NoLongerSupportsDollarOpenBraceCombination.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/NoLongerSupportsDollarOpenBraceCombination.stree.txt index 7be20b9bb1..af6cd12e73 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/NoLongerSupportsDollarOpenBraceCombination.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/NoLongerSupportsDollarOpenBraceCombination.stree.txt @@ -4,8 +4,8 @@ Markup block - Gen - 17 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[foo]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [${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 - 6 - (11:0,11) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (11:0,11) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/RendersTextPseudoTagAsMarkup.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/RendersTextPseudoTagAsMarkup.stree.txt index 6d5fca2bac..1dc42d172d 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/RendersTextPseudoTagAsMarkup.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlDocumentTest/RendersTextPseudoTagAsMarkup.stree.txt @@ -7,8 +7,8 @@ Markup block - Gen - 20 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[text]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 7 - (13:0,13) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (13:0,13) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlTagsTest/VoidElementFollowedByOtherTag.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlTagsTest/VoidElementFollowedByOtherTag.stree.txt index ff1e45cbe0..dcc9e60c04 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlTagsTest/VoidElementFollowedByOtherTag.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlTagsTest/VoidElementFollowedByOtherTag.stree.txt @@ -12,20 +12,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 6 - (38:4,0) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (38:4,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -36,20 +37,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 4 - (73:7,0) Markup span - Gen - [
] - SpanEditHandler;Accepts:Any - (73:7,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -60,20 +62,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 5 - (106:10,0) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (106:10,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -84,20 +87,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 9 - (140:13,0) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (140:13,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -108,20 +112,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 7 - (178:16,0) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (178:16,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -132,20 +137,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 4 - (214:19,0) Markup span - Gen - [
] - SpanEditHandler;Accepts:Any - (214:19,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -156,20 +162,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 5 - (247:22,0) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (247:22,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -180,20 +187,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 7 - (281:25,0) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (281:25,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -204,20 +212,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 8 - (317:28,0) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (317:28,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -228,20 +237,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 6 - (354:31,0) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (354:31,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -252,20 +262,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 6 - (389:34,0) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (389:34,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -276,20 +287,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 7 - (424:37,0) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (424:37,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -300,20 +312,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 8 - (460:40,0) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (460:40,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -324,20 +337,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 7 - (497:43,0) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (497:43,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -348,20 +362,21 @@ Markup block - Gen - 564 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[other]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ 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 - 5 - (533:46,0) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (533:46,0) - Tokens:3 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/ParseDocumentGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/ParseDocumentGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine.stree.txt index 97fd746b22..6cbf72896e 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/ParseDocumentGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/ParseDocumentGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine.stree.txt @@ -57,8 +57,8 @@ Markup block - Gen - 95 - (0:0,0) CSharpTokenType.WhiteSpace;[ ]; CSharpTokenType.RightBrace;[}]; CSharpTokenType.NewLine;[LF]; - Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (86:4,0) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [ ] - [86..90) - FullWidth: 4 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 5 - (90:4,4) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (90:4,4) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/ParseDocumentTreatsTwoAtSignsAsEscapeSequence.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/ParseDocumentTreatsTwoAtSignsAsEscapeSequence.stree.txt index e870829b98..1a12555431 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/ParseDocumentTreatsTwoAtSignsAsEscapeSequence.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/ParseDocumentTreatsTwoAtSignsAsEscapeSequence.stree.txt @@ -6,9 +6,10 @@ Markup block - Gen - 16 - (0:0,0) HtmlTokenType.CloseAngle;[>]; Markup span - Gen - [@] - SpanEditHandler;Accepts:Any - (5:0,5) - Tokens:1 HtmlTokenType.Transition;[@]; - Markup span - Gen - [@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 - 6 - (10:0,10) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (10:0,10) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/SectionBodyTreatsTwoAtSignsAsEscapeSequence.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/SectionBodyTreatsTwoAtSignsAsEscapeSequence.stree.txt index 8314633d3a..e339ea4c7b 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/SectionBodyTreatsTwoAtSignsAsEscapeSequence.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/SectionBodyTreatsTwoAtSignsAsEscapeSequence.stree.txt @@ -24,9 +24,10 @@ Markup block - Gen - 33 - (0:0,0) HtmlTokenType.CloseAngle;[>]; Markup span - Gen - [@] - SpanEditHandler;Accepts:Any - (20:0,20) - Tokens:1 HtmlTokenType.Transition;[@]; - Markup span - Gen - [@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 - 6 - (25:0,25) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/SectionContextGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/SectionContextGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine.stree.txt index 4b833c9b90..6679cbc713 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/SectionContextGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/HtmlToCodeSwitchTest/SectionContextGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine.stree.txt @@ -74,8 +74,8 @@ Markup block - Gen - 127 - (0:0,0) CSharpTokenType.WhiteSpace;[ ]; CSharpTokenType.RightBrace;[}]; CSharpTokenType.NewLine;[LF]; - Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (115:5,0) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [ ] - [115..119) - FullWidth: 4 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 5 - (119:5,4) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (119:5,4) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CanHandleSymbolBoundAttributes3.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CanHandleSymbolBoundAttributes3.stree.txt index 366dbc6078..e5de15c751 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CanHandleSymbolBoundAttributes3.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CanHandleSymbolBoundAttributes3.stree.txt @@ -5,7 +5,8 @@ Markup block - Gen - 55 - (0:0,0) (click) - SingleQuotes Code span - Gen - [doSomething()] - ImplicitExpressionEditHandler;Accepts:AnyExceptNewline;ImplicitExpression[ATD];K14 - (23:0,23) - Tokens:1 HtmlTokenType.Text;[doSomething()]; - Markup span - Gen - [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]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CanHandleSymbolBoundAttributes4.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CanHandleSymbolBoundAttributes4.stree.txt index cbf0f2b725..50715ec4ce 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CanHandleSymbolBoundAttributes4.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CanHandleSymbolBoundAttributes4.stree.txt @@ -5,7 +5,8 @@ Markup block - Gen - 56 - (0:0,0) (^click) - SingleQuotes Code span - Gen - [doSomething()] - ImplicitExpressionEditHandler;Accepts:AnyExceptNewline;ImplicitExpression[ATD];K14 - (24:0,24) - Tokens:1 HtmlTokenType.Text;[doSomething()]; - Markup span - Gen - [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]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CreatesErrorForMalformedTagHelper6.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CreatesErrorForMalformedTagHelper6.stree.txt index fe4a84da78..7f6efaa0b4 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CreatesErrorForMalformedTagHelper6.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CreatesErrorForMalformedTagHelper6.stree.txt @@ -11,8 +11,8 @@ Markup block - Gen - 16 - (0:0,0) HtmlTokenType.ForwardSlash;[/]; HtmlTokenType.Text;[strong]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (11:0,11) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [ ] - [11..12) - FullWidth: 1 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 1 - (12:0,12) Markup span - Gen - [<] - SpanEditHandler;Accepts:Any - (12:0,12) - Tokens:1 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CreatesErrorForMalformedTagHelper7.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CreatesErrorForMalformedTagHelper7.stree.txt index 7be3a33a3d..c8c9775478 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CreatesErrorForMalformedTagHelper7.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/CreatesErrorForMalformedTagHelper7.stree.txt @@ -7,9 +7,10 @@ Markup block - Gen - 16 - (0:0,0) HtmlTokenType.OpenAngle;[<]; Tag block - Gen - 14 - (2:0,2) - strong - strongtaghelper StartTagAndEndTag - - Markup span - Gen - [> ] - 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 - 1 - (12:0,12) Markup span - Gen - [<] - SpanEditHandler;Accepts:Any - (12:0,12) - Tokens:1 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml1.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml1.stree.txt index 691f1ef5f0..651de5616b 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml1.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml1.stree.txt @@ -7,6 +7,7 @@ Markup block - Gen - 11 - (0:0,0) HtmlTokenType.OpenAngle;[<]; Tag block - Gen - 9 - (2:0,2) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [>>] - 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;[>]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml10.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml10.stree.txt index 3bd9e0da8b..7162e0ec6e 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml10.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml10.stree.txt @@ -27,6 +27,7 @@ Markup block - Gen - 42 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [ >] - 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;[>]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml6.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml6.stree.txt index 205fa19ad5..8a18d0f97d 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml6.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml6.stree.txt @@ -8,8 +8,9 @@ Markup block - Gen - 13 - (0:0,0) HtmlTokenType.OpenAngle;[<]; Tag block - Gen - 9 - (3:0,3) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [/>] - 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 - [>] - SpanEditHandler;Accepts:Any - (12:0,12) - Tokens:1 HtmlTokenType.CloseAngle;[>]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml7.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml7.stree.txt index 08d08394e4..4db6a53c07 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml7.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml7.stree.txt @@ -8,9 +8,10 @@ Markup block - Gen - 21 - (0:0,0) HtmlTokenType.OpenAngle;[<]; Tag block - Gen - 17 - (3:0,3) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [/>] - 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 - 8 - (8:0,8) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (8:0,8) - Tokens:3 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml8.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml8.stree.txt index 5b8eb5624a..a2778a175d 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml8.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml8.stree.txt @@ -15,9 +15,10 @@ Markup block - Gen - 34 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [/>] - 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 - 8 - (21:0,21) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (21:0,21) - Tokens:3 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml9.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml9.stree.txt index be1f5cade9..450dc56e03 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml9.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_AllowsInvalidHtml9.stree.txt @@ -4,8 +4,8 @@ Markup block - Gen - 52 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.ForwardSlash;[/]; HtmlTokenType.WhiteSpace;[ ]; - Markup span - Gen - [/] - SpanEditHandler;Accepts:Any - (4:0,4) - Tokens:1 - HtmlTokenType.ForwardSlash;[/]; + SyntaxKind.HtmlText - [/] - [4..5) - FullWidth: 1 - Slots: 1 + SyntaxKind.ForwardSlash;[/]; Tag block - Gen - 4 - (5:0,5) Markup span - Gen - [< >] - SpanEditHandler;Accepts:Any - (5:0,5) - Tokens:3 HtmlTokenType.OpenAngle;[<]; @@ -20,11 +20,12 @@ Markup block - Gen - 52 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [ / >] - 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 - 8 - (29:0,29) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (29:0,29) - Tokens:3 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper2.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper2.stree.txt index 7507d4edbb..d5041a70bd 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper2.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper2.stree.txt @@ -6,13 +6,14 @@ Markup block - Gen - 42 - (0:0,0) HtmlTokenType.CloseAngle;[>]; Tag block - Gen - 37 - (5:0,5) - p - ptaghelper StartTagAndEndTag -

- Markup span - Gen - [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 - 22 - (14:0,14) - strong - strongtaghelper StartTagAndEndTag - ... - Markup span - Gen - [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 - 6 - (36:0,36) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (36:0,36) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper3.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper3.stree.txt index 4db15664cc..ec641a65dc 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper3.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper3.stree.txt @@ -6,13 +6,14 @@ Markup block - Gen - 33 - (0:0,0) HtmlTokenType.CloseAngle;[>]; Tag block - Gen - 28 - (5:0,5) - p - ptaghelper StartTagAndEndTag -

- Markup span - Gen - [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 - 19 - (14:0,14) - strong - strongtaghelper StartTagAndEndTag - - Markup span - Gen - [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 - 6 - (27:0,27) Markup span - Gen - [

] - SpanEditHandler;Accepts:Any - (27:0,27) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper4.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper4.stree.txt index 53f8db31af..d65111c91c 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper4.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper4.stree.txt @@ -4,13 +4,14 @@ Markup block - Gen - 52 - (0:0,0) class - DoubleQuotes Markup span - Gen - [foo] - SpanEditHandler;Accepts:Any - (10:0,10) - Tokens:1 HtmlTokenType.Text;[foo]; - Markup span - Gen - [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 - 31 - (21:0,21) - p - ptaghelper StartTagAndEndTag -

...

style - DoubleQuotes Markup span - Gen - [color:red;] - SpanEditHandler;Accepts:Any - (31:0,31) - Tokens:1 HtmlTokenType.Text;[color:red;]; - Markup span - Gen - [World] - SpanEditHandler;Accepts:Any - (43:0,43) - Tokens:1 - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [World] - [43..48) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks3.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks3.stree.txt index f0ca32e92b..0e92db66cb 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks3.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks3.stree.txt @@ -21,7 +21,8 @@ Markup block - Gen - 62 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [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]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks4.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks4.stree.txt index ae4ff2e8b5..58dedb903f 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks4.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks4.stree.txt @@ -103,7 +103,8 @@ Markup block - Gen - 164 - (0:0,0) CSharpTokenType.GreaterThan;[>]; CSharpTokenType.RightParenthesis;[)]; CSharpTokenType.Semicolon;[;]; - Markup span - Gen - [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]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks5.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks5.stree.txt index 96fd57b5b6..8c66f6af06 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks5.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks5.stree.txt @@ -11,10 +11,10 @@ Markup block - Gen - 69 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [Hello] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:1 - HtmlTokenType.Text;[Hello]; - Markup span - Gen - [ ] - 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 - 34 - (35:0,35) - p - ptaghelper StartTagAndEndTag -

...

style - SingleQuotes @@ -27,5 +27,5 @@ Markup block - Gen - 69 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [World] - SpanEditHandler;Accepts:Any - (60:0,60) - Tokens:1 - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [World] - [60..65) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks6.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks6.stree.txt index 227cfafca6..f857b3b159 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks6.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks6.stree.txt @@ -52,10 +52,10 @@ Markup block - Gen - 171 - (0:0,0) CSharpTokenType.GreaterThan;[>]; CSharpTokenType.RightParenthesis;[)]; CSharpTokenType.Semicolon;[;]; - Markup span - Gen - [Hello] - SpanEditHandler;Accepts:Any - (76:0,76) - Tokens:1 - HtmlTokenType.Text;[Hello]; - Markup span - Gen - [ ] - 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 - 85 - (86:0,86) - p - ptaghelper StartTagAndEndTag -

...

style - SingleQuotes @@ -109,5 +109,5 @@ Markup block - Gen - 171 - (0:0,0) CSharpTokenType.GreaterThan;[>]; CSharpTokenType.RightParenthesis;[)]; CSharpTokenType.Semicolon;[;]; - Markup span - Gen - [World] - SpanEditHandler;Accepts:Any - (162:0,162) - Tokens:1 - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [World] - [162..167) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks7.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks7.stree.txt index d7b3ddaf13..0370e716d7 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks7.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks7.stree.txt @@ -21,11 +21,12 @@ Markup block - Gen - 122 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [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 - 30 - (59:0,59) Markup span - Gen - [ - 122 - (0:0,0) HtmlTokenType.DoubleQuote;["]; Markup span - Gen - [>] - SpanEditHandler;Accepts:Any - (88:0,88) - Tokens:1 HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [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 - 9 - (109:0,109) Markup span - Gen - [
] - SpanEditHandler;Accepts:Any - (109:0,109) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks5.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks5.stree.txt index 4b1ec685e7..f56e242178 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks5.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks5.stree.txt @@ -8,8 +8,8 @@ Markup block - Gen - 41 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (20:0,20) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [ ] - [20..21) - FullWidth: 1 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 20 - (21:0,21) - p - ptaghelper StartTagAndEndTag -

...

Expression block - Gen - 13 - (24:0,24) diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks6.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks6.stree.txt index ea99ab8b27..1c73cb4a04 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks6.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks6.stree.txt @@ -42,8 +42,8 @@ Markup block - Gen - 131 - (0:0,0) CSharpTokenType.GreaterThan;[>]; CSharpTokenType.RightParenthesis;[)]; CSharpTokenType.Semicolon;[;]; - Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (65:0,65) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [ ] - [65..66) - FullWidth: 1 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 65 - (66:0,66) - p - ptaghelper StartTagAndEndTag -

...

Statement block - Gen - 58 - (69:0,69) diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks7.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks7.stree.txt index 65a743ab54..89b597f453 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks7.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks7.stree.txt @@ -28,11 +28,12 @@ Markup block - Gen - 77 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [ 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 - 9 - (64:0,64) Markup span - Gen - [
] - SpanEditHandler;Accepts:Any - (64:0,64) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks8.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks8.stree.txt index 0a629daead..39f7f0e90e 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks8.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks8.stree.txt @@ -96,11 +96,12 @@ Markup block - Gen - 167 - (0:0,0) CSharpTokenType.GreaterThan;[>]; CSharpTokenType.RightParenthesis;[)]; CSharpTokenType.Semicolon;[;]; - Markup span - Gen - [ 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 - 9 - (154:0,154) Markup span - Gen - [
] - SpanEditHandler;Accepts:Any - (154:0,154) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesOddlySpacedTagHelperTagBlocks2.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesOddlySpacedTagHelperTagBlocks2.stree.txt index dcbff8cf35..4899139986 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesOddlySpacedTagHelperTagBlocks2.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesOddlySpacedTagHelperTagBlocks2.stree.txt @@ -21,7 +21,8 @@ Markup block - Gen - 77 - (0:0,0) HtmlTokenType.Text;[;]; Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (53:0,53) - Tokens:1 HtmlTokenType.WhiteSpace;[ ]; - Markup span - Gen - [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]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesOddlySpacedTagHelperTagBlocks3.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesOddlySpacedTagHelperTagBlocks3.stree.txt index f8e29d153c..e50a16ac77 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesOddlySpacedTagHelperTagBlocks3.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesOddlySpacedTagHelperTagBlocks3.stree.txt @@ -8,10 +8,10 @@ Markup block - Gen - 73 - (0:0,0) HtmlTokenType.Text;[foo]; Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (20:0,20) - Tokens:1 HtmlTokenType.WhiteSpace;[ ]; - Markup span - Gen - [Hello] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:1 - HtmlTokenType.Text;[Hello]; - Markup span - Gen - [ ] - 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 - 38 - (35:0,35) - p - ptaghelper StartTagAndEndTag -

...

style - DoubleQuotes @@ -21,5 +21,5 @@ Markup block - Gen - 73 - (0:0,0) HtmlTokenType.Text;[color:red;]; Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (60:0,60) - Tokens:1 HtmlTokenType.WhiteSpace;[ ]; - Markup span - Gen - [World] - SpanEditHandler;Accepts:Any - (64:0,64) - Tokens:1 - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [World] - [64..69) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks2.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks2.stree.txt index 9342e8c17f..037159aa8b 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks2.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks2.stree.txt @@ -1,7 +1,8 @@ Markup block - Gen - 18 - (0:0,0) Tag block - Gen - 18 - (0:0,0) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [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]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks3.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks3.stree.txt index 416fb1eea7..c0d42d889b 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks3.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks3.stree.txt @@ -1,11 +1,11 @@ Markup block - Gen - 25 - (0:0,0) Tag block - Gen - 12 - (0:0,0) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [Hello] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:1 - HtmlTokenType.Text;[Hello]; - Markup span - Gen - [ ] - 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 - 12 - (13:0,13) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [World] - SpanEditHandler;Accepts:Any - (16:0,16) - Tokens:1 - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [World] - [16..21) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks4.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks4.stree.txt index abfc92081e..57227a6b9c 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks4.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks4.stree.txt @@ -1,24 +1,26 @@ Markup block - Gen - 56 - (0:0,0) Tag block - Gen - 56 - (0:0,0) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [Hello World ] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:4 - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [Hello World ] - [3..15) - FullWidth: 12 - Slots: 1 + SyntaxKind.List - [Hello World ] - [3..15) - FullWidth: 12 - Slots: 4 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 8 - (15:0,15) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (15:0,15) - Tokens:3 HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[strong]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [inside of strong tag] - SpanEditHandler;Accepts:Any - (23:0,23) - 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] - [23..43) - FullWidth: 20 - Slots: 1 + SyntaxKind.List - [inside of strong tag] - [23..43) - 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 - 9 - (43:0,43) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (43:0,43) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers3.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers3.stree.txt index ac2d4ce18f..ca53775995 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers3.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers3.stree.txt @@ -11,11 +11,11 @@ Markup block - Gen - 53 - (0:0,0) HtmlTokenType.ForwardSlash;[/]; HtmlTokenType.Text;[p]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (29:0,29) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [ ] - [29..30) - FullWidth: 1 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 23 - (30:0,30) - p - ptaghelper StartTagAndEndTag -

...

Tag block - Gen - 16 - (33:0,33) - div - divtaghelper StartTagAndEndTag -
...
- Markup span - Gen - [World] - SpanEditHandler;Accepts:Any - (38:0,38) - Tokens:1 - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [World] - [38..43) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers4.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers4.stree.txt index 2bc0cce4d1..8e9b5e2654 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers4.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers4.stree.txt @@ -11,8 +11,8 @@ Markup block - Gen - 75 - (0:0,0) HtmlTokenType.ForwardSlash;[/]; HtmlTokenType.Text;[strong]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (39:0,39) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [ ] - [39..40) - FullWidth: 1 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 35 - (40:0,40) - script - scripttaghelper StartTagAndEndTag - Markup span - Gen - [World] - SpanEditHandler;Accepts:Any - (48:0,48) - Tokens:8 diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers6.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers6.stree.txt index 8a460e1b8a..9b1944707c 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers6.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers6.stree.txt @@ -1,9 +1,10 @@ Markup block - Gen - 67 - (0:0,0) Tag block - Gen - 67 - (0:0,0) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [Hello ] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:2 - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [Hello ] - [3..9) - FullWidth: 6 - Slots: 1 + SyntaxKind.List - [Hello ] - [3..9) - FullWidth: 6 - Slots: 2 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 48 - (9:0,9) - script - scripttaghelper StartTagAndEndTag - class - DoubleQuotes @@ -12,6 +13,7 @@ Markup block - Gen - 67 - (0:0,0) style - DoubleQuotes Markup span - Gen - [color:red;] - SpanEditHandler;Accepts:Any - (36:0,36) - Tokens:1 HtmlTokenType.Text;[color:red;]; - Markup span - Gen - [ World] - SpanEditHandler;Accepts:Any - (57:0,57) - Tokens:2 - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [ World] - [57..63) - FullWidth: 6 - Slots: 1 + SyntaxKind.List - [ World] - [57..63) - FullWidth: 6 - Slots: 2 + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers7.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers7.stree.txt index cd797ecdad..44250bb25c 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers7.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesScriptTagHelpers7.stree.txt @@ -1,9 +1,10 @@ Markup block - Gen - 77 - (0:0,0) Tag block - Gen - 77 - (0:0,0) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [Hello ] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:2 - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [Hello ] - [3..9) - FullWidth: 6 - Slots: 1 + SyntaxKind.List - [Hello ] - [3..9) - FullWidth: 6 - Slots: 2 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 58 - (9:0,9) - script - scripttaghelper StartTagAndEndTag - class - DoubleQuotes @@ -18,6 +19,7 @@ Markup block - Gen - 77 - (0:0,0) style - DoubleQuotes Markup span - Gen - [color:red;] - SpanEditHandler;Accepts:Any - (46:0,46) - Tokens:1 HtmlTokenType.Text;[color:red;]; - Markup span - Gen - [ World] - SpanEditHandler;Accepts:Any - (67:0,67) - Tokens:2 - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [ World] - [67..73) - FullWidth: 6 - Slots: 1 + SyntaxKind.List - [ World] - [67..73) - FullWidth: 6 - Slots: 2 + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesSelfClosingTagHelpers2.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesSelfClosingTagHelpers2.stree.txt index f2e8370abd..e208c481fc 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesSelfClosingTagHelpers2.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesSelfClosingTagHelpers2.stree.txt @@ -1,9 +1,10 @@ Markup block - Gen - 55 - (0:0,0) Tag block - Gen - 55 - (0:0,0) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [Hello ] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:2 - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [Hello ] - [3..9) - FullWidth: 6 - Slots: 1 + SyntaxKind.List - [Hello ] - [3..9) - FullWidth: 6 - Slots: 2 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 36 - (9:0,9) - p - ptaghelper SelfClosing -

class - DoubleQuotes @@ -12,6 +13,7 @@ Markup block - Gen - 55 - (0:0,0) style - DoubleQuotes Markup span - Gen - [color:red;] - SpanEditHandler;Accepts:Any - (31:0,31) - Tokens:1 HtmlTokenType.Text;[color:red;]; - Markup span - Gen - [ World] - SpanEditHandler;Accepts:Any - (45:0,45) - Tokens:2 - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [ World] - [45..51) - FullWidth: 6 - Slots: 1 + SyntaxKind.List - [ World] - [45..51) - FullWidth: 6 - Slots: 2 + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesSelfClosingTagHelpers3.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesSelfClosingTagHelpers3.stree.txt index 172a414a85..240216bd1b 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesSelfClosingTagHelpers3.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesSelfClosingTagHelpers3.stree.txt @@ -6,8 +6,8 @@ Markup block - Gen - 52 - (0:0,0) class - DoubleQuotes Markup span - Gen - [foo] - SpanEditHandler;Accepts:Any - (15:0,15) - Tokens:1 HtmlTokenType.Text;[foo]; - Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (22:0,22) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [ ] - [22..23) - FullWidth: 1 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 24 - (23:0,23) - p - ptaghelper SelfClosing -

style - DoubleQuotes diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes2.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes2.stree.txt index 139d9edd0b..14d467f45c 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes2.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes2.stree.txt @@ -7,7 +7,8 @@ Markup block - Gen - 49 - (0:0,0) style - DoubleQuotes Markup span - Gen - [color:red;] - SpanEditHandler;Accepts:Any - (22:0,22) - Tokens:1 HtmlTokenType.Text;[color:red;]; - Markup span - Gen - [Hello World] - SpanEditHandler;Accepts:Any - (34:0,34) - Tokens:3 - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [Hello World] - [34..45) - FullWidth: 11 - Slots: 1 + SyntaxKind.List - [Hello World] - [34..45) - FullWidth: 11 - Slots: 3 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes3.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes3.stree.txt index 4a1b76e66f..3ef0269912 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes3.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes3.stree.txt @@ -4,14 +4,14 @@ Markup block - Gen - 56 - (0:0,0) class - DoubleQuotes Markup span - Gen - [foo] - SpanEditHandler;Accepts:Any - (10:0,10) - Tokens:1 HtmlTokenType.Text;[foo]; - Markup span - Gen - [Hello] - SpanEditHandler;Accepts:Any - (15:0,15) - Tokens:1 - HtmlTokenType.Text;[Hello]; - Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (24:0,24) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [Hello] - [15..20) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.HtmlText - [ ] - [24..25) - FullWidth: 1 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 31 - (25:0,25) - p - ptaghelper StartTagAndEndTag -

...

style - DoubleQuotes Markup span - Gen - [color:red;] - SpanEditHandler;Accepts:Any - (35:0,35) - Tokens:1 HtmlTokenType.Text;[color:red;]; - Markup span - Gen - [World] - SpanEditHandler;Accepts:Any - (47:0,47) - Tokens:1 - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [World] - [47..52) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes4.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes4.stree.txt index c0735871ee..dbbf227e04 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes4.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes4.stree.txt @@ -7,11 +7,12 @@ Markup block - Gen - 99 - (0:0,0) style - DoubleQuotes Markup span - Gen - [color:red;] - SpanEditHandler;Accepts:Any - (22:0,22) - Tokens:1 HtmlTokenType.Text;[color:red;]; - Markup span - Gen - [Hello World ] - SpanEditHandler;Accepts:Any - (34:0,34) - Tokens:4 - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [Hello World ] - [34..46) - FullWidth: 12 - Slots: 1 + SyntaxKind.List - [Hello World ] - [34..46) - FullWidth: 12 - Slots: 4 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 20 - (46:0,46) Markup span - Gen - [ - 99 - (0:0,0) HtmlTokenType.DoubleQuote;["]; Markup span - Gen - [>] - SpanEditHandler;Accepts:Any - (65:0,65) - Tokens:1 HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [inside of strong tag] - SpanEditHandler;Accepts:Any - (66:0,66) - 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] - [66..86) - FullWidth: 20 - Slots: 1 + SyntaxKind.List - [inside of strong tag] - [66..86) - 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 - 9 - (86:0,86) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (86:0,86) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes2.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes2.stree.txt index 69000027f8..66909a9b03 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes2.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes2.stree.txt @@ -17,7 +17,8 @@ Markup block - Gen - 67 - (0:0,0) style - NoQuotes Markup span - Gen - [color:red;] - SpanEditHandler;Accepts:Any - (41:0,41) - Tokens:1 HtmlTokenType.Text;[color:red;]; - Markup span - Gen - [Hello World] - SpanEditHandler;Accepts:Any - (52:0,52) - Tokens:3 - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [Hello World] - [52..63) - FullWidth: 11 - Slots: 1 + SyntaxKind.List - [Hello World] - [52..63) - FullWidth: 11 - Slots: 3 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes3.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes3.stree.txt index 5678b9c2a8..bda8459af3 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes3.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes3.stree.txt @@ -25,7 +25,8 @@ Markup block - Gen - 69 - (0:0,0) HtmlTokenType.Transition;[@]; Markup span - Gen - [:red;] - SpanEditHandler;Accepts:Any - (48:0,48) - Tokens:1 HtmlTokenType.Text;[:red;]; - Markup span - Gen - [Hello World] - SpanEditHandler;Accepts:Any - (54:0,54) - Tokens:3 - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [Hello World] - [54..65) - FullWidth: 11 - Slots: 1 + SyntaxKind.List - [Hello World] - [54..65) - FullWidth: 11 - Slots: 3 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes4.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes4.stree.txt index d8b15f08be..c584c614d3 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes4.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes4.stree.txt @@ -14,10 +14,10 @@ Markup block - Gen - 96 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [Hello] - SpanEditHandler;Accepts:Any - (35:0,35) - Tokens:1 - HtmlTokenType.Text;[Hello]; - Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (44:0,44) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [Hello] - [35..40) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.HtmlText - [ ] - [44..45) - FullWidth: 1 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 51 - (45:0,45) - p - ptaghelper StartTagAndEndTag -

...

style - NoQuotes @@ -33,5 +33,5 @@ Markup block - Gen - 96 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [World] - SpanEditHandler;Accepts:Any - (87:0,87) - Tokens:1 - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [World] - [87..92) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes5.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes5.stree.txt index b8af7a90a7..682edd9cb7 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes5.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperBlockRewriterTest/TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes5.stree.txt @@ -17,11 +17,12 @@ Markup block - Gen - 117 - (0:0,0) style - NoQuotes Markup span - Gen - [color:red;] - SpanEditHandler;Accepts:Any - (41:0,41) - Tokens:1 HtmlTokenType.Text;[color:red;]; - Markup span - Gen - [Hello World ] - SpanEditHandler;Accepts:Any - (52:0,52) - Tokens:4 - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [Hello World ] - [52..64) - FullWidth: 12 - Slots: 1 + SyntaxKind.List - [Hello World ] - [52..64) - FullWidth: 12 - Slots: 4 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 20 - (64:0,64) Markup span - Gen - [ - 117 - (0:0,0) HtmlTokenType.DoubleQuote;["]; Markup span - Gen - [>] - SpanEditHandler;Accepts:Any - (83:0,83) - Tokens:1 HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [inside of strong tag] - SpanEditHandler;Accepts:Any - (84:0,84) - 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] - [84..104) - FullWidth: 20 - Slots: 1 + SyntaxKind.List - [inside of strong tag] - [84..104) - 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 - 9 - (104:0,104) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (104:0,104) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsPrefixedTagHelpers10.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsPrefixedTagHelpers10.stree.txt index 57ede0c7c8..2261b505dd 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsPrefixedTagHelpers10.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsPrefixedTagHelpers10.stree.txt @@ -4,9 +4,10 @@ Markup block - Gen - 47 - (0:0,0) class - DoubleQuotes Markup span - Gen - [btn] - SpanEditHandler;Accepts:Any - (16:0,16) - Tokens:1 HtmlTokenType.Text;[btn]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (21:0,21) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [21..37) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [21..37) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsPrefixedTagHelpers2.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsPrefixedTagHelpers2.stree.txt index ff9ec4c836..f1a4ac271a 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsPrefixedTagHelpers2.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsPrefixedTagHelpers2.stree.txt @@ -4,12 +4,13 @@ Markup block - Gen - 27 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[th:]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (5:0,5) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [5..21) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [5..21) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; Tag block - Gen - 6 - (21:0,21) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (21:0,21) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsRazorCommentsAsChildren.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsRazorCommentsAsChildren.stree.txt index 65a33c1dd7..2185b6c7d8 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsRazorCommentsAsChildren.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsRazorCommentsAsChildren.stree.txt @@ -6,8 +6,8 @@ Markup block - Gen - 26 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[b]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [asdf] - SpanEditHandler;Accepts:Any - (6:0,6) - Tokens:1 - HtmlTokenType.Text;[asdf]; + SyntaxKind.HtmlText - [asdf] - [6..10) - FullWidth: 4 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[asdf]; Tag block - Gen - 4 - (10:0,10) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (10:0,10) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsRazorMarkupInHtmlComment.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsRazorMarkupInHtmlComment.stree.txt index e2c3d3f02e..179b922d73 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsRazorMarkupInHtmlComment.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsRazorMarkupInHtmlComment.stree.txt @@ -6,8 +6,8 @@ Markup block - Gen - 37 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[b]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [asdf] - SpanEditHandler;Accepts:Any - (6:0,6) - Tokens:1 - HtmlTokenType.Text;[asdf]; + SyntaxKind.HtmlText - [asdf] - [6..10) - FullWidth: 4 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[asdf]; Tag block - Gen - 4 - (10:0,10) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (10:0,10) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsSimpleHtmlCommentsAsChildren.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsSimpleHtmlCommentsAsChildren.stree.txt index 6bded863a8..015f78b77e 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsSimpleHtmlCommentsAsChildren.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsSimpleHtmlCommentsAsChildren.stree.txt @@ -6,8 +6,8 @@ Markup block - Gen - 36 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[b]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [asdf] - SpanEditHandler;Accepts:Any - (6:0,6) - Tokens:1 - HtmlTokenType.Text;[asdf]; + SyntaxKind.HtmlText - [asdf] - [6..10) - FullWidth: 4 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[asdf]; Tag block - Gen - 4 - (10:0,10) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (10:0,10) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsTagHelperElementOptOutHTML_WithAttributeData3.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsTagHelperElementOptOutHTML_WithAttributeData3.stree.txt index 89bdbd9827..7d584c965c 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsTagHelperElementOptOutHTML_WithAttributeData3.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/AllowsTagHelperElementOptOutHTML_WithAttributeData3.stree.txt @@ -18,12 +18,13 @@ Markup block - Gen - 37 - (0:0,0) HtmlTokenType.DoubleQuote;["]; Markup span - Gen - [>] - SpanEditHandler;Accepts:Any - (15:0,15) - Tokens:1 HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (16:0,16) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [16..32) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [16..32) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; Tag block - Gen - 5 - (32:0,32) Markup span - Gen - [ - 25 - (0:0,0) Markup span - Gen - [p>] - SpanEditHandler;Accepts:Any - (2:0,2) - Tokens:2 HtmlTokenType.Text;[p]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (4:0,4) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [4..20) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [4..20) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; Tag block - Gen - 5 - (20:0,20) Markup span - Gen - [ - 53 - (0:0,0) Tag block - Gen - 53 - (0:0,0) - p - PTagHelper StartTagAndEndTag -

...

- Markup span - Gen - [LF ] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:2 - HtmlTokenType.NewLine;[LF]; - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [LF ] - [3..9) - FullWidth: 6 - Slots: 1 + SyntaxKind.List - [LF ] - [3..9) - FullWidth: 6 - Slots: 2 + SyntaxKind.NewLine;[LF]; + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 8 - (9:1,4) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (9:1,4) - Tokens:3 HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[strong]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [LF HelloLF ] - SpanEditHandler;Accepts:Any - (17:1,12) - Tokens:5 - HtmlTokenType.NewLine;[LF]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[Hello]; - HtmlTokenType.NewLine;[LF]; - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [LF HelloLF ] - [17..38) - FullWidth: 21 - Slots: 1 + SyntaxKind.List - [LF HelloLF ] - [17..38) - FullWidth: 21 - Slots: 5 + SyntaxKind.NewLine;[LF]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.NewLine;[LF]; + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 9 - (38:3,4) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (38:3,4) - Tokens:4 HtmlTokenType.OpenAngle;[<]; HtmlTokenType.ForwardSlash;[/]; HtmlTokenType.Text;[strong]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [LF] - SpanEditHandler;Accepts:Any - (47:3,13) - Tokens:1 - HtmlTokenType.NewLine;[LF]; + SyntaxKind.HtmlText - [LF] - [47..49) - FullWidth: 2 - Slots: 1 + SyntaxKind.NewLine;[LF]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/CanHandleMultipleTagHelpersWithAllowedChildren.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/CanHandleMultipleTagHelpersWithAllowedChildren.stree.txt index 39abf8bc1c..559893493c 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/CanHandleMultipleTagHelpersWithAllowedChildren.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/CanHandleMultipleTagHelpersWithAllowedChildren.stree.txt @@ -3,9 +3,10 @@ Markup block - Gen - 39 - (0:0,0) StartTagAndEndTag -

...

Tag block - Gen - 28 - (3:0,3) - strong - StrongTagHelper StartTagAndEndTag - ... - Markup span - Gen - [Hello World] - SpanEditHandler;Accepts:Any - (11:0,11) - Tokens:3 - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [Hello World] - [11..22) - FullWidth: 11 - Slots: 1 + SyntaxKind.List - [Hello World] - [11..22) - FullWidth: 11 - Slots: 3 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; Tag block - Gen - 4 - (31:0,31) - br - BRTagHelper StartTagOnly -
diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/CanHandleMultipleTagHelpersWithAllowedChildren_OneNull.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/CanHandleMultipleTagHelpersWithAllowedChildren_OneNull.stree.txt index 39abf8bc1c..559893493c 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/CanHandleMultipleTagHelpersWithAllowedChildren_OneNull.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/CanHandleMultipleTagHelpersWithAllowedChildren_OneNull.stree.txt @@ -3,9 +3,10 @@ Markup block - Gen - 39 - (0:0,0) StartTagAndEndTag -

...

Tag block - Gen - 28 - (3:0,3) - strong - StrongTagHelper StartTagAndEndTag - ... - Markup span - Gen - [Hello World] - SpanEditHandler;Accepts:Any - (11:0,11) - Tokens:3 - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [Hello World] - [11..22) - FullWidth: 11 - Slots: 1 + SyntaxKind.List - [Hello World] - [11..22) - FullWidth: 11 - Slots: 3 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; Tag block - Gen - 4 - (31:0,31) - br - BRTagHelper StartTagOnly -
diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers3.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers3.stree.txt index ae0fe4b2d3..5f423530de 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers3.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers3.stree.txt @@ -4,17 +4,18 @@ Markup block - Gen - 31 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[foo]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (5:0,5) - Tokens:10 - HtmlTokenType.OpenAngle;[<]; - HtmlTokenType.QuestionMark;[?]; - HtmlTokenType.Text;[xml]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.QuestionMark;[?]; - HtmlTokenType.CloseAngle;[>]; + SyntaxKind.HtmlText - [] - [5..25) - FullWidth: 20 - Slots: 1 + SyntaxKind.List - [] - [5..25) - FullWidth: 20 - Slots: 10 + SyntaxKind.OpenAngle;[<]; + SyntaxKind.QuestionMark;[?]; + SyntaxKind.HtmlTextLiteralToken;[xml]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.QuestionMark;[?]; + SyntaxKind.CloseAngle;[>]; Tag block - Gen - 6 - (25:0,25) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers4.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers4.stree.txt index 70ff974ca4..2dc95b7645 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers4.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers4.stree.txt @@ -14,10 +14,11 @@ Markup block - Gen - 24 - (0:0,0) CSharpTokenType.Transition;[@]; Code span - Gen - [foo] - ImplicitExpressionEditHandler;Accepts:NonWhiteSpace;ImplicitExpression[RTD];K14 - (12:0,12) - Tokens:1 CSharpTokenType.Identifier;[foo]; - Markup span - Gen - [ ?>] - SpanEditHandler;Accepts:Any - (15:0,15) - Tokens:3 - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.QuestionMark;[?]; - HtmlTokenType.CloseAngle;[>]; + SyntaxKind.HtmlText - [ ?>] - [15..18) - FullWidth: 3 - Slots: 1 + SyntaxKind.List - [ ?>] - [15..18) - FullWidth: 3 - Slots: 3 + SyntaxKind.Whitespace;[ ]; + SyntaxKind.QuestionMark;[?]; + SyntaxKind.CloseAngle;[>]; Tag block - Gen - 6 - (18:0,18) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (18:0,18) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers5.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers5.stree.txt index c1c7227367..862e8828b5 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers5.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers5.stree.txt @@ -14,9 +14,10 @@ Markup block - Gen - 27 - (0:0,0) CSharpTokenType.Transition;[@]; Code span - Gen - [foo] - ImplicitExpressionEditHandler;Accepts:NonWhiteSpace;ImplicitExpression[RTD];K14 - (16:0,16) - Tokens:1 CSharpTokenType.Identifier;[foo]; - Markup span - Gen - [ >] - SpanEditHandler;Accepts:Any - (19:0,19) - Tokens:2 - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.CloseAngle;[>]; + SyntaxKind.HtmlText - [ >] - [19..21) - FullWidth: 2 - Slots: 1 + SyntaxKind.List - [ >] - [19..21) - FullWidth: 2 - Slots: 2 + SyntaxKind.Whitespace;[ ]; + SyntaxKind.CloseAngle;[>]; Tag block - Gen - 6 - (21:0,21) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (21:0,21) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers6.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers6.stree.txt index db02a12d1e..fa19d6d74d 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers6.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers6.stree.txt @@ -4,18 +4,19 @@ Markup block - Gen - 36 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[foo]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (5:0,5) - Tokens:11 - HtmlTokenType.OpenAngle;[<]; - HtmlTokenType.Bang;[!]; - HtmlTokenType.Text;[DOCTYPE]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[hello]; - HtmlTokenType.Equals;[=]; - HtmlTokenType.DoubleQuote;["]; - HtmlTokenType.Text;[world]; - HtmlTokenType.DoubleQuote;["]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.CloseAngle;[>]; + SyntaxKind.HtmlText - [] - [5..30) - FullWidth: 25 - Slots: 1 + SyntaxKind.List - [] - [5..30) - FullWidth: 25 - Slots: 11 + SyntaxKind.OpenAngle;[<]; + SyntaxKind.Bang;[!]; + SyntaxKind.HtmlTextLiteralToken;[DOCTYPE]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[hello]; + SyntaxKind.Equals;[=]; + SyntaxKind.DoubleQuote;["]; + SyntaxKind.HtmlTextLiteralToken;[world]; + SyntaxKind.DoubleQuote;["]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.CloseAngle;[>]; Tag block - Gen - 6 - (30:0,30) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (30:0,30) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers7.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers7.stree.txt index 9191c0df85..d5ef09e795 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers7.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers7.stree.txt @@ -4,20 +4,21 @@ Markup block - Gen - 36 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[foo]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (5:0,5) - Tokens:13 - HtmlTokenType.OpenAngle;[<]; - HtmlTokenType.Bang;[!]; - HtmlTokenType.LeftBracket;[[]; - HtmlTokenType.Text;[CDATA]; - HtmlTokenType.LeftBracket;[[]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.RightBracket;[]]; - HtmlTokenType.RightBracket;[]]; - HtmlTokenType.CloseAngle;[>]; + SyntaxKind.HtmlText - [] - [5..30) - FullWidth: 25 - Slots: 1 + SyntaxKind.List - [] - [5..30) - FullWidth: 25 - Slots: 13 + SyntaxKind.OpenAngle;[<]; + SyntaxKind.Bang;[!]; + SyntaxKind.LeftBracket;[[]; + SyntaxKind.HtmlTextLiteralToken;[CDATA]; + SyntaxKind.LeftBracket;[[]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.RightBracket;[]]; + SyntaxKind.RightBracket;[]]; + SyntaxKind.CloseAngle;[>]; Tag block - Gen - 6 - (30:0,30) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (30:0,30) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers8.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers8.stree.txt index 269d727534..2f0435624a 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers8.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteSpecialTagTagHelpers8.stree.txt @@ -16,11 +16,12 @@ Markup block - Gen - 29 - (0:0,0) CSharpTokenType.Transition;[@]; Code span - Gen - [foo] - ImplicitExpressionEditHandler;Accepts:NonWhiteSpace;ImplicitExpression[RTD];K14 - (16:0,16) - Tokens:1 CSharpTokenType.Identifier;[foo]; - Markup span - Gen - [ ]]>] - SpanEditHandler;Accepts:Any - (19:0,19) - Tokens:4 - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.RightBracket;[]]; - HtmlTokenType.RightBracket;[]]; - HtmlTokenType.CloseAngle;[>]; + SyntaxKind.HtmlText - [ ]]>] - [19..23) - FullWidth: 4 - Slots: 1 + SyntaxKind.List - [ ]]>] - [19..23) - FullWidth: 4 - Slots: 4 + SyntaxKind.Whitespace;[ ]; + SyntaxKind.RightBracket;[]]; + SyntaxKind.RightBracket;[]]; + SyntaxKind.CloseAngle;[>]; Tag block - Gen - 6 - (23:0,23) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (23:0,23) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteTextTagTransitionTagHelpers1.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteTextTagTransitionTagHelpers1.stree.txt index 71ab735856..8bb9161487 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteTextTagTransitionTagHelpers1.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/DoesNotRewriteTextTagTransitionTagHelpers1.stree.txt @@ -1,7 +1,8 @@ Markup block - Gen - 24 - (0:0,0) Tag block - Gen - 24 - (0:0,0) - text - texttaghelper StartTagAndEndTag - ... - Markup span - Gen - [Hello World] - SpanEditHandler;Accepts:Any - (6:0,6) - Tokens:3 - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [Hello World] - [6..17) - FullWidth: 11 - Slots: 1 + SyntaxKind.List - [Hello World] - [6..17) - FullWidth: 11 - Slots: 3 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly12.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly12.stree.txt index e4144deee1..15e6a99460 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly12.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly12.stree.txt @@ -4,9 +4,10 @@ Markup block - Gen - 47 - (0:0,0) catchAll - DoubleQuotes Markup span - Gen - [hi] - SpanEditHandler;Accepts:Any - (18:0,18) - Tokens:1 HtmlTokenType.Text;[hi]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (22:0,22) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [22..38) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [22..38) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly13.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly13.stree.txt index 611bd33126..82f974fd2d 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly13.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly13.stree.txt @@ -11,9 +11,10 @@ Markup block - Gen - 58 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (33:0,33) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [33..49) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [33..49) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly18.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly18.stree.txt index b8f52275ec..fe60ec311b 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly18.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly18.stree.txt @@ -7,9 +7,10 @@ Markup block - Gen - 51 - (0:0,0) class - DoubleQuotes Markup span - Gen - [btn] - SpanEditHandler;Accepts:Any - (26:0,26) - Tokens:1 HtmlTokenType.Text;[btn]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (31:0,31) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [31..47) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [31..47) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly21.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly21.stree.txt index ae7da8d3bf..d48854c6ca 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly21.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly21.stree.txt @@ -6,9 +6,10 @@ Markup block - Gen - 48 - (0:0,0) class - DoubleQuotes Markup span - Gen - [btn] - SpanEditHandler;Accepts:Any - (21:0,21) - Tokens:1 HtmlTokenType.Text;[btn]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (26:0,26) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [26..42) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [26..42) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly22.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly22.stree.txt index ff1ac587a8..65c77a3afc 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly22.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly22.stree.txt @@ -21,9 +21,10 @@ Markup block - Gen - 71 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (49:0,49) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [49..65) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [49..65) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly23.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly23.stree.txt index a3497aefd1..71d15cc105 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly23.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly23.stree.txt @@ -6,20 +6,20 @@ Markup block - Gen - 63 - (0:0,0) class - DoubleQuotes Markup span - Gen - [btn] - SpanEditHandler;Accepts:Any - (21:0,21) - Tokens:1 HtmlTokenType.Text;[btn]; - Markup span - Gen - [words] - SpanEditHandler;Accepts:Any - (26:0,26) - Tokens:1 - HtmlTokenType.Text;[words]; + SyntaxKind.HtmlText - [words] - [26..31) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[words]; Tag block - Gen - 8 - (31:0,31) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (31:0,31) - Tokens:3 HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[strong]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [and] - SpanEditHandler;Accepts:Any - (39:0,39) - Tokens:1 - HtmlTokenType.Text;[and]; + SyntaxKind.HtmlText - [and] - [39..42) - FullWidth: 3 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[and]; Tag block - Gen - 9 - (42:0,42) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (42:0,42) - Tokens:4 HtmlTokenType.OpenAngle;[<]; HtmlTokenType.ForwardSlash;[/]; HtmlTokenType.Text;[strong]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [spaces] - SpanEditHandler;Accepts:Any - (51:0,51) - Tokens:1 - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [spaces] - [51..57) - FullWidth: 6 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly25.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly25.stree.txt index afe5f75025..d84ee3a355 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly25.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly25.stree.txt @@ -7,9 +7,10 @@ Markup block - Gen - 49 - (0:0,0) catchAll - DoubleQuotes Markup span - Gen - [hi] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:1 HtmlTokenType.Text;[hi]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (29:0,29) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [29..45) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [29..45) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly27.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly27.stree.txt index d26626a437..ce687fa183 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly27.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly27.stree.txt @@ -9,9 +9,10 @@ Markup block - Gen - 63 - (0:0,0) catchAll - DoubleQuotes Markup span - Gen - [hi] - SpanEditHandler;Accepts:Any - (36:0,36) - Tokens:1 HtmlTokenType.Text;[hi]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (41:0,41) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [41..57) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [41..57) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly28.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly28.stree.txt index 14faf216a7..384a5a66de 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly28.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly28.stree.txt @@ -15,9 +15,10 @@ Markup block - Gen - 65 - (0:0,0) HtmlTokenType.Transition;[@]; Markup span - Gen - [hi] - SpanEditHandler;Accepts:Any - (38:0,38) - Tokens:1 HtmlTokenType.Text;[hi]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (43:0,43) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [43..59) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [43..59) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly29.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly29.stree.txt index 0ae6065f5e..11b6fc8f3e 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly29.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly29.stree.txt @@ -31,9 +31,10 @@ Markup block - Gen - 97 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (75:0,75) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [75..91) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [75..91) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly30.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly30.stree.txt index 91eadbe144..41c7885beb 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly30.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly30.stree.txt @@ -9,20 +9,20 @@ Markup block - Gen - 78 - (0:0,0) catchAll - DoubleQuotes Markup span - Gen - [hi] - SpanEditHandler;Accepts:Any - (36:0,36) - Tokens:1 HtmlTokenType.Text;[hi]; - Markup span - Gen - [words] - SpanEditHandler;Accepts:Any - (41:0,41) - Tokens:1 - HtmlTokenType.Text;[words]; + SyntaxKind.HtmlText - [words] - [41..46) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[words]; Tag block - Gen - 8 - (46:0,46) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (46:0,46) - Tokens:3 HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[strong]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [and] - SpanEditHandler;Accepts:Any - (54:0,54) - Tokens:1 - HtmlTokenType.Text;[and]; + SyntaxKind.HtmlText - [and] - [54..57) - FullWidth: 3 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[and]; Tag block - Gen - 9 - (57:0,57) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (57:0,57) - Tokens:4 HtmlTokenType.OpenAngle;[<]; HtmlTokenType.ForwardSlash;[/]; HtmlTokenType.Text;[strong]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [spaces] - SpanEditHandler;Accepts:Any - (66:0,66) - Tokens:1 - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [spaces] - [66..72) - FullWidth: 6 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly7.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly7.stree.txt index bc8211a69b..9dcffabe84 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly7.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly7.stree.txt @@ -4,9 +4,10 @@ Markup block - Gen - 35 - (0:0,0) class - DoubleQuotes Markup span - Gen - [btn] - SpanEditHandler;Accepts:Any - (10:0,10) - Tokens:1 HtmlTokenType.Text;[btn]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (15:0,15) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [15..31) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [15..31) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly8.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly8.stree.txt index 88b241fa8d..18416f3cc4 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly8.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly8.stree.txt @@ -11,9 +11,10 @@ Markup block - Gen - 45 - (0:0,0) CSharpTokenType.Identifier;[DateTime]; CSharpTokenType.Dot;[.]; CSharpTokenType.Identifier;[Now]; - Markup span - Gen - [words and spaces] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:5 - HtmlTokenType.Text;[words]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[and]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [words and spaces] - [25..41) - FullWidth: 16 - Slots: 1 + SyntaxKind.List - [words and spaces] - [25..41) - FullWidth: 16 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[words]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[and]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly9.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly9.stree.txt index 012c1cafd0..3d76bacf64 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly9.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly9.stree.txt @@ -4,20 +4,20 @@ Markup block - Gen - 50 - (0:0,0) class - DoubleQuotes Markup span - Gen - [btn] - SpanEditHandler;Accepts:Any - (10:0,10) - Tokens:1 HtmlTokenType.Text;[btn]; - Markup span - Gen - [words] - SpanEditHandler;Accepts:Any - (15:0,15) - Tokens:1 - HtmlTokenType.Text;[words]; + SyntaxKind.HtmlText - [words] - [15..20) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[words]; Tag block - Gen - 8 - (20:0,20) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (20:0,20) - Tokens:3 HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[strong]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [and] - SpanEditHandler;Accepts:Any - (28:0,28) - Tokens:1 - HtmlTokenType.Text;[and]; + SyntaxKind.HtmlText - [and] - [28..31) - FullWidth: 3 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[and]; Tag block - Gen - 9 - (31:0,31) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (31:0,31) - Tokens:4 HtmlTokenType.OpenAngle;[<]; HtmlTokenType.ForwardSlash;[/]; HtmlTokenType.Text;[strong]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [spaces] - SpanEditHandler;Accepts:Any - (40:0,40) - Tokens:1 - HtmlTokenType.Text;[spaces]; + SyntaxKind.HtmlText - [spaces] - [40..46) - FullWidth: 6 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[spaces]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RewritesNestedTagHelperTagBlocks2.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RewritesNestedTagHelperTagBlocks2.stree.txt index a584ab11d6..81d8a7532f 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RewritesNestedTagHelperTagBlocks2.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RewritesNestedTagHelperTagBlocks2.stree.txt @@ -1,10 +1,11 @@ Markup block - Gen - 30 - (0:0,0) Tag block - Gen - 30 - (0:0,0) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [Hello World ] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:4 - HtmlTokenType.Text;[Hello]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[World]; - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [Hello World ] - [3..15) - FullWidth: 12 - Slots: 1 + SyntaxKind.List - [Hello World ] - [3..15) - FullWidth: 12 - Slots: 4 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[World]; + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 11 - (15:0,15) - div - divtaghelper StartTagAndEndTag -
...
diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RewritesNestedTagHelperTagBlocks3.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RewritesNestedTagHelperTagBlocks3.stree.txt index 95f7c3c249..356b41b4fe 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RewritesNestedTagHelperTagBlocks3.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RewritesNestedTagHelperTagBlocks3.stree.txt @@ -1,17 +1,17 @@ Markup block - Gen - 43 - (0:0,0) Tag block - Gen - 19 - (0:0,0) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [Hel] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:1 - HtmlTokenType.Text;[Hel]; + SyntaxKind.HtmlText - [Hel] - [3..6) - FullWidth: 3 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Hel]; Tag block - Gen - 9 - (6:0,6) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [lo] - SpanEditHandler;Accepts:Any - (9:0,9) - Tokens:1 - HtmlTokenType.Text;[lo]; - Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (19:0,19) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [lo] - [9..11) - FullWidth: 2 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[lo]; + SyntaxKind.HtmlText - [ ] - [19..20) - FullWidth: 1 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 23 - (20:0,20) - p - ptaghelper StartTagAndEndTag -

...

Tag block - Gen - 16 - (23:0,23) - div - divtaghelper StartTagAndEndTag -
...
- Markup span - Gen - [World] - SpanEditHandler;Accepts:Any - (28:0,28) - Tokens:1 - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [World] - [28..33) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[World]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RewritesNestedTagHelperTagBlocks4.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RewritesNestedTagHelperTagBlocks4.stree.txt index ae4e2a0c86..323ee1b780 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RewritesNestedTagHelperTagBlocks4.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/RewritesNestedTagHelperTagBlocks4.stree.txt @@ -1,23 +1,23 @@ Markup block - Gen - 55 - (0:0,0) Tag block - Gen - 29 - (0:0,0) - p - ptaghelper StartTagAndEndTag -

...

- Markup span - Gen - [Hel] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:1 - HtmlTokenType.Text;[Hel]; + SyntaxKind.HtmlText - [Hel] - [3..6) - FullWidth: 3 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Hel]; Tag block - Gen - 8 - (6:0,6) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (6:0,6) - Tokens:3 HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[strong]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [lo] - SpanEditHandler;Accepts:Any - (14:0,14) - Tokens:1 - HtmlTokenType.Text;[lo]; + SyntaxKind.HtmlText - [lo] - [14..16) - FullWidth: 2 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[lo]; Tag block - Gen - 9 - (16:0,16) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (16:0,16) - Tokens:4 HtmlTokenType.OpenAngle;[<]; HtmlTokenType.ForwardSlash;[/]; HtmlTokenType.Text;[strong]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (29:0,29) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [ ] - [29..30) - FullWidth: 1 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 25 - (30:0,30) - p - ptaghelper StartTagAndEndTag -

...

Tag block - Gen - 6 - (33:0,33) @@ -25,8 +25,8 @@ Markup block - Gen - 55 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[span]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [World] - SpanEditHandler;Accepts:Any - (39:0,39) - Tokens:1 - HtmlTokenType.Text;[World]; + SyntaxKind.HtmlText - [World] - [39..44) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[World]; Tag block - Gen - 7 - (44:0,44) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (44:0,44) - Tokens:4 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren10.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren10.stree.txt index b2a07fedaf..c10ea3664c 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren10.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren10.stree.txt @@ -3,8 +3,8 @@ Markup block - Gen - 69 - (0:0,0) StartTagAndEndTag -

...

Tag block - Gen - 47 - (3:0,3) - strong - StrongTagHelper StartTagAndEndTag - ... - Markup span - Gen - [Title:] - SpanEditHandler;Accepts:Any - (11:0,11) - Tokens:1 - HtmlTokenType.Text;[Title:]; + SyntaxKind.HtmlText - [Title:] - [11..17) - FullWidth: 6 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Title:]; Tag block - Gen - 4 - (17:0,17) - br - BRTagHelper StartTagOnly -
Tag block - Gen - 4 - (21:0,21) @@ -12,12 +12,13 @@ Markup block - Gen - 69 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[em]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [A Very Cool] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:5 - HtmlTokenType.Text;[A]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[Very]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[Cool]; + SyntaxKind.HtmlText - [A Very Cool] - [25..36) - FullWidth: 11 - Slots: 1 + SyntaxKind.List - [A Very Cool] - [25..36) - FullWidth: 11 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[A]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[Very]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[Cool]; Tag block - Gen - 5 - (36:0,36) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (36:0,36) - Tokens:4 HtmlTokenType.OpenAngle;[<]; @@ -26,5 +27,5 @@ Markup block - Gen - 69 - (0:0,0) HtmlTokenType.CloseAngle;[>]; Tag block - Gen - 6 - (50:0,50) - br - BRTagHelper SelfClosing -
- Markup span - Gen - [Something] - SpanEditHandler;Accepts:Any - (56:0,56) - Tokens:1 - HtmlTokenType.Text;[Something]; + SyntaxKind.HtmlText - [Something] - [56..65) - FullWidth: 9 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Something]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren11.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren11.stree.txt index 240e049f63..27fbb13343 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren11.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren11.stree.txt @@ -6,8 +6,8 @@ Markup block - Gen - 69 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[custom]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [Title:] - SpanEditHandler;Accepts:Any - (11:0,11) - Tokens:1 - HtmlTokenType.Text;[Title:]; + SyntaxKind.HtmlText - [Title:] - [11..17) - FullWidth: 6 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Title:]; Tag block - Gen - 4 - (17:0,17) - br - BRTagHelper StartTagOnly -
Tag block - Gen - 4 - (21:0,21) @@ -15,12 +15,13 @@ Markup block - Gen - 69 - (0:0,0) HtmlTokenType.OpenAngle;[<]; HtmlTokenType.Text;[em]; HtmlTokenType.CloseAngle;[>]; - Markup span - Gen - [A Very Cool] - SpanEditHandler;Accepts:Any - (25:0,25) - Tokens:5 - HtmlTokenType.Text;[A]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[Very]; - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[Cool]; + SyntaxKind.HtmlText - [A Very Cool] - [25..36) - FullWidth: 11 - Slots: 1 + SyntaxKind.List - [A Very Cool] - [25..36) - FullWidth: 11 - Slots: 5 + SyntaxKind.HtmlTextLiteralToken;[A]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[Very]; + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[Cool]; Tag block - Gen - 5 - (36:0,36) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (36:0,36) - Tokens:4 HtmlTokenType.OpenAngle;[<]; @@ -35,5 +36,5 @@ Markup block - Gen - 69 - (0:0,0) HtmlTokenType.CloseAngle;[>]; Tag block - Gen - 6 - (50:0,50) - br - BRTagHelper SelfClosing -
- Markup span - Gen - [Something] - SpanEditHandler;Accepts:Any - (56:0,56) - Tokens:1 - HtmlTokenType.Text;[Something]; + SyntaxKind.HtmlText - [Something] - [56..65) - FullWidth: 9 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Something]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren14.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren14.stree.txt index 4751517c44..44b41388f0 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren14.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren14.stree.txt @@ -8,16 +8,16 @@ Markup block - Gen - 76 - (0:0,0) HtmlTokenType.CloseAngle;[>]; Tag block - Gen - 4 - (11:0,11) - br - BRTagHelper StartTagOnly -
- Markup span - Gen - [:] - SpanEditHandler;Accepts:Any - (15:0,15) - Tokens:1 - HtmlTokenType.Text;[:]; + SyntaxKind.HtmlText - [:] - [15..16) - FullWidth: 1 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[:]; Tag block - Gen - 39 - (16:0,16) - strong - StrongTagHelper StartTagAndEndTag - ... Tag block - Gen - 22 - (24:0,24) - strong - StrongTagHelper StartTagAndEndTag - ... - Markup span - Gen - [Hello] - SpanEditHandler;Accepts:Any - (32:0,32) - Tokens:1 - HtmlTokenType.Text;[Hello]; - Markup span - Gen - [:] - SpanEditHandler;Accepts:Any - (55:0,55) - Tokens:1 - HtmlTokenType.Text;[:]; + SyntaxKind.HtmlText - [Hello] - [32..37) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Hello]; + SyntaxKind.HtmlText - [:] - [55..56) - FullWidth: 1 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[:]; Tag block - Gen - 7 - (56:0,56) Markup span - Gen - [] - SpanEditHandler;Accepts:Any - (56:0,56) - Tokens:3 HtmlTokenType.OpenAngle;[<]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren2.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren2.stree.txt index 030417ade1..435494aff1 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren2.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren2.stree.txt @@ -1,9 +1,9 @@ Markup block - Gen - 17 - (0:0,0) Tag block - Gen - 17 - (0:0,0) - p - PTagHelper StartTagAndEndTag -

...

- Markup span - Gen - [LF] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:1 - HtmlTokenType.NewLine;[LF]; + SyntaxKind.HtmlText - [LF] - [3..5) - FullWidth: 2 - Slots: 1 + SyntaxKind.NewLine;[LF]; Tag block - Gen - 6 - (5:1,0) - br - BRTagHelper SelfClosing -
- Markup span - Gen - [LF] - SpanEditHandler;Accepts:Any - (11:1,6) - Tokens:1 - HtmlTokenType.NewLine;[LF]; + SyntaxKind.HtmlText - [LF] - [11..13) - FullWidth: 2 - Slots: 1 + SyntaxKind.NewLine;[LF]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren4.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren4.stree.txt index 5c64fe7293..80028cb3b4 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren4.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren4.stree.txt @@ -1,5 +1,5 @@ Markup block - Gen - 12 - (0:0,0) Tag block - Gen - 12 - (0:0,0) - p - PTagHelper StartTagAndEndTag -

...

- Markup span - Gen - [Hello] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:1 - HtmlTokenType.Text;[Hello]; + SyntaxKind.HtmlText - [Hello] - [3..8) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Hello]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren6.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren6.stree.txt index 44ab808bfc..5c4530d693 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren6.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren6.stree.txt @@ -3,5 +3,5 @@ Markup block - Gen - 16 - (0:0,0) StartTagAndEndTag -

...

Tag block - Gen - 4 - (3:0,3) - br - BRTagHelper StartTagOnly -
- Markup span - Gen - [Hello] - SpanEditHandler;Accepts:Any - (7:0,7) - Tokens:1 - HtmlTokenType.Text;[Hello]; + SyntaxKind.HtmlText - [Hello] - [7..12) - FullWidth: 5 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Hello]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren7.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren7.stree.txt index 944b6b2068..35addd3c14 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren7.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren7.stree.txt @@ -3,9 +3,9 @@ Markup block - Gen - 45 - (0:0,0) StartTagAndEndTag -

...

Tag block - Gen - 23 - (3:0,3) - strong - StrongTagHelper StartTagAndEndTag - ... - Markup span - Gen - [Title:] - SpanEditHandler;Accepts:Any - (11:0,11) - Tokens:1 - HtmlTokenType.Text;[Title:]; + SyntaxKind.HtmlText - [Title:] - [11..17) - FullWidth: 6 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Title:]; Tag block - Gen - 6 - (26:0,26) - br - BRTagHelper SelfClosing -
- Markup span - Gen - [Something] - SpanEditHandler;Accepts:Any - (32:0,32) - Tokens:1 - HtmlTokenType.Text;[Something]; + SyntaxKind.HtmlText - [Something] - [32..41) - FullWidth: 9 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Something]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren8.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren8.stree.txt index 944b6b2068..35addd3c14 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren8.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren8.stree.txt @@ -3,9 +3,9 @@ Markup block - Gen - 45 - (0:0,0) StartTagAndEndTag -

...

Tag block - Gen - 23 - (3:0,3) - strong - StrongTagHelper StartTagAndEndTag - ... - Markup span - Gen - [Title:] - SpanEditHandler;Accepts:Any - (11:0,11) - Tokens:1 - HtmlTokenType.Text;[Title:]; + SyntaxKind.HtmlText - [Title:] - [11..17) - FullWidth: 6 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Title:]; Tag block - Gen - 6 - (26:0,26) - br - BRTagHelper SelfClosing -
- Markup span - Gen - [Something] - SpanEditHandler;Accepts:Any - (32:0,32) - Tokens:1 - HtmlTokenType.Text;[Something]; + SyntaxKind.HtmlText - [Something] - [32..41) - FullWidth: 9 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Something]; diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren9.stree.txt b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren9.stree.txt index 08853feef9..7ee594fd39 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren9.stree.txt +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/ParserTests/TagHelperParseTreeRewriterTest/UnderstandsAllowedChildren9.stree.txt @@ -1,16 +1,17 @@ Markup block - Gen - 51 - (0:0,0) Tag block - Gen - 51 - (0:0,0) - p - PTagHelper StartTagAndEndTag -

...

- Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (3:0,3) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [ ] - [3..5) - FullWidth: 2 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 23 - (5:0,5) - strong - StrongTagHelper StartTagAndEndTag - ... - Markup span - Gen - [Title:] - SpanEditHandler;Accepts:Any - (13:0,13) - Tokens:1 - HtmlTokenType.Text;[Title:]; - Markup span - Gen - [ ] - SpanEditHandler;Accepts:Any - (28:0,28) - Tokens:1 - HtmlTokenType.WhiteSpace;[ ]; + SyntaxKind.HtmlText - [Title:] - [13..19) - FullWidth: 6 - Slots: 1 + SyntaxKind.HtmlTextLiteralToken;[Title:]; + SyntaxKind.HtmlText - [ ] - [28..30) - FullWidth: 2 - Slots: 1 + SyntaxKind.Whitespace;[ ]; Tag block - Gen - 6 - (30:0,30) - br - BRTagHelper SelfClosing -
- Markup span - Gen - [ Something] - SpanEditHandler;Accepts:Any - (36:0,36) - Tokens:2 - HtmlTokenType.WhiteSpace;[ ]; - HtmlTokenType.Text;[Something]; + SyntaxKind.HtmlText - [ Something] - [36..47) - FullWidth: 11 - Slots: 1 + SyntaxKind.List - [ Something] - [36..47) - FullWidth: 11 - Slots: 2 + SyntaxKind.Whitespace;[ ]; + SyntaxKind.HtmlTextLiteralToken;[Something]; diff --git a/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/RawTextToken.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/RawTextToken.cs index 943ed7ffce..b1b1452048 100644 --- a/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/RawTextToken.cs +++ b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/RawTextToken.cs @@ -1,8 +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 System; using System.Globalization; +using Microsoft.AspNetCore.Razor.Language.Syntax.InternalSyntax; namespace Microsoft.AspNetCore.Razor.Language.Legacy { @@ -18,6 +18,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy public string Content { get; } public Span Parent { get; set; } + public SyntaxKind SyntaxKind => SyntaxToken.Kind; + + public SyntaxToken SyntaxToken => SyntaxFactory.UnknownToken(Content); + public override bool Equals(object obj) { var other = obj as RawTextToken; diff --git a/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxTreeNodeWriter.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxTreeNodeWriter.cs index 227c632192..8e4e344730 100644 --- a/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxTreeNodeWriter.cs +++ b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/Legacy/SyntaxTreeNodeWriter.cs @@ -3,8 +3,10 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; +using Microsoft.AspNetCore.Razor.Language.Syntax; namespace Microsoft.AspNetCore.Razor.Language.Legacy { @@ -173,6 +175,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy protected void WriteSpan(Span span) { + if (span.SyntaxNode != null) + { + WriteSyntaxNode(span.SyntaxNode.CreateRed(null, span.Start.AbsoluteIndex)); + return; + } + WriteIndent(); Write($"{span.Kind} span"); WriteSeparator(); @@ -197,6 +205,49 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Depth--; } + private void WriteSyntaxNode(SyntaxNode syntaxNode) + { + WriteIndent(); + Write($"{typeof(SyntaxKind).Name}.{syntaxNode.Kind}"); + WriteSeparator(); + Write($"[{syntaxNode.ToFullString()}]"); + WriteSeparator(); + Write($"[{syntaxNode.Position}..{syntaxNode.EndPosition})"); + WriteSeparator(); + Write($"FullWidth: {syntaxNode.FullWidth}"); + WriteSeparator(); + Write($"Slots: {syntaxNode.SlotCount}"); + + // Write tokens + Depth++; + for (var i = 0; i < syntaxNode.SlotCount; i++) + { + var slot = syntaxNode.GetNodeSlot(i); + if (slot == null) + { + continue; + } + + WriteNewLine(); + if (slot.IsList || !(slot is SyntaxToken syntaxToken)) + { + WriteSyntaxNode(slot); + continue; + } + + WriteSyntaxToken(syntaxToken); + } + Depth--; + } + + protected void WriteSyntaxToken(SyntaxToken syntaxToken) + { + WriteIndent(); + var diagnostics = syntaxToken.GetDiagnostics(); + var tokenString = $"{typeof(SyntaxKind).Name}.{syntaxToken.Kind};[{syntaxToken.Text}];{string.Join(", ", diagnostics.Select(diagnostic => diagnostic.Id + diagnostic.Span))}"; + Write(tokenString); + } + protected void WriteToken(IToken token) { var tokenType = string.Empty; diff --git a/test/Microsoft.VisualStudio.Editor.Razor.Test/DefaultRazorCompletionFactsServiceTest.cs b/test/Microsoft.VisualStudio.Editor.Razor.Test/DefaultRazorCompletionFactsServiceTest.cs new file mode 100644 index 0000000000..a5f095be0d --- /dev/null +++ b/test/Microsoft.VisualStudio.Editor.Razor.Test/DefaultRazorCompletionFactsServiceTest.cs @@ -0,0 +1,239 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Moq; +using Xunit; + +namespace Microsoft.VisualStudio.Editor.Razor +{ + public class DefaultRazorCompletionFactsServiceTest + { + private static readonly IReadOnlyList DefaultDirectives = new[] + { + CSharpCodeParser.AddTagHelperDirectiveDescriptor, + CSharpCodeParser.RemoveTagHelperDirectiveDescriptor, + CSharpCodeParser.TagHelperPrefixDirectiveDescriptor, + }; + + [Fact] + public void GetDirectiveCompletionItems_ReturnsDefaultDirectivesAsCompletionItems() + { + // Arrange + var syntaxTree = CreateSyntaxTree("@addTag"); + + // Act + var completionItems = DefaultRazorCompletionFactsService.GetDirectiveCompletionItems(syntaxTree); + + // Assert + Assert.Collection( + completionItems, + item => AssertRazorCompletionItem(DefaultDirectives[0], item), + item => AssertRazorCompletionItem(DefaultDirectives[1], item), + item => AssertRazorCompletionItem(DefaultDirectives[2], item)); + } + + [Fact] + public void GetDirectiveCompletionItems_ReturnsCustomDirectivesAsCompletionItems() + { + // Arrange + var customDirective = DirectiveDescriptor.CreateSingleLineDirective("custom", builder => + { + builder.Description = "My Custom Directive."; + }); + var syntaxTree = CreateSyntaxTree("@addTag", customDirective); + + // Act + var completionItems = DefaultRazorCompletionFactsService.GetDirectiveCompletionItems(syntaxTree); + + // Assert + Assert.Collection( + completionItems, + item => AssertRazorCompletionItem(customDirective, item), + item => AssertRazorCompletionItem(DefaultDirectives[0], item), + item => AssertRazorCompletionItem(DefaultDirectives[1], item), + item => AssertRazorCompletionItem(DefaultDirectives[2], item)); + } + + [Fact] + public void GetDirectiveCompletionItems_UsesDisplayNamesWhenNotNull() + { + // Arrange + var customDirective = DirectiveDescriptor.CreateSingleLineDirective("custom", builder => + { + builder.DisplayName = "different"; + builder.Description = "My Custom Directive."; + }); + var syntaxTree = CreateSyntaxTree("@addTag", customDirective); + + // Act + var completionItems = DefaultRazorCompletionFactsService.GetDirectiveCompletionItems(syntaxTree); + + // Assert + Assert.Collection( + completionItems, + item => AssertRazorCompletionItem("different", customDirective, item), + item => AssertRazorCompletionItem(DefaultDirectives[0], item), + item => AssertRazorCompletionItem(DefaultDirectives[1], item), + item => AssertRazorCompletionItem(DefaultDirectives[2], item)); + } + + [Fact] + public void AtDirectiveCompletionPoint_ReturnsFalseIfSyntaxTreeNull() + { + // Act + var result = DefaultRazorCompletionFactsService.AtDirectiveCompletionPoint(syntaxTree: null, location: new SourceSpan(0, 0)); + + // Assert + Assert.False(result); + } + + [Fact] + public void AtDirectiveCompletionPoint_ReturnsFalseIfNoOwner() + { + // Arrange + var syntaxTree = CreateSyntaxTree("@"); + var location = new SourceSpan(2, 0); + + // Act + var result = DefaultRazorCompletionFactsService.AtDirectiveCompletionPoint(syntaxTree, location); + + // Assert + Assert.False(result); + } + + [Fact] + public void AtDirectiveCompletionPoint_ReturnsFalseWhenOwnerIsNotExpression() + { + // Arrange + var syntaxTree = CreateSyntaxTree("@{"); + var location = new SourceSpan(2, 0); + + // Act + var result = DefaultRazorCompletionFactsService.AtDirectiveCompletionPoint(syntaxTree, location); + + // Assert + Assert.False(result); + } + + [Fact] + public void AtDirectiveCompletionPoint_ReturnsFalseWhenOwnerIsComplexExpression() + { + // Arrange + var syntaxTree = CreateSyntaxTree("@DateTime.Now"); + var location = new SourceSpan(2, 0); + + // Act + var result = DefaultRazorCompletionFactsService.AtDirectiveCompletionPoint(syntaxTree, location); + + // Assert + Assert.False(result); + } + + [Fact] + public void AtDirectiveCompletionPoint_ReturnsFalseWhenOwnerIsExplicitExpression() + { + // Arrange + var syntaxTree = CreateSyntaxTree("@(something)"); + var location = new SourceSpan(4, 0); + + // Act + var result = DefaultRazorCompletionFactsService.AtDirectiveCompletionPoint(syntaxTree, location); + + // Assert + Assert.False(result); + } + + [Fact] + public void AtDirectiveCompletionPoint_ReturnsTrueForSimpleImplicitExpressions() + { + // Arrange + var syntaxTree = CreateSyntaxTree("@mod"); + var location = new SourceSpan(2, 0); + + // Act + var result = DefaultRazorCompletionFactsService.AtDirectiveCompletionPoint(syntaxTree, location); + + // Assert + Assert.True(result); + } + + [Fact] + public void IsDirectiveCompletableToken_ReturnsTrueForCSharpIdentifiers() + { + // Arrange + var csharpToken = new CSharpToken("model", CSharpTokenType.Identifier); + + // Act + var result = DefaultRazorCompletionFactsService.IsDirectiveCompletableToken(csharpToken); + + // Assert + Assert.True(result); + } + + [Fact] + public void IsDirectiveCompletableToken_ReturnsTrueForCSharpMarkerTokens() + { + // Arrange + var csharpToken = new CSharpToken(string.Empty, CSharpTokenType.Unknown); + + // Act + var result = DefaultRazorCompletionFactsService.IsDirectiveCompletableToken(csharpToken); + + // Assert + Assert.True(result); + } + + [Fact] + public void IsDirectiveCompletableToken_ReturnsFalseForNonCSharpTokens() + { + // Arrange + var token = Mock.Of(); + + // Act + var result = DefaultRazorCompletionFactsService.IsDirectiveCompletableToken(token); + + // Assert + Assert.False(result); + } + + [Fact] + public void IsDirectiveCompletableToken_ReturnsFalseForInvalidCSharpTokens() + { + // Arrange + var csharpToken = new CSharpToken("~", CSharpTokenType.Tilde); + + // Act + var result = DefaultRazorCompletionFactsService.IsDirectiveCompletableToken(csharpToken); + + // Assert + Assert.False(result); + } + + private static void AssertRazorCompletionItem(string completionDisplayText, DirectiveDescriptor directive, RazorCompletionItem item) + { + Assert.Equal(item.DisplayText, completionDisplayText); + Assert.Equal(item.InsertText, directive.Directive); + Assert.Equal(directive.Description, item.Description); + } + + private static void AssertRazorCompletionItem(DirectiveDescriptor directive, RazorCompletionItem item) => + AssertRazorCompletionItem(directive.Directive, directive, item); + + private static RazorSyntaxTree CreateSyntaxTree(string text, params DirectiveDescriptor[] directives) + { + var sourceDocument = TestRazorSourceDocument.Create(text); + var options = RazorParserOptions.Create(builder => + { + foreach (var directive in directives) + { + builder.Directives.Add(directive); + } + }); + var syntaxTree = RazorSyntaxTree.Parse(sourceDocument, options); + return syntaxTree; + } + } +} diff --git a/test/Microsoft.VisualStudio.Editor.Razor.Test/RazorDirectiveCompletionProviderTest.cs b/test/Microsoft.VisualStudio.Editor.Razor.Test/RazorDirectiveCompletionProviderTest.cs index 1b76f772b6..cd35510b36 100644 --- a/test/Microsoft.VisualStudio.Editor.Razor.Test/RazorDirectiveCompletionProviderTest.cs +++ b/test/Microsoft.VisualStudio.Editor.Razor.Test/RazorDirectiveCompletionProviderTest.cs @@ -4,51 +4,39 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.ComponentModel.Composition; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Language; -using Microsoft.AspNetCore.Razor.Language.Extensions; -using Microsoft.AspNetCore.Razor.Language.Legacy; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Completion; using Microsoft.CodeAnalysis.Options; -using Microsoft.CodeAnalysis.Tags; using Microsoft.CodeAnalysis.Text; +using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion; using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Utilities; using Moq; using Xunit; +using ITextBuffer = Microsoft.VisualStudio.Text.ITextBuffer; namespace Microsoft.VisualStudio.Editor.Razor { public class RazorDirectiveCompletionProviderTest { - private static readonly IReadOnlyList DefaultDirectives = new[] + public RazorDirectiveCompletionProviderTest() { - CSharpCodeParser.AddTagHelperDirectiveDescriptor, - CSharpCodeParser.RemoveTagHelperDirectiveDescriptor, - CSharpCodeParser.TagHelperPrefixDirectiveDescriptor, - }; - - [Fact] - public void AtDirectiveCompletionPoint_ReturnsFalseIfChangeHasNoOwner() - { - // Arrange - var codeDocumentProvider = CreateCodeDocumentProvider("@", Enumerable.Empty()); - var completionProvider = new FailOnGetCompletionsProvider(codeDocumentProvider); - var document = CreateDocument(); - codeDocumentProvider.Value.TryGetFromDocument(document, out var codeDocument); - var syntaxTree = codeDocument.GetSyntaxTree(); - var completionContext = CreateContext(2, completionProvider, document); - - // Act - var result = completionProvider.AtDirectiveCompletionPoint(syntaxTree, completionContext); - - // Assert - Assert.False(result); + CompletionBroker = Mock.Of(broker => broker.IsCompletionSupported(It.IsAny()) == true); + var razorBuffer = Mock.Of(buffer => buffer.ContentType == Mock.Of()); + TextBufferProvider = Mock.Of(provider => provider.TryGetFromDocument(It.IsAny(), out razorBuffer) == true); + CompletionFactsService = new DefaultRazorCompletionFactsService(); } + private IAsyncCompletionBroker CompletionBroker { get; } + + private RazorTextBufferProvider TextBufferProvider { get; } + + private RazorCompletionFactsService CompletionFactsService { get; } + [Fact] public async Task GetDescriptionAsync_AddsDirectiveDescriptionIfPropertyExists() { @@ -61,7 +49,11 @@ namespace Microsoft.VisualStudio.Editor.Razor [RazorDirectiveCompletionProvider.DescriptionKey] = expectedDescription, }).ToImmutableDictionary()); var codeDocumentProvider = new Mock(); - var completionProvider = new RazorDirectiveCompletionProvider(new Lazy(() => codeDocumentProvider.Object)); + var completionProvider = new RazorDirectiveCompletionProvider( + new Lazy(() => codeDocumentProvider.Object), + new Lazy(() => CompletionFactsService), + CompletionBroker, + TextBufferProvider); // Act var description = await completionProvider.GetDescriptionAsync(document, item, CancellationToken.None); @@ -80,7 +72,11 @@ namespace Microsoft.VisualStudio.Editor.Razor var document = CreateDocument(); var item = CompletionItem.Create("TestDirective"); var codeDocumentProvider = new Mock(); - var completionProvider = new RazorDirectiveCompletionProvider(new Lazy(() => codeDocumentProvider.Object)); + var completionProvider = new RazorDirectiveCompletionProvider( + new Lazy(() => codeDocumentProvider.Object), + new Lazy(() => CompletionFactsService), + CompletionBroker, + TextBufferProvider); // Act var description = await completionProvider.GetDescriptionAsync(document, item, CancellationToken.None); @@ -95,7 +91,10 @@ namespace Microsoft.VisualStudio.Editor.Razor { // Arrange var codeDocumentProvider = new Mock(MockBehavior.Strict); - var completionProvider = new FailOnGetCompletionsProvider(new Lazy(() => codeDocumentProvider.Object)); + var completionProvider = new FailOnGetCompletionsProvider( + new Lazy(() => codeDocumentProvider.Object), + CompletionBroker, + TextBufferProvider); var document = CreateDocument(); document = document.WithFilePath("NotRazor.cs"); var context = CreateContext(1, completionProvider, document); @@ -104,7 +103,6 @@ namespace Microsoft.VisualStudio.Editor.Razor await completionProvider.ProvideCompletionsAsync(context); } - [Fact] public async Task ProvideCompletionAsync_DoesNotProvideCompletionsForDocumentWithoutPath() { @@ -121,7 +119,10 @@ namespace Microsoft.VisualStudio.Editor.Razor }); var codeDocumentProvider = new Mock(MockBehavior.Strict); - var completionProvider = new FailOnGetCompletionsProvider(new Lazy(() => codeDocumentProvider.Object)); + var completionProvider = new FailOnGetCompletionsProvider( + new Lazy(() => codeDocumentProvider.Object), + CompletionBroker, + TextBufferProvider); var context = CreateContext(1, completionProvider, document); // Act & Assert @@ -136,7 +137,10 @@ namespace Microsoft.VisualStudio.Editor.Razor var codeDocumentProvider = new Mock(); codeDocumentProvider.Setup(provider => provider.TryGetFromDocument(It.IsAny(), out codeDocument)) .Returns(false); - var completionProvider = new FailOnGetCompletionsProvider(new Lazy(() => codeDocumentProvider.Object)); + var completionProvider = new FailOnGetCompletionsProvider( + new Lazy(() => codeDocumentProvider.Object), + CompletionBroker, + TextBufferProvider); var document = CreateDocument(); var context = CreateContext(1, completionProvider, document); @@ -149,7 +153,11 @@ namespace Microsoft.VisualStudio.Editor.Razor { // Arrange var codeDocumentProvider = CreateCodeDocumentProvider("@", Enumerable.Empty()); - var completionProvider = new FailOnGetCompletionsProvider(codeDocumentProvider, false); + var completionProvider = new FailOnGetCompletionsProvider( + codeDocumentProvider, + CompletionBroker, + TextBufferProvider, + canGetSnapshotPoint: false); var document = CreateDocument(); var context = CreateContext(0, completionProvider, document); @@ -157,142 +165,6 @@ namespace Microsoft.VisualStudio.Editor.Razor await completionProvider.ProvideCompletionsAsync(context); } - [Fact] - public async Task ProvideCompletionAsync_DoesNotProvideCompletionsWhenNotAtCompletionPoint() - { - // Arrange - var codeDocumentProvider = CreateCodeDocumentProvider("@", Enumerable.Empty()); - var completionProvider = new FailOnGetCompletionsProvider(codeDocumentProvider); - var document = CreateDocument(); - var context = CreateContext(0, completionProvider, document); - - // Act & Assert - await completionProvider.ProvideCompletionsAsync(context); - } - - [Theory] - [InlineData("DateTime.Now")] - [InlineData("SomeMethod()")] - public async Task ProvideCompletionAsync_DoesNotProvideCompletionsWhenAtComplexExpressions(string content) - { - // Arrange - var codeDocumentProvider = CreateCodeDocumentProvider("@" + content, Enumerable.Empty()); - var completionProvider = new FailOnGetCompletionsProvider(codeDocumentProvider); - var document = CreateDocument(); - var context = CreateContext(1, completionProvider, document); - - // Act & Assert - await completionProvider.ProvideCompletionsAsync(context); - } - - [Fact] - public async Task ProvideCompletionAsync_DoesNotProvideCompletionsForExplicitExpressions() - { - // Arrange - var codeDocumentProvider = CreateCodeDocumentProvider("@()", Enumerable.Empty()); - var completionProvider = new FailOnGetCompletionsProvider(codeDocumentProvider); - var document = CreateDocument(); - var context = CreateContext(2, completionProvider, document); - - // Act & Assert - await completionProvider.ProvideCompletionsAsync(context); - } - - [Fact] - public async Task ProvideCompletionAsync_DoesNotProvideCompletionsForCodeDocumentWithoutSyntaxTree() - { - // Arrange - var codeDocumentProvider = new Mock(); - var codeDocument = TestRazorCodeDocument.CreateEmpty(); - codeDocumentProvider.Setup(provider => provider.TryGetFromDocument(It.IsAny(), out codeDocument)) - .Returns(true); - var completionProvider = new FailOnGetCompletionsProvider(new Lazy(() => codeDocumentProvider.Object)); - var document = CreateDocument(); - var context = CreateContext(2, completionProvider, document); - - // Act & Assert - await completionProvider.ProvideCompletionsAsync(context); - } - - [Fact] - public void GetCompletionItems_ProvidesCompletionsForDefaultDirectives() - { - // Arrange - var codeDocumentProvider = CreateCodeDocumentProvider("@", Enumerable.Empty()); - var completionProvider = new RazorDirectiveCompletionProvider(codeDocumentProvider); - var document = CreateDocument(); - codeDocumentProvider.Value.TryGetFromDocument(document, out var codeDocument); - var syntaxTree = codeDocument.GetSyntaxTree(); - - // Act - var completionItems = completionProvider.GetCompletionItems(syntaxTree); - - // Assert - Assert.Collection( - completionItems, - item => AssertRazorCompletionItem(DefaultDirectives[0].Description, item), - item => AssertRazorCompletionItem(DefaultDirectives[1].Description, item), - item => AssertRazorCompletionItem(DefaultDirectives[2].Description, item)); - } - - [Fact] - public void GetCompletionItems_ProvidesCompletionsForDefaultAndExtensibleDirectives() - { - // Arrange - var codeDocumentProvider = CreateCodeDocumentProvider("@", new[] { SectionDirective.Directive }); - var completionProvider = new RazorDirectiveCompletionProvider(codeDocumentProvider); - var document = CreateDocument(); - codeDocumentProvider.Value.TryGetFromDocument(document, out var codeDocument); - var syntaxTree = codeDocument.GetSyntaxTree(); - - // Act - var completionItems = completionProvider.GetCompletionItems(syntaxTree); - - // Assert - Assert.Collection( - completionItems, - item => AssertRazorCompletionItem(SectionDirective.Directive.Description, item), - item => AssertRazorCompletionItem(DefaultDirectives[0].Description, item), - item => AssertRazorCompletionItem(DefaultDirectives[1].Description, item), - item => AssertRazorCompletionItem(DefaultDirectives[2].Description, item)); - } - - [Fact] - public void GetCompletionItems_ProvidesCompletionsForDirectivesWithoutDescription() - { - // Arrange - var customDirective = DirectiveDescriptor.CreateSingleLineDirective("custom"); - var codeDocumentProvider = CreateCodeDocumentProvider("@", new[] { customDirective }); - var completionProvider = new RazorDirectiveCompletionProvider(codeDocumentProvider); - var document = CreateDocument(); - codeDocumentProvider.Value.TryGetFromDocument(document, out var codeDocument); - var syntaxTree = codeDocument.GetSyntaxTree(); - - // Act - var completionItems = completionProvider.GetCompletionItems(syntaxTree); - - // Assert - var customDirectiveCompletion = Assert.Single(completionItems, item => item.DisplayText == customDirective.Directive); - AssertRazorCompletionItemDefaults(customDirectiveCompletion); - Assert.DoesNotContain(customDirectiveCompletion.Properties, property => property.Key == RazorDirectiveCompletionProvider.DescriptionKey); - } - - private static void AssertRazorCompletionItem(string expectedDescription, CompletionItem item) - { - Assert.True(item.Properties.TryGetValue(RazorDirectiveCompletionProvider.DescriptionKey, out var actualDescription)); - Assert.Equal(expectedDescription, actualDescription); - - AssertRazorCompletionItemDefaults(item); - } - - private static void AssertRazorCompletionItemDefaults(CompletionItem item) - { - Assert.Equal("_RazorDirective_", item.SortText); - Assert.False(item.Rules.FormatOnCommit); - var tag = Assert.Single(item.Tags); - Assert.Equal(WellKnownTags.Intrinsic, tag); - } - private static Lazy CreateCodeDocumentProvider(string text, IEnumerable directives) { var codeDocumentProvider = new Mock(); @@ -348,18 +220,16 @@ namespace Microsoft.VisualStudio.Editor.Razor { private readonly bool _canGetSnapshotPoint; - public FailOnGetCompletionsProvider(Lazy codeDocumentProvider, bool canGetSnapshotPoint = true) - : base(codeDocumentProvider) + public FailOnGetCompletionsProvider( + Lazy codeDocumentProvider, + IAsyncCompletionBroker asyncCompletionBroker, + RazorTextBufferProvider textBufferProvider, + bool canGetSnapshotPoint = true) + : base(codeDocumentProvider, new Lazy(() => new DefaultRazorCompletionFactsService()), asyncCompletionBroker, textBufferProvider) { _canGetSnapshotPoint = canGetSnapshotPoint; } - internal override IEnumerable GetCompletionItems(RazorSyntaxTree syntaxTree) - { - Assert.False(true, "Completions should not have been attempted."); - return null; - } - protected override bool TryGetRazorSnapshotPoint(CompletionContext context, out SnapshotPoint snapshotPoint) { if (!_canGetSnapshotPoint) diff --git a/test/Microsoft.VisualStudio.Editor.Razor.Test/RazorDirectiveCompletionSourceProviderTest.cs b/test/Microsoft.VisualStudio.Editor.Razor.Test/RazorDirectiveCompletionSourceProviderTest.cs new file mode 100644 index 0000000000..ac8dba7e3c --- /dev/null +++ b/test/Microsoft.VisualStudio.Editor.Razor.Test/RazorDirectiveCompletionSourceProviderTest.cs @@ -0,0 +1,101 @@ +// 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.ObjectModel; +using Microsoft.CodeAnalysis.Razor; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.Text.Editor; +using Microsoft.VisualStudio.Text.Projection; +using Microsoft.VisualStudio.Utilities; +using Moq; +using Xunit; + +namespace Microsoft.VisualStudio.Editor.Razor +{ + public class RazorDirectiveCompletionSourceProviderTest : ForegroundDispatcherTestBase + { + private IContentType RazorContentType { get; } = Mock.Of(c => c.IsOfType(RazorLanguage.ContentType) == true); + + private IContentType NonRazorContentType { get; } = Mock.Of(c => c.IsOfType(It.IsAny()) == false); + + private RazorCompletionFactsService CompletionFactsService { get; } = Mock.Of(); + + [Fact] + public void CreateCompletionSource_ReturnsNullIfParserHasNotBeenAssocitedWithRazorBuffer() + { + // Arrange + var expectedParser = Mock.Of(); + var properties = new PropertyCollection(); + properties.AddProperty(typeof(VisualStudioRazorParser), expectedParser); + var razorBuffer = Mock.Of(buffer => buffer.ContentType == RazorContentType && buffer.Properties == properties); + var completionSourceProvider = new RazorDirectiveCompletionSourceProvider(Dispatcher, CompletionFactsService); + + // Act + var completionSource = completionSourceProvider.CreateCompletionSource(razorBuffer); + + // Assert + var completionSourceImpl = Assert.IsType(completionSource); + Assert.Same(expectedParser, completionSourceImpl._parser); + } + + [Fact] + public void CreateCompletionSource_CreatesACompletionSourceWithTextBuffersParser() + { + // Arrange + var razorBuffer = Mock.Of(buffer => buffer.ContentType == RazorContentType && buffer.Properties == new PropertyCollection()); + var completionSourceProvider = new RazorDirectiveCompletionSourceProvider(Dispatcher, CompletionFactsService); + + // Act + var completionSource = completionSourceProvider.CreateCompletionSource(razorBuffer); + + // Assert + Assert.Null(completionSource); + } + + [Fact] + public void GetOrCreate_ReturnsNullIfRazorBufferHasNotBeenAssociatedWithTextView() + { + // Arrange + var textView = CreateTextView(NonRazorContentType, new PropertyCollection()); + var completionSourceProvider = new RazorDirectiveCompletionSourceProvider(Dispatcher, CompletionFactsService); + + // Act + var completionSource = completionSourceProvider.GetOrCreate(textView); + + // Assert + Assert.Null(completionSource); + } + + [Fact] + public void GetOrCreate_CachesCompletionSource() + { + // Arrange + var expectedParser = Mock.Of(); + var properties = new PropertyCollection(); + properties.AddProperty(typeof(VisualStudioRazorParser), expectedParser); + var textView = CreateTextView(RazorContentType, properties); + var completionSourceProvider = new RazorDirectiveCompletionSourceProvider(Dispatcher, CompletionFactsService); + + // Act + var completionSource1 = completionSourceProvider.GetOrCreate(textView); + var completionSource2 = completionSourceProvider.GetOrCreate(textView); + + // Assert + Assert.Same(completionSource1, completionSource2); + } + + private static ITextView CreateTextView(IContentType contentType, PropertyCollection properties) + { + var bufferGraph = new Mock(); + bufferGraph.Setup(graph => graph.GetTextBuffers(It.IsAny>())) + .Returns(new Collection() + { + Mock.Of(buffer => buffer.ContentType == contentType && buffer.Properties == properties) + }); + var textView = Mock.Of(view => view.BufferGraph == bufferGraph.Object); + + return textView; + } + } +} diff --git a/test/Microsoft.VisualStudio.Editor.Razor.Test/RazorDirectiveCompletionSourceTest.cs b/test/Microsoft.VisualStudio.Editor.Razor.Test/RazorDirectiveCompletionSourceTest.cs new file mode 100644 index 0000000000..1c9516fa8a --- /dev/null +++ b/test/Microsoft.VisualStudio.Editor.Razor.Test/RazorDirectiveCompletionSourceTest.cs @@ -0,0 +1,174 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.Language; +using Microsoft.AspNetCore.Razor.Language.Extensions; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion; +using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion.Data; +using Microsoft.VisualStudio.Text; +using Moq; +using Xunit; +using Span = Microsoft.VisualStudio.Text.Span; + +namespace Microsoft.VisualStudio.Editor.Razor +{ + public class RazorDirectiveCompletionSourceTest : ForegroundDispatcherTestBase + { + private static readonly IReadOnlyList DefaultDirectives = new[] + { + CSharpCodeParser.AddTagHelperDirectiveDescriptor, + CSharpCodeParser.RemoveTagHelperDirectiveDescriptor, + CSharpCodeParser.TagHelperPrefixDirectiveDescriptor, + }; + + private RazorCompletionFactsService CompletionFactsService { get; } = new DefaultRazorCompletionFactsService(); + + [ForegroundFact] + public async Task GetCompletionContextAsync_DoesNotProvideCompletionsPriorToParseResults() + { + // Arrange + var text = "@validCompletion"; + var parser = Mock.Of(); // CodeDocument will be null faking a parser without a parse. + var completionSource = new RazorDirectiveCompletionSource(Dispatcher, parser, CompletionFactsService); + var documentSnapshot = new StringTextSnapshot(text); + var triggerLocation = new SnapshotPoint(documentSnapshot, 4); + var applicableSpan = new SnapshotSpan(documentSnapshot, new Span(1, text.Length - 1 /* validCompletion */)); + + // Act + var completionContext = await Task.Run( + async () => await completionSource.GetCompletionContextAsync(new InitialTrigger(), triggerLocation, applicableSpan, CancellationToken.None)); + + // Assert + Assert.Empty(completionContext.Items); + } + + [ForegroundFact] + public async Task GetCompletionContextAsync_DoesNotProvideCompletionsWhenNotAtCompletionPoint() + { + // Arrange + var text = "@(NotValidCompletionLocation)"; + var parser = CreateParser(text); + var completionSource = new RazorDirectiveCompletionSource(Dispatcher, parser, CompletionFactsService); + var documentSnapshot = new StringTextSnapshot(text); + var triggerLocation = new SnapshotPoint(documentSnapshot, 4); + var applicableSpan = new SnapshotSpan(documentSnapshot, new Span(2, text.Length - 3 /* @() */)); + + // Act + var completionContext = await Task.Run( + async () => await completionSource.GetCompletionContextAsync(new InitialTrigger(), triggerLocation, applicableSpan, CancellationToken.None)); + + // Assert + Assert.Empty(completionContext.Items); + } + + // This is more of an integration level test validating the end-to-end completion flow. + [ForegroundFact] + public async Task GetCompletionContextAsync_ProvidesCompletionsWhenAtCompletionPoint() + { + // Arrange + var text = "@addTag"; + var parser = CreateParser(text, SectionDirective.Directive); + var completionSource = new RazorDirectiveCompletionSource(Dispatcher, parser, CompletionFactsService); + var documentSnapshot = new StringTextSnapshot(text); + var triggerLocation = new SnapshotPoint(documentSnapshot, 4); + var applicableSpan = new SnapshotSpan(documentSnapshot, new Span(1, 6 /* addTag */)); + + // Act + var completionContext = await Task.Run( + async () => await completionSource.GetCompletionContextAsync(new InitialTrigger(), triggerLocation, applicableSpan, CancellationToken.None)); + + // Assert + Assert.Collection( + completionContext.Items, + item => AssertRazorCompletionItem(SectionDirective.Directive, item, completionSource), + item => AssertRazorCompletionItem(DefaultDirectives[0], item, completionSource), + item => AssertRazorCompletionItem(DefaultDirectives[1], item, completionSource), + item => AssertRazorCompletionItem(DefaultDirectives[2], item, completionSource)); + } + + [Fact] + public async Task GetDescriptionAsync_AddsDirectiveDescriptionIfPropertyExists() + { + // Arrange + var completionItem = new CompletionItem("TestDirective", Mock.Of()); + var expectedDescription = "The expected description"; + completionItem.Properties.AddProperty(RazorDirectiveCompletionSource.DescriptionKey, expectedDescription); + var completionSource = new RazorDirectiveCompletionSource(Dispatcher, Mock.Of(), CompletionFactsService); + + // Act + var descriptionObject = await completionSource.GetDescriptionAsync(completionItem, CancellationToken.None); + + // Assert + var description = Assert.IsType(descriptionObject); + Assert.Equal(expectedDescription, descriptionObject); + } + + [Fact] + public async Task GetDescriptionAsync_DoesNotAddDescriptionWhenPropertyAbsent() + { + // Arrange + var completionItem = new CompletionItem("TestDirective", Mock.Of()); + var completionSource = new RazorDirectiveCompletionSource(Dispatcher, Mock.Of(), CompletionFactsService); + + // Act + var descriptionObject = await completionSource.GetDescriptionAsync(completionItem, CancellationToken.None); + + // Assert + var description = Assert.IsType(descriptionObject); + Assert.Equal(string.Empty, description); + } + + private static void AssertRazorCompletionItem(string completionDisplayText, DirectiveDescriptor directive, CompletionItem item, IAsyncCompletionSource source) + { + Assert.Equal(item.DisplayText, completionDisplayText); + Assert.Equal(item.FilterText, completionDisplayText); + Assert.Equal(item.InsertText, directive.Directive); + Assert.Same(item.Source, source); + Assert.True(item.Properties.TryGetProperty(RazorDirectiveCompletionSource.DescriptionKey, out var actualDescription)); + Assert.Equal(directive.Description, actualDescription); + + AssertRazorCompletionItemDefaults(item); + } + + private static void AssertRazorCompletionItem(DirectiveDescriptor directive, CompletionItem item, IAsyncCompletionSource source) => + AssertRazorCompletionItem(directive.Directive, directive, item, source); + + private static void AssertRazorCompletionItemDefaults(CompletionItem item) + { + Assert.Equal(item.Icon.ImageId.Guid, RazorDirectiveCompletionSource.DirectiveImageGlyph.ImageId.Guid); + var filter = Assert.Single(item.Filters); + Assert.Same(RazorDirectiveCompletionSource.DirectiveCompletionFilters[0], filter); + Assert.Equal(string.Empty, item.Suffix); + Assert.Equal(item.DisplayText, item.SortText); + Assert.Empty(item.AttributeIcons); + } + + private static VisualStudioRazorParser CreateParser(string text, params DirectiveDescriptor[] directives) + { + var syntaxTree = CreateSyntaxTree(text, directives); + var codeDocument = TestRazorCodeDocument.Create(text); + codeDocument.SetSyntaxTree(syntaxTree); + var parser = Mock.Of(p => p.CodeDocument == codeDocument); + + return parser; + } + + private static RazorSyntaxTree CreateSyntaxTree(string text, params DirectiveDescriptor[] directives) + { + var sourceDocument = TestRazorSourceDocument.Create(text); + var options = RazorParserOptions.Create(builder => + { + foreach (var directive in directives) + { + builder.Directives.Add(directive); + } + }); + var syntaxTree = RazorSyntaxTree.Parse(sourceDocument, options); + return syntaxTree; + } + } +} diff --git a/tooling/Microsoft.VisualStudio.RazorExtension/Microsoft.VisualStudio.RazorExtension.csproj b/tooling/Microsoft.VisualStudio.RazorExtension/Microsoft.VisualStudio.RazorExtension.csproj index 491559471e..6bdb8d5376 100644 --- a/tooling/Microsoft.VisualStudio.RazorExtension/Microsoft.VisualStudio.RazorExtension.csproj +++ b/tooling/Microsoft.VisualStudio.RazorExtension/Microsoft.VisualStudio.RazorExtension.csproj @@ -1,7 +1,7 @@  - 15.8 + 16.0 99999 diff --git a/tooling/Microsoft.VisualStudio.RazorExtension/source.extension.vsixmanifest b/tooling/Microsoft.VisualStudio.RazorExtension/source.extension.vsixmanifest index 253dcc8b70..d50e2d376b 100644 --- a/tooling/Microsoft.VisualStudio.RazorExtension/source.extension.vsixmanifest +++ b/tooling/Microsoft.VisualStudio.RazorExtension/source.extension.vsixmanifest @@ -13,11 +13,11 @@ - + - - + + diff --git a/version.props b/version.props index 88598148cd..584473c9bb 100644 --- a/version.props +++ b/version.props @@ -1,7 +1,7 @@ - + - 2.2.0 - preview1 + 3.0.0 + alpha1 $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final t000