Skip to content

Commit

Permalink
Do not use SyntaxWalker to visit an arbitrary syntax tree in order to…
Browse files Browse the repository at this point in the history
… avoid a stack overflow. (#59203)

Fixes #59190.
  • Loading branch information
AlekseyTs authored Feb 2, 2022
1 parent e2d317d commit 62ef6c0
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2806,5 +2806,43 @@ class C { }
driver = driver.RunGenerators(compilation);
Assert.Single(referenceList, modifiedRef.Display);
}

[ConditionalFact(typeof(NoIOperationValidation))]
[WorkItem(59190, "https://github.com/dotnet/roslyn/issues/59190")]
public void LongBinaryExpression()
{
var source = @"
class C {
public static readonly string F = ""a""
";

for (int i = 0; i < 7000; i++)
{
source += @" + ""a""
";
}

source += @";
}
";
var parseOptions = TestOptions.RegularPreview;
Compilation compilation = CreateCompilation(source, options: TestOptions.DebugDll, parseOptions: parseOptions);
compilation.VerifyDiagnostics();
Assert.Single(compilation.SyntaxTrees);

var generator = new PipelineCallbackGenerator(ctx =>
{
ctx.RegisterSourceOutput(ctx.SyntaxProvider.CreateSyntaxProvider((node, ct) => node is ClassDeclarationSyntax c, (context, ct) => context.Node).WithTrackingName("Syntax"), (context, ct) => { });
ctx.RegisterSourceOutput(ctx.CompilationProvider, (context, ct) => { });
ctx.RegisterSourceOutput(ctx.AnalyzerConfigOptionsProvider, (context, ct) => { });
ctx.RegisterSourceOutput(ctx.ParseOptionsProvider, (context, ct) => { });
ctx.RegisterSourceOutput(ctx.AdditionalTextsProvider, (context, ct) => { });
ctx.RegisterImplementationSourceOutput(ctx.MetadataReferencesProvider, (context, ct) => { });
});

GeneratorDriver driver = CSharpGeneratorDriver.Create(new[] { generator.AsSourceGenerator() }, parseOptions: parseOptions, additionalTexts: new[] { new InMemoryAdditionalText("text.txt", "") }, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, trackIncrementalGeneratorSteps: true));
driver = driver.RunGenerators(compilation);
driver.GetRunResult();
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void VisitTree(Lazy<SyntaxNode> root, EntryState state, SemanticModel? mo
if (state != EntryState.Cached || !_filterTable.TryUseCachedEntries(TimeSpan.Zero, noInputStepsStepInfo, out ImmutableArray<SyntaxNode> nodes))
{
var stopwatch = SharedStopwatch.StartNew();
nodes = IncrementalGeneratorSyntaxWalker.GetFilteredNodes(root.Value, _owner._filterFunc, cancellationToken);
nodes = getFilteredNodes(root.Value, _owner._filterFunc, cancellationToken);
_filterTable.AddEntries(nodes, state, stopwatch.Elapsed, noInputStepsStepInfo, state);
}

Expand All @@ -111,6 +111,22 @@ public void VisitTree(Lazy<SyntaxNode> root, EntryState state, SemanticModel? mo
}
}
}

static ImmutableArray<SyntaxNode> getFilteredNodes(SyntaxNode root, Func<SyntaxNode, CancellationToken, bool> func, CancellationToken token)
{
ArrayBuilder<SyntaxNode>? results = null;
foreach (var node in root.DescendantNodesAndSelf())
{
token.ThrowIfCancellationRequested();

if (func(node, token))
{
(results ??= ArrayBuilder<SyntaxNode>.GetInstance()).Add(node);
}
}

return results.ToImmutableOrEmptyAndFree();
}
}
}
}
Expand Down

0 comments on commit 62ef6c0

Please sign in to comment.