Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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 @@ -334,7 +334,15 @@ void processMember(
// For any other node, just keep recursing deeper to see if we can find an attribute. Note: we cannot
// terminate the search anywhere as attributes may be found on things like local functions, and that
// means having to dive deep into statements and expressions.
foreach (var child in node.ChildNodesAndTokens().Reverse())
var childNodesAndTokens = node.ChildNodesAndTokens();

// Avoid performance issue (in .NET 7 and earlier) iterating the child list in reverse
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this relate to ".NET 7"? Is this actually about the version of Roslyn that's being used?

Copy link
Contributor Author

@cston cston Mar 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this comment is about the version of Roslyn that's used.

Perhaps this should be: "Avoid performance issue in earlier implementations of ChildSyntaxList iterating the child list in reverse ..."

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. You could just be explicit and include a link to the Roslyn PR that fixed it. Essentially we're saying if you're running with an earlier Roslyn than that, you could have perf issues. I'm just questioning the original wording because you will likely end up getting that fix as part of .NET 7 SDK updates and as part of VS updates, right?

// by iterating forward first, to populate the cache.
foreach (var childNode in childNodesAndTokens)
{
}

foreach (var child in childNodesAndTokens.Reverse())
{
if (child.IsNode)
nodeStack.Append(child.AsNode()!);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,40 @@ partial class C
Assert.Empty(diagnostics);
}

[Fact]
public static void SyntaxListWithManyItems()
{
const int nItems = 200000;
var builder = new System.Text.StringBuilder();
builder.AppendLine(
"""
using Microsoft.Extensions.Logging;
class Program
{
[LoggerMessage(EventId = 1, Level = LogLevel.Debug, Message = "M1")]
static partial void M1(ILogger logger)
{
""");
builder.AppendLine(" int[] values = new[] { ");
for (int i = 0; i < nItems; i++)
{
builder.Append("0, ");
}
builder.AppendLine("};");
builder.AppendLine("}");
builder.AppendLine("}");

string source = builder.ToString();
Compilation compilation = CompilationHelper.CreateCompilation(source);
LoggerMessageGenerator generator = new LoggerMessageGenerator();

(ImmutableArray<Diagnostic> diagnostics, _) =
RoslynTestUtils.RunGenerator(compilation, generator);

Assert.Single(diagnostics);
Assert.Equal(DiagnosticDescriptors.LoggingMethodHasBody.Id, diagnostics[0].Id);
}

private static async Task<IReadOnlyList<Diagnostic>> RunGenerator(
string code,
bool wrap = true,
Expand Down