Refactored Html parser - part 1
This commit is contained in:
parent
46242b307c
commit
31f53d44b5
|
|
@ -9,6 +9,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||||
internal class DirectiveHtmlTokenizer : HtmlTokenizer
|
internal class DirectiveHtmlTokenizer : HtmlTokenizer
|
||||||
{
|
{
|
||||||
private bool _visitedFirstTokenStart = false;
|
private bool _visitedFirstTokenStart = false;
|
||||||
|
private SourceLocation _firstTokenVisitLocation = SourceLocation.Undefined;
|
||||||
|
|
||||||
public DirectiveHtmlTokenizer(ITextDocument source) : base(source)
|
public DirectiveHtmlTokenizer(ITextDocument source) : base(source)
|
||||||
{
|
{
|
||||||
|
|
@ -16,10 +17,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||||
|
|
||||||
protected override StateResult Dispatch()
|
protected override StateResult Dispatch()
|
||||||
{
|
{
|
||||||
|
var location = CurrentLocation;
|
||||||
var result = base.Dispatch();
|
var result = base.Dispatch();
|
||||||
if (result.Result != null && IsValidTokenType(result.Result.Kind))
|
if (result.Result != null && IsValidTokenType(result.Result.Kind))
|
||||||
{
|
{
|
||||||
_visitedFirstTokenStart = true;
|
_visitedFirstTokenStart = true;
|
||||||
|
_firstTokenVisitLocation = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -31,8 +34,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||||
Debug.Assert(Buffer.Length == 0);
|
Debug.Assert(Buffer.Length == 0);
|
||||||
StartToken();
|
StartToken();
|
||||||
|
|
||||||
if (EndOfFile || _visitedFirstTokenStart)
|
if (EndOfFile || (_visitedFirstTokenStart && _firstTokenVisitLocation != CurrentLocation))
|
||||||
{
|
{
|
||||||
|
// We also need to make sure we are currently past the position where we found the first token.
|
||||||
|
// If the position is equal, that means the parser put the token back for later parsing.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -49,6 +49,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||||
|
|
||||||
public bool InTemplateContext { get; set; }
|
public bool InTemplateContext { get; set; }
|
||||||
|
|
||||||
|
public bool StartOfLine { get; set; }
|
||||||
|
|
||||||
public AcceptedCharactersInternal LastAcceptedCharacters { get; set; } = AcceptedCharactersInternal.None;
|
public AcceptedCharactersInternal LastAcceptedCharacters { get; set; } = AcceptedCharactersInternal.None;
|
||||||
|
|
||||||
public bool EndOfFile
|
public bool EndOfFile
|
||||||
|
|
|
||||||
|
|
@ -100,5 +100,26 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||||
{
|
{
|
||||||
return CharUnicodeInfo.GetUnicodeCategory(value) == UnicodeCategory.DecimalDigitNumber;
|
return CharUnicodeInfo.GetUnicodeCategory(value) == UnicodeCategory.DecimalDigitNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From http://dev.w3.org/html5/spec/Overview.html#elements-0
|
||||||
|
public static readonly HashSet<string> VoidElements = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||||
|
{
|
||||||
|
"area",
|
||||||
|
"base",
|
||||||
|
"br",
|
||||||
|
"col",
|
||||||
|
"command",
|
||||||
|
"embed",
|
||||||
|
"hr",
|
||||||
|
"img",
|
||||||
|
"input",
|
||||||
|
"keygen",
|
||||||
|
"link",
|
||||||
|
"meta",
|
||||||
|
"param",
|
||||||
|
"source",
|
||||||
|
"track",
|
||||||
|
"wbr"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
// 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.Legacy
|
||||||
|
{
|
||||||
|
internal enum ParserState
|
||||||
|
{
|
||||||
|
CData,
|
||||||
|
CodeTransition,
|
||||||
|
DoubleTransition,
|
||||||
|
EOF,
|
||||||
|
MarkupComment,
|
||||||
|
MarkupText,
|
||||||
|
Misc,
|
||||||
|
RazorComment,
|
||||||
|
SpecialTag,
|
||||||
|
Tag,
|
||||||
|
Unknown,
|
||||||
|
XmlPI,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -243,6 +243,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected internal IEnumerable<SyntaxToken> ReadWhile(params SyntaxKind[] types)
|
||||||
|
{
|
||||||
|
return ReadWhile(token => types.Any(expected => expected == token.Kind));
|
||||||
|
}
|
||||||
|
|
||||||
protected internal IEnumerable<SyntaxToken> ReadWhile(Func<SyntaxToken, bool> condition)
|
protected internal IEnumerable<SyntaxToken> ReadWhile(Func<SyntaxToken, bool> condition)
|
||||||
{
|
{
|
||||||
return ReadWhileLazy(condition).ToList();
|
return ReadWhileLazy(condition).ToList();
|
||||||
|
|
@ -409,12 +414,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||||
{
|
{
|
||||||
foreach (var token in tokens)
|
foreach (var token in tokens)
|
||||||
{
|
{
|
||||||
foreach (var error in token.GetDiagnostics())
|
Accept(token);
|
||||||
{
|
|
||||||
Context.ErrorSink.OnError(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
TokenBuilder.Add(token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -422,6 +422,15 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||||
{
|
{
|
||||||
if (token != null)
|
if (token != null)
|
||||||
{
|
{
|
||||||
|
if (token.Kind == SyntaxKind.NewLine)
|
||||||
|
{
|
||||||
|
Context.StartOfLine = true;
|
||||||
|
}
|
||||||
|
else if (token.Kind != SyntaxKind.Whitespace)
|
||||||
|
{
|
||||||
|
Context.StartOfLine = false;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var error in token.GetDiagnostics())
|
foreach (var error in token.GetDiagnostics())
|
||||||
{
|
{
|
||||||
Context.ErrorSink.OnError(error);
|
Context.ErrorSink.OnError(error);
|
||||||
|
|
|
||||||
|
|
@ -11,27 +11,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||||
{
|
{
|
||||||
internal static class SyntaxNodeExtensions
|
internal static class SyntaxNodeExtensions
|
||||||
{
|
{
|
||||||
// From http://dev.w3.org/html5/spec/Overview.html#elements-0
|
|
||||||
private static readonly HashSet<string> VoidElements = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
|
||||||
{
|
|
||||||
"area",
|
|
||||||
"base",
|
|
||||||
"br",
|
|
||||||
"col",
|
|
||||||
"command",
|
|
||||||
"embed",
|
|
||||||
"hr",
|
|
||||||
"img",
|
|
||||||
"input",
|
|
||||||
"keygen",
|
|
||||||
"link",
|
|
||||||
"meta",
|
|
||||||
"param",
|
|
||||||
"source",
|
|
||||||
"track",
|
|
||||||
"wbr"
|
|
||||||
};
|
|
||||||
|
|
||||||
public static TNode WithAnnotations<TNode>(this TNode node, params SyntaxAnnotation[] annotations) where TNode : SyntaxNode
|
public static TNode WithAnnotations<TNode>(this TNode node, params SyntaxAnnotation[] annotations) where TNode : SyntaxNode
|
||||||
{
|
{
|
||||||
if (node == null)
|
if (node == null)
|
||||||
|
|
@ -333,7 +312,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Syntax
|
||||||
throw new ArgumentNullException(nameof(tagBlock));
|
throw new ArgumentNullException(nameof(tagBlock));
|
||||||
}
|
}
|
||||||
|
|
||||||
return VoidElements.Contains(tagBlock.GetTagName());
|
return ParserHelpers.VoidElements.Contains(tagBlock.GetTagName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Test.Legacy
|
||||||
var sut = CreateTestParserForContent("---->");
|
var sut = CreateTestParserForContent("---->");
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
Assert.True(sut.IsHtmlCommentAhead());
|
Assert.True(sut.LegacyIsHtmlCommentAhead());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Test.Legacy
|
||||||
var sut = CreateTestParserForContent("-- Some comment content in here -->");
|
var sut = CreateTestParserForContent("-- Some comment content in here -->");
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
Assert.True(sut.IsHtmlCommentAhead());
|
Assert.True(sut.LegacyIsHtmlCommentAhead());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Test.Legacy
|
||||||
var sut = CreateTestParserForContent("-- Some comment content in here ----->");
|
var sut = CreateTestParserForContent("-- Some comment content in here ----->");
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
Assert.True(sut.IsHtmlCommentAhead());
|
Assert.True(sut.LegacyIsHtmlCommentAhead());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Test.Legacy
|
||||||
var sut = CreateTestParserForContent("-- Some comment content in here <!--->");
|
var sut = CreateTestParserForContent("-- Some comment content in here <!--->");
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
Assert.False(sut.IsHtmlCommentAhead());
|
Assert.False(sut.LegacyIsHtmlCommentAhead());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -124,7 +124,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Test.Legacy
|
||||||
var sut = CreateTestParserForContent("-- comment --> the first part is a valid comment without the Open angle and bang tokens");
|
var sut = CreateTestParserForContent("-- comment --> the first part is a valid comment without the Open angle and bang tokens");
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
Assert.True(sut.IsHtmlCommentAhead());
|
Assert.True(sut.LegacyIsHtmlCommentAhead());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -134,7 +134,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Test.Legacy
|
||||||
var sut = CreateTestParserForContent("-- not closed comment");
|
var sut = CreateTestParserForContent("-- not closed comment");
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
Assert.False(sut.IsHtmlCommentAhead());
|
Assert.False(sut.LegacyIsHtmlCommentAhead());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -144,7 +144,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Test.Legacy
|
||||||
var sut = CreateTestParserForContent("-- not closed comment--");
|
var sut = CreateTestParserForContent("-- not closed comment--");
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
Assert.False(sut.IsHtmlCommentAhead());
|
Assert.False(sut.LegacyIsHtmlCommentAhead());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -154,7 +154,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Test.Legacy
|
||||||
var sut = CreateTestParserForContent("-- not closed @DateTime.Now comment-->");
|
var sut = CreateTestParserForContent("-- not closed @DateTime.Now comment-->");
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
Assert.True(sut.IsHtmlCommentAhead());
|
Assert.True(sut.LegacyIsHtmlCommentAhead());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -202,9 +202,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Test.Legacy
|
||||||
get => base.PreviousToken;
|
get => base.PreviousToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
public new bool IsHtmlCommentAhead()
|
public new bool LegacyIsHtmlCommentAhead()
|
||||||
{
|
{
|
||||||
return base.IsHtmlCommentAhead();
|
return base.LegacyIsHtmlCommentAhead();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestHtmlMarkupParser(ParserContext context) : base(context)
|
public TestHtmlMarkupParser(ParserContext context) : base(context)
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,10 @@ Document -
|
||||||
IntermediateToken - (804:26,9 [10] CSharp7.cshtml) - Html - \n
|
IntermediateToken - (804:26,9 [10] CSharp7.cshtml) - Html - \n
|
||||||
CSharpExpression - (816:27,10 [34] CSharp7.cshtml)
|
CSharpExpression - (816:27,10 [34] CSharp7.cshtml)
|
||||||
IntermediateToken - (816:27,10 [34] CSharp7.cshtml) - CSharp - (First: "John", Last: "Doe").First
|
IntermediateToken - (816:27,10 [34] CSharp7.cshtml) - CSharp - (First: "John", Last: "Doe").First
|
||||||
HtmlContent - (872:28,0 [18] CSharp7.cshtml)
|
HtmlContent - (851:27,45 [1] CSharp7.cshtml)
|
||||||
IntermediateToken - (872:28,0 [4] CSharp7.cshtml) - Html -
|
IntermediateToken - (851:27,45 [1] CSharp7.cshtml) - Html -
|
||||||
|
HtmlContent - (870:27,64 [20] CSharp7.cshtml)
|
||||||
|
IntermediateToken - (870:27,64 [6] CSharp7.cshtml) - Html - \n
|
||||||
IntermediateToken - (876:28,4 [6] CSharp7.cshtml) - Html - </div>
|
IntermediateToken - (876:28,4 [6] CSharp7.cshtml) - Html - </div>
|
||||||
IntermediateToken - (882:28,10 [8] CSharp7.cshtml) - Html - \n\n
|
IntermediateToken - (882:28,10 [8] CSharp7.cshtml) - Html - \n\n
|
||||||
CSharpCode - (891:30,5 [291] CSharp7.cshtml)
|
CSharpCode - (891:30,5 [291] CSharp7.cshtml)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue