Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change RazorSyntaxTree.Diagnostics from an IReadOnlyList<RazorDiagnostic> to an ImmutableArray<RazorDiagnostic> #10797

Merged
merged 15 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void GetAttributeNameValuePairs_ParsesPairsCorrectly(
IEnumerable<KeyValuePair<string, string>> expectedPairs)
{
// Arrange
var errorSink = new ErrorSink();
using var errorSink = new ErrorSink();
var parseResult = ParseDocument(documentContent);
var document = parseResult.Root;

Expand All @@ -61,7 +61,7 @@ public void GetAttributeNameValuePairs_ParsesPairsCorrectly(
var rootMarkup = Assert.IsType<MarkupBlockSyntax>(rootBlock.Document);
var childBlock = Assert.Single(rootMarkup.Children);
var element = Assert.IsType<MarkupElementSyntax>(childBlock);
Assert.Empty(errorSink.Errors);
Assert.Empty(errorSink.GetErrorsAndClear());

// Act
var pairs = TagHelperParseTreeRewriter.Rewriter.GetAttributeNameValuePairs(element.StartTag);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void Moves_Whitespace_Preceeding_ExpressionBlock_To_Parent_Block()
var rewritten = rewriter.Visit(parsed.Root);

// Assert
var rewrittenTree = RazorSyntaxTree.Create(rewritten, parsed.Source, parsed.Diagnostics, parsed.Options);
var rewrittenTree = new RazorSyntaxTree(rewritten, parsed.Source, parsed.Diagnostics, parsed.Options);
BaselineTest(rewrittenTree);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ public void Execute_CombinesErrorsOnRewritingErrors()
var expectedRewritingError = RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
new SourceSpan(new SourceLocation((Environment.NewLine.Length * 2) + 30, 2, 1), contentLength: 4), "form");

var erroredOriginalTree = RazorSyntaxTree.Create(originalTree.Root, originalTree.Source, [initialError], originalTree.Options);
var erroredOriginalTree = new RazorSyntaxTree(originalTree.Root, originalTree.Source, [initialError], originalTree.Options);
codeDocument.SetSyntaxTree(erroredOriginalTree);

// Act
Expand All @@ -615,7 +615,7 @@ public void Execute_CombinesErrorsOnRewritingErrors()
var outputTree = codeDocument.GetSyntaxTree();
Assert.Empty(originalTree.Diagnostics);
Assert.NotSame(erroredOriginalTree, outputTree);
Assert.Equal([initialError, expectedRewritingError], outputTree.Diagnostics);
Assert.Equal<RazorDiagnostic>([initialError, expectedRewritingError], outputTree.Diagnostics);
}

private static string AssemblyA => "TestAssembly";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,13 +215,15 @@ public void MapDirectives_HandlesDuplicates()
// Arrange
var source = TestRazorSourceDocument.Create();
var options = RazorParserOptions.CreateDefault();
var context = new ParserContext(source, options);
using var context = new ParserContext(source, options);

// Act & Assert (Does not throw)
var directiveDescriptors = new[] {
var directiveDescriptors = new[]
{
DirectiveDescriptor.CreateDirective("test", DirectiveKind.SingleLine),
DirectiveDescriptor.CreateDirective("test", DirectiveKind.SingleLine),
};

_ = new CSharpCodeParser(directiveDescriptors, context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void IsHyphen_ReturnsTrueForADashToken()
public void AcceptAllButLastDoubleHypens_ReturnsTheOnlyDoubleHyphenToken()
{
// Arrange
var sut = CreateTestParserForContent("-->");
using var sut = CreateTestParserForContent("-->");

// Act
var token = sut.AcceptAllButLastDoubleHyphens();
Expand All @@ -68,7 +68,7 @@ public void AcceptAllButLastDoubleHypens_ReturnsTheOnlyDoubleHyphenToken()
public void AcceptAllButLastDoubleHypens_ReturnsTheDoubleHyphenTokenAfterAcceptingTheDash()
{
// Arrange
var sut = CreateTestParserForContent("--->");
using var sut = CreateTestParserForContent("--->");

// Act
var token = sut.AcceptAllButLastDoubleHyphens();
Expand All @@ -83,7 +83,7 @@ public void AcceptAllButLastDoubleHypens_ReturnsTheDoubleHyphenTokenAfterAccepti
public void IsHtmlCommentAhead_ReturnsTrueForEmptyCommentTag()
{
// Arrange
var sut = CreateTestParserForContent("<!---->");
using var sut = CreateTestParserForContent("<!---->");

// Act & Assert
Assert.True(sut.IsHtmlCommentAhead());
Expand All @@ -93,7 +93,7 @@ public void IsHtmlCommentAhead_ReturnsTrueForEmptyCommentTag()
public void IsHtmlCommentAhead_ReturnsTrueForValidCommentTag()
{
// Arrange
var sut = CreateTestParserForContent("<!-- Some comment content in here -->");
using var sut = CreateTestParserForContent("<!-- Some comment content in here -->");

// Act & Assert
Assert.True(sut.IsHtmlCommentAhead());
Expand All @@ -103,7 +103,7 @@ public void IsHtmlCommentAhead_ReturnsTrueForValidCommentTag()
public void IsHtmlCommentAhead_ReturnsTrueForValidCommentTagWithExtraDashesAtClosingTag()
{
// Arrange
var sut = CreateTestParserForContent("<!-- Some comment content in here ----->");
using var sut = CreateTestParserForContent("<!-- Some comment content in here ----->");

// Act & Assert
Assert.True(sut.IsHtmlCommentAhead());
Expand All @@ -113,7 +113,7 @@ public void IsHtmlCommentAhead_ReturnsTrueForValidCommentTagWithExtraDashesAtClo
public void IsHtmlCommentAhead_ReturnsFalseForContentWithBadEndingAndExtraDash()
{
// Arrange
var sut = CreateTestParserForContent("<!-- Some comment content in here <!--->");
using var sut = CreateTestParserForContent("<!-- Some comment content in here <!--->");

// Act & Assert
Assert.False(sut.IsHtmlCommentAhead());
Expand All @@ -123,7 +123,7 @@ public void IsHtmlCommentAhead_ReturnsFalseForContentWithBadEndingAndExtraDash()
public void IsHtmlCommentAhead_ReturnsTrueForValidCommentTagWithExtraInfoAfter()
{
// Arrange
var sut = CreateTestParserForContent("<!-- comment --> the first part is a valid comment without the Open angle and bang tokens");
using var sut = CreateTestParserForContent("<!-- comment --> the first part is a valid comment without the Open angle and bang tokens");

// Act & Assert
Assert.True(sut.IsHtmlCommentAhead());
Expand All @@ -133,7 +133,7 @@ public void IsHtmlCommentAhead_ReturnsTrueForValidCommentTagWithExtraInfoAfter()
public void IsHtmlCommentAhead_ReturnsFalseForNotClosedComment()
{
// Arrange
var sut = CreateTestParserForContent("<!-- not closed comment");
using var sut = CreateTestParserForContent("<!-- not closed comment");

// Act & Assert
Assert.False(sut.IsHtmlCommentAhead());
Expand All @@ -143,7 +143,7 @@ public void IsHtmlCommentAhead_ReturnsFalseForNotClosedComment()
public void IsHtmlCommentAhead_ReturnsFalseForCommentWithoutLastClosingAngle()
{
// Arrange
var sut = CreateTestParserForContent("<!-- not closed comment--");
using var sut = CreateTestParserForContent("<!-- not closed comment--");

// Act & Assert
Assert.False(sut.IsHtmlCommentAhead());
Expand All @@ -153,7 +153,7 @@ public void IsHtmlCommentAhead_ReturnsFalseForCommentWithoutLastClosingAngle()
public void IsHtmlCommentAhead_ReturnsTrueForCommentWithCodeInside()
{
// Arrange
var sut = CreateTestParserForContent("<!-- not closed @DateTime.Now comment-->");
using var sut = CreateTestParserForContent("<!-- not closed @DateTime.Now comment-->");

// Act & Assert
Assert.True(sut.IsHtmlCommentAhead());
Expand Down Expand Up @@ -195,8 +195,19 @@ public void IsCommentContentEndingInvalid_ReturnsFalseForEmptyContent()
Assert.False(HtmlMarkupParser.IsCommentContentEndingInvalid(sequence));
}

private class TestHtmlMarkupParser : HtmlMarkupParser
private class TestHtmlMarkupParser : HtmlMarkupParser, IDisposable
{
public TestHtmlMarkupParser(ParserContext context)
: base(context)
{
EnsureCurrent();
}

public void Dispose()
{
Context.Dispose();
}

public new SyntaxToken PreviousToken
{
get => base.PreviousToken;
Expand All @@ -207,11 +218,6 @@ private class TestHtmlMarkupParser : HtmlMarkupParser
return base.IsHtmlCommentAhead();
}

public TestHtmlMarkupParser(ParserContext context) : base(context)
{
EnsureCurrent();
}

public new SyntaxToken AcceptAllButLastDoubleHyphens()
{
return base.AcceptAllButLastDoubleHyphens();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void GetAttributeNameValuePairs_ParsesPairsCorrectly(
IEnumerable<KeyValuePair<string, string>> expectedPairs)
{
// Arrange
var errorSink = new ErrorSink();
using var errorSink = new ErrorSink();
var parseResult = ParseDocument(documentContent);
var document = parseResult.Root;

Expand All @@ -61,7 +61,7 @@ public void GetAttributeNameValuePairs_ParsesPairsCorrectly(
var rootMarkup = Assert.IsType<MarkupBlockSyntax>(rootBlock.Document);
var childBlock = Assert.Single(rootMarkup.Children);
var element = Assert.IsType<MarkupElementSyntax>(childBlock);
Assert.Empty(errorSink.Errors);
Assert.Empty(errorSink.GetErrorsAndClear());

// Act
var pairs = TagHelperParseTreeRewriter.Rewriter.GetAttributeNameValuePairs(element.StartTag);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void Lookahead_MaintainsExistingBufferWhenSuccessfulAndTakeIfMatchIsFalse
public void LookaheadUntil_PassesThePreviousTokensInTheSameOrder()
{
// Arrange
var tokenizer = CreateContentTokenizer("asdf--fvd--<");
using var tokenizer = CreateContentTokenizer("asdf--fvd--<");

// Act
var i = 3;
Expand All @@ -89,7 +89,7 @@ public void LookaheadUntil_PassesThePreviousTokensInTheSameOrder()
public void LookaheadUntil_ReturnsFalseAfterIteratingOverAllTokensIfConditionIsNotMet()
{
// Arrange
var tokenizer = CreateContentTokenizer("asdf--fvd");
using var tokenizer = CreateContentTokenizer("asdf--fvd");

// Act
var tokens = new Stack<SyntaxToken>();
Expand All @@ -111,7 +111,7 @@ public void LookaheadUntil_ReturnsFalseAfterIteratingOverAllTokensIfConditionIsN
public void LookaheadUntil_ReturnsTrueAndBreaksIteration()
{
// Arrange
var tokenizer = CreateContentTokenizer("asdf--fvd");
using var tokenizer = CreateContentTokenizer("asdf--fvd");

// Act
var tokens = new Stack<SyntaxToken>();
Expand All @@ -134,8 +134,7 @@ private static TestTokenizerBackedParser CreateContentTokenizer(string content)
var options = RazorParserOptions.CreateDefault();
var context = new ParserContext(source, options);

var tokenizer = new TestTokenizerBackedParser(HtmlLanguageCharacteristics.Instance, context);
return tokenizer;
return new TestTokenizerBackedParser(HtmlLanguageCharacteristics.Instance, context);
}

private static void AssertTokenEqual(SyntaxToken expected, SyntaxToken actual)
Expand Down Expand Up @@ -204,12 +203,18 @@ protected override StateResult Dispatch()
}
}

private class TestTokenizerBackedParser : TokenizerBackedParser<HtmlTokenizer>
private class TestTokenizerBackedParser : TokenizerBackedParser<HtmlTokenizer>, IDisposable
{
internal TestTokenizerBackedParser(LanguageCharacteristics<HtmlTokenizer> language, ParserContext context) : base(language, context)
internal TestTokenizerBackedParser(LanguageCharacteristics<HtmlTokenizer> language, ParserContext context)
: base(language, context)
{
}

public void Dispose()
{
Context.Dispose();
}

internal new bool LookaheadUntil(Func<SyntaxToken, IEnumerable<SyntaxToken>, bool> condition)
{
return base.LookaheadUntil(condition);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void Moves_Whitespace_Preceeding_ExpressionBlock_To_Parent_Block()
var rewritten = rewriter.Visit(parsed.Root);

// Assert
var rewrittenTree = RazorSyntaxTree.Create(rewritten, parsed.Source, parsed.Diagnostics, parsed.Options);
var rewrittenTree = new RazorSyntaxTree(rewritten, parsed.Source, parsed.Diagnostics, parsed.Options);
BaselineTest(rewrittenTree);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.AspNetCore.Razor.Language.Syntax;

Expand All @@ -26,23 +24,19 @@ public RazorSyntaxTree Execute(RazorCodeDocument codeDocument, RazorSyntaxTree s
return sectionVerifier.Verify();
}

private class NestedSectionVerifier : SyntaxRewriter
private sealed class NestedSectionVerifier(RazorSyntaxTree syntaxTree) : SyntaxRewriter
{
private int _nestedLevel;
private readonly RazorSyntaxTree _syntaxTree;
private readonly List<RazorDiagnostic> _diagnostics;
private readonly RazorSyntaxTree _syntaxTree = syntaxTree;

public NestedSectionVerifier(RazorSyntaxTree syntaxTree)
{
_syntaxTree = syntaxTree;
_diagnostics = new List<RazorDiagnostic>(syntaxTree.Diagnostics);
}
private ImmutableArray<RazorDiagnostic>.Builder? _diagnostics;
private int _nestedLevel;

public RazorSyntaxTree Verify()
{
var root = Visit(_syntaxTree.Root);
var rewrittenTree = new DefaultRazorSyntaxTree(root, _syntaxTree.Source, _diagnostics, _syntaxTree.Options);
return rewrittenTree;
var diagnostics = _diagnostics?.DrainToImmutable() ?? _syntaxTree.Diagnostics;

return new RazorSyntaxTree(root, _syntaxTree.Source, diagnostics, _syntaxTree.Options);
}

public override SyntaxNode Visit(SyntaxNode node)
Expand All @@ -55,6 +49,7 @@ public override SyntaxNode Visit(SyntaxNode node)
{
// We're very close to reaching the stack limit. Let's not go any deeper.
// It's okay to not show nested section errors in deeply nested cases instead of crashing.
_diagnostics ??= _syntaxTree.Diagnostics.ToBuilder();
_diagnostics.Add(RazorDiagnosticFactory.CreateRewriter_InsufficientStack());

return node;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,18 @@ protected override void ExecuteCore(RazorCodeDocument codeDocument)

// The document should contain all errors that currently exist in the system. This involves
// adding the errors from the primary and imported syntax trees.
for (var i = 0; i < syntaxTree.Diagnostics.Count; i++)
foreach (var diagnostic in syntaxTree.Diagnostics)
{
document.Diagnostics.Add(syntaxTree.Diagnostics[i]);
document.Diagnostics.Add(diagnostic);
}

if (imports is { IsDefault: false } importsArray)
{
foreach (var import in importsArray)
{
for (var j = 0; j < import.Diagnostics.Count; j++)
foreach (var diagnostic in import.Diagnostics)
{
document.Diagnostics.Add(import.Diagnostics[j]);
document.Diagnostics.Add(diagnostic);
}
}
}
Expand Down
Loading
Loading