Added check to ensure we generate syntax tree with full fidelity (dotnet/aspnetcore-tooling#111)
* Added check to ensure we generate syntax tree with full fidelity
* Better check
* Feedback
\n\nCommit migrated from 88653fc348
This commit is contained in:
parent
b449a44440
commit
b0e2dc2add
|
|
@ -4,16 +4,13 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Text;
|
||||
using Xunit;
|
||||
using Xunit.Sdk;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.AspNetCore.Razor.Language.Syntax;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
||||
{
|
||||
|
|
@ -175,44 +172,19 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
return Regex.Replace(content, "(?<!\r)\n", "\r\n", RegexOptions.None, TimeSpan.FromSeconds(10));
|
||||
}
|
||||
|
||||
internal virtual void BaselineTest(RazorSyntaxTree syntaxTree, bool verifySyntaxTree = true)
|
||||
internal virtual void BaselineTest(RazorSyntaxTree syntaxTree, bool verifySyntaxTree = true, bool ensureFullFidelity = true)
|
||||
{
|
||||
if (verifySyntaxTree)
|
||||
{
|
||||
SyntaxTreeVerifier.Verify(syntaxTree);
|
||||
SyntaxTreeVerifier.Verify(syntaxTree, ensureFullFidelity);
|
||||
}
|
||||
|
||||
AssertSyntaxTreeNodeMatchesBaseline(syntaxTree);
|
||||
}
|
||||
|
||||
internal RazorSyntaxTree ParseBlock(string document, bool designTime)
|
||||
{
|
||||
return ParseBlock(RazorLanguageVersion.Latest, document, designTime);
|
||||
}
|
||||
|
||||
internal RazorSyntaxTree ParseBlock(RazorLanguageVersion version, string document, bool designTime)
|
||||
{
|
||||
return ParseBlock(version, document, null, designTime);
|
||||
}
|
||||
|
||||
internal RazorSyntaxTree ParseBlock(string document, IEnumerable<DirectiveDescriptor> directives, bool designTime)
|
||||
{
|
||||
return ParseBlock(RazorLanguageVersion.Latest, document, directives, designTime);
|
||||
}
|
||||
|
||||
internal abstract RazorSyntaxTree ParseBlock(RazorLanguageVersion version, string document, IEnumerable<DirectiveDescriptor> directives, bool designTime);
|
||||
|
||||
internal RazorSyntaxTree ParseDocument(string document, bool designTime = false, RazorParserFeatureFlags featureFlags = null)
|
||||
{
|
||||
return ParseDocument(RazorLanguageVersion.Latest, document, designTime, featureFlags);
|
||||
}
|
||||
|
||||
internal RazorSyntaxTree ParseDocument(RazorLanguageVersion version, string document, bool designTime = false, RazorParserFeatureFlags featureFlags = null)
|
||||
{
|
||||
return ParseDocument(version, document, null, designTime, featureFlags);
|
||||
}
|
||||
|
||||
internal RazorSyntaxTree ParseDocument(string document, IEnumerable<DirectiveDescriptor> directives, bool designTime = false, RazorParserFeatureFlags featureFlags = null)
|
||||
internal RazorSyntaxTree ParseDocument(string document, bool designTime = false, IEnumerable<DirectiveDescriptor> directives = null, RazorParserFeatureFlags featureFlags = null)
|
||||
{
|
||||
return ParseDocument(RazorLanguageVersion.Latest, document, directives, designTime, featureFlags);
|
||||
}
|
||||
|
|
@ -271,11 +243,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
return syntaxTree;
|
||||
}
|
||||
|
||||
internal RazorSyntaxTree ParseCodeBlock(string document, bool designTime = false)
|
||||
{
|
||||
return ParseCodeBlock(RazorLanguageVersion.Latest, document, Enumerable.Empty<DirectiveDescriptor>(), designTime);
|
||||
}
|
||||
|
||||
internal virtual RazorSyntaxTree ParseCodeBlock(
|
||||
RazorLanguageVersion version,
|
||||
string document,
|
||||
|
|
@ -306,86 +273,39 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
internal virtual void ParseBlockTest(string document)
|
||||
{
|
||||
ParseBlockTest(document, null, false, new RazorDiagnostic[0]);
|
||||
ParseBlockTest(document, null, false);
|
||||
}
|
||||
|
||||
internal virtual void ParseBlockTest(string document, IEnumerable<DirectiveDescriptor> directives)
|
||||
internal virtual void ParseBlockTest(string document, bool designTime)
|
||||
{
|
||||
ParseBlockTest(document, directives, null);
|
||||
}
|
||||
|
||||
internal virtual void ParseBlockTest(string document, params RazorDiagnostic[] expectedErrors)
|
||||
{
|
||||
ParseBlockTest(document, false, expectedErrors);
|
||||
}
|
||||
|
||||
internal virtual void ParseBlockTest(string document, bool designTime, params RazorDiagnostic[] expectedErrors)
|
||||
{
|
||||
ParseBlockTest(document, null, designTime, expectedErrors);
|
||||
ParseBlockTest(document, null, designTime);
|
||||
}
|
||||
|
||||
internal virtual void ParseBlockTest(RazorLanguageVersion version, string document)
|
||||
{
|
||||
ParseBlockTest(version, document, false, null);
|
||||
ParseBlockTest(version, document, false);
|
||||
}
|
||||
|
||||
internal virtual void ParseBlockTest(string document, IEnumerable<DirectiveDescriptor> directives, params RazorDiagnostic[] expectedErrors)
|
||||
internal virtual void ParseBlockTest(string document, IEnumerable<DirectiveDescriptor> directives)
|
||||
{
|
||||
ParseBlockTest(document, directives, false, expectedErrors);
|
||||
ParseBlockTest(document, directives, false);
|
||||
}
|
||||
|
||||
internal virtual void ParseBlockTest(RazorLanguageVersion version, string document, bool designTime, params RazorDiagnostic[] expectedErrors)
|
||||
internal virtual void ParseBlockTest(RazorLanguageVersion version, string document, bool designTime)
|
||||
{
|
||||
ParseBlockTest(version, document, null, designTime, expectedErrors);
|
||||
ParseBlockTest(version, document, null, designTime);
|
||||
}
|
||||
|
||||
internal virtual void ParseBlockTest(string document, IEnumerable<DirectiveDescriptor> directives, bool designTime, params RazorDiagnostic[] expectedErrors)
|
||||
internal virtual void ParseBlockTest(string document, IEnumerable<DirectiveDescriptor> directives, bool designTime)
|
||||
{
|
||||
ParseBlockTest(RazorLanguageVersion.Latest, document, directives, designTime, expectedErrors);
|
||||
ParseBlockTest(RazorLanguageVersion.Latest, document, directives, designTime);
|
||||
}
|
||||
|
||||
internal virtual void ParseBlockTest(RazorLanguageVersion version, string document, IEnumerable<DirectiveDescriptor> directives, bool designTime, params RazorDiagnostic[] expectedErrors)
|
||||
internal virtual void ParseBlockTest(RazorLanguageVersion version, string document, IEnumerable<DirectiveDescriptor> directives, bool designTime)
|
||||
{
|
||||
var result = ParseBlock(version, document, directives, designTime);
|
||||
|
||||
BaselineTest(result);
|
||||
}
|
||||
|
||||
internal virtual void SingleSpanBlockTest(string document)
|
||||
{
|
||||
SingleSpanBlockTest(document, default, default);
|
||||
}
|
||||
|
||||
internal virtual void SingleSpanBlockTest(string document, BlockKindInternal blockKind, SpanKindInternal spanType, AcceptedCharactersInternal acceptedCharacters = AcceptedCharactersInternal.Any)
|
||||
{
|
||||
SingleSpanBlockTest(document, blockKind, spanType, acceptedCharacters, expectedError: null);
|
||||
}
|
||||
|
||||
internal virtual void SingleSpanBlockTest(string document, string spanContent, BlockKindInternal blockKind, SpanKindInternal spanType, AcceptedCharactersInternal acceptedCharacters = AcceptedCharactersInternal.Any)
|
||||
{
|
||||
SingleSpanBlockTest(document, spanContent, blockKind, spanType, acceptedCharacters, expectedErrors: null);
|
||||
}
|
||||
|
||||
internal virtual void SingleSpanBlockTest(string document, BlockKindInternal blockKind, SpanKindInternal spanType, params RazorDiagnostic[] expectedError)
|
||||
{
|
||||
SingleSpanBlockTest(document, document, blockKind, spanType, expectedError);
|
||||
}
|
||||
|
||||
internal virtual void SingleSpanBlockTest(string document, string spanContent, BlockKindInternal blockKind, SpanKindInternal spanType, params RazorDiagnostic[] expectedErrors)
|
||||
{
|
||||
SingleSpanBlockTest(document, spanContent, blockKind, spanType, AcceptedCharactersInternal.Any, expectedErrors ?? new RazorDiagnostic[0]);
|
||||
}
|
||||
|
||||
internal virtual void SingleSpanBlockTest(string document, BlockKindInternal blockKind, SpanKindInternal spanType, AcceptedCharactersInternal acceptedCharacters, params RazorDiagnostic[] expectedError)
|
||||
{
|
||||
SingleSpanBlockTest(document, document, blockKind, spanType, acceptedCharacters, expectedError);
|
||||
}
|
||||
|
||||
internal virtual void SingleSpanBlockTest(string document, string spanContent, BlockKindInternal blockKind, SpanKindInternal spanType, AcceptedCharactersInternal acceptedCharacters, params RazorDiagnostic[] expectedErrors)
|
||||
{
|
||||
var result = ParseBlock(document, designTime: false);
|
||||
|
||||
BaselineTest(result);
|
||||
BaselineTest(result, ensureFullFidelity: false);
|
||||
}
|
||||
|
||||
internal virtual void ParseDocumentTest(string document)
|
||||
|
|
@ -393,14 +313,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
ParseDocumentTest(document, null, false);
|
||||
}
|
||||
|
||||
internal virtual void ParseDocumentTest(string document, params RazorDiagnostic[] expectedErrors)
|
||||
internal virtual void ParseDocumentTest(string document, IEnumerable<DirectiveDescriptor> directives)
|
||||
{
|
||||
ParseDocumentTest(document, false, expectedErrors);
|
||||
}
|
||||
|
||||
internal virtual void ParseDocumentTest(string document, IEnumerable<DirectiveDescriptor> directives, params RazorDiagnostic[] expectedErrors)
|
||||
{
|
||||
ParseDocumentTest(document, directives, false, expectedErrors);
|
||||
ParseDocumentTest(document, directives, false);
|
||||
}
|
||||
|
||||
internal virtual void ParseDocumentTest(string document, bool designTime)
|
||||
|
|
@ -408,14 +323,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
ParseDocumentTest(document, null, designTime);
|
||||
}
|
||||
|
||||
internal virtual void ParseDocumentTest(string document, bool designTime, params RazorDiagnostic[] expectedErrors)
|
||||
internal virtual void ParseDocumentTest(string document, IEnumerable<DirectiveDescriptor> directives, bool designTime)
|
||||
{
|
||||
ParseDocumentTest(document, null, designTime, expectedErrors);
|
||||
}
|
||||
|
||||
internal virtual void ParseDocumentTest(string document, IEnumerable<DirectiveDescriptor> directives, bool designTime, params RazorDiagnostic[] expectedErrors)
|
||||
{
|
||||
var result = ParseDocument(document, directives, designTime);
|
||||
var result = ParseDocument(document, designTime, directives);
|
||||
|
||||
BaselineTest(result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,20 +2,37 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Razor.Language.Legacy;
|
||||
using Microsoft.AspNetCore.Razor.Language.Syntax;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
{
|
||||
// Verifies recursively that a syntax tree has no gaps in terms of position/location.
|
||||
internal class SyntaxTreeVerifier
|
||||
{
|
||||
public static void Verify(RazorSyntaxTree syntaxTree)
|
||||
public static void Verify(RazorSyntaxTree syntaxTree, bool ensureFullFidelity = true)
|
||||
{
|
||||
new Verifier(syntaxTree.Source).Visit(syntaxTree.Root);
|
||||
var verifier = new Verifier(syntaxTree.Source);
|
||||
verifier.Visit(syntaxTree.Root);
|
||||
|
||||
if (ensureFullFidelity)
|
||||
{
|
||||
var syntaxTreeString = syntaxTree.Root.ToFullString();
|
||||
var builder = new StringBuilder(syntaxTree.Source.Length);
|
||||
for (var i = 0; i < syntaxTree.Source.Length; i++)
|
||||
{
|
||||
builder.Append(syntaxTree.Source[i]);
|
||||
}
|
||||
var sourceString = builder.ToString();
|
||||
|
||||
// Make sure the syntax tree contains all of the text in the document.
|
||||
Assert.Equal(sourceString, syntaxTreeString);
|
||||
}
|
||||
}
|
||||
|
||||
private class Verifier : SyntaxRewriter
|
||||
private class Verifier : SyntaxWalker
|
||||
{
|
||||
private readonly SourceLocationTracker _tracker;
|
||||
private readonly RazorSourceDocument _source;
|
||||
|
|
@ -26,7 +43,9 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
_source = source;
|
||||
}
|
||||
|
||||
public override SyntaxNode VisitToken(SyntaxToken token)
|
||||
public SourceLocationTracker SourceLocationTracker => _tracker;
|
||||
|
||||
public override void VisitToken(SyntaxToken token)
|
||||
{
|
||||
if (token != null && !token.IsMissing && token.Kind != SyntaxKind.Marker)
|
||||
{
|
||||
|
|
@ -39,7 +58,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
_tracker.UpdateLocation(token.Content);
|
||||
}
|
||||
|
||||
return base.VisitToken(token);
|
||||
base.VisitToken(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue