Skip to content

Commit 0b03ca6

Browse files
authored
SyntaxValueProvider: avoid performance issue with syntax list containing many items (#83483)
1 parent 8e8ab0c commit 0b03ca6

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

src/libraries/Common/src/Roslyn/SyntaxValueProvider_ForAttributeWithSimpleName.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,16 @@ void processMember(
334334
// For any other node, just keep recursing deeper to see if we can find an attribute. Note: we cannot
335335
// terminate the search anywhere as attributes may be found on things like local functions, and that
336336
// means having to dive deep into statements and expressions.
337-
foreach (var child in node.ChildNodesAndTokens().Reverse())
337+
var childNodesAndTokens = node.ChildNodesAndTokens();
338+
339+
// Avoid performance issue in ChildSyntaxList when iterating the child list in reverse
340+
// (see https://github.com/dotnet/roslyn/issues/66475) by iterating forward first to
341+
// ensure child nodes are realized.
342+
foreach (var childNode in childNodesAndTokens)
343+
{
344+
}
345+
346+
foreach (var child in childNodesAndTokens.Reverse())
338347
{
339348
if (child.IsNode)
340349
nodeStack.Append(child.AsNode()!);

src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,40 @@ partial class C
877877
Assert.Empty(diagnostics);
878878
}
879879

880+
[Fact]
881+
public static void SyntaxListWithManyItems()
882+
{
883+
const int nItems = 200000;
884+
var builder = new System.Text.StringBuilder();
885+
builder.AppendLine(
886+
"""
887+
using Microsoft.Extensions.Logging;
888+
class Program
889+
{
890+
[LoggerMessage(EventId = 1, Level = LogLevel.Debug, Message = "M1")]
891+
static partial void M1(ILogger logger)
892+
{
893+
""");
894+
builder.AppendLine(" int[] values = new[] { ");
895+
for (int i = 0; i < nItems; i++)
896+
{
897+
builder.Append("0, ");
898+
}
899+
builder.AppendLine("};");
900+
builder.AppendLine("}");
901+
builder.AppendLine("}");
902+
903+
string source = builder.ToString();
904+
Compilation compilation = CompilationHelper.CreateCompilation(source);
905+
LoggerMessageGenerator generator = new LoggerMessageGenerator();
906+
907+
(ImmutableArray<Diagnostic> diagnostics, _) =
908+
RoslynTestUtils.RunGenerator(compilation, generator);
909+
910+
Assert.Single(diagnostics);
911+
Assert.Equal(DiagnosticDescriptors.LoggingMethodHasBody.Id, diagnostics[0].Id);
912+
}
913+
880914
private static async Task<IReadOnlyList<Diagnostic>> RunGenerator(
881915
string code,
882916
bool wrap = true,

0 commit comments

Comments
 (0)