提交 67ce4533 编写于 作者: J Julien Couvreur

Removing recursion in SyntaxNode.FindTriviaByOffset

(with test)

Adding VB test for this change and original fix #5528
上级 631e9fa1
......@@ -8,6 +8,7 @@
using Roslyn.Test.Utilities;
using Xunit;
using InternalSyntax = Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax;
using System.Text;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
......@@ -2936,5 +2937,30 @@ public void TestTriviaExists()
Assert.Equal(1, nodeOrToken.GetTrailingTrivia().Count);
Assert.Equal(2, nodeOrToken.GetTrailingTrivia().Span.Length); // zero-width elastic trivia
}
[WorkItem(6536, "https://github.com/dotnet/roslyn/issues/6536")]
[Fact]
public void TestFindTrivia_NoStackOverflowOnLargeExpression()
{
StringBuilder code = new StringBuilder();
code.Append(
@"class Foo
{
void Bar()
{
string test = ");
for (var i = 0; i < 3000; i++)
{
code.Append(@"""asdf"" + ");
}
code.Append(@"""last"";
}
}");
var tree = SyntaxFactory.ParseSyntaxTree(code.ToString());
var position = 4000;
var trivia = tree.GetCompilationUnitRoot().FindTrivia(position);
// no stack overflow
}
}
}
......@@ -923,6 +923,7 @@ public SyntaxTrivia FindTrivia(int position, Func<SyntaxTrivia, bool> stepInto)
internal static SyntaxTrivia FindTriviaByOffset(SyntaxNode node, int textOffset, Func<SyntaxTrivia, bool> stepInto = null)
{
recurse:
if (textOffset >= 0)
{
foreach (var element in node.ChildNodesAndTokens())
......@@ -932,7 +933,8 @@ internal static SyntaxTrivia FindTriviaByOffset(SyntaxNode node, int textOffset,
{
if (element.IsNode)
{
return FindTriviaByOffset(element.AsNode(), textOffset, stepInto);
node = element.AsNode();
goto recurse;
}
else if (element.IsToken)
{
......@@ -946,7 +948,8 @@ internal static SyntaxTrivia FindTriviaByOffset(SyntaxNode node, int textOffset,
{
if (trivia.HasStructure && stepInto != null && stepInto(trivia))
{
return FindTriviaByOffset(trivia.GetStructure(), textOffset, stepInto);
node = trivia.GetStructure();
goto recurse;
}
return trivia;
......@@ -964,7 +967,8 @@ internal static SyntaxTrivia FindTriviaByOffset(SyntaxNode node, int textOffset,
{
if (trivia.HasStructure && stepInto != null && stepInto(trivia))
{
return FindTriviaByOffset(trivia.GetStructure(), textOffset, stepInto);
node = trivia.GetStructure();
goto recurse;
}
return trivia;
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Globalization
Imports System.Text
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
......@@ -3141,6 +3142,27 @@ End Module
Assert.Equal(1, x.Count)
End Sub
<WorkItem(6536, "https://github.com/dotnet/roslyn/issues/6536")>
<Fact>
Public Sub TestFindTrivia_NoStackOverflowOnLargeExpression()
Dim code As New StringBuilder()
code.Append(<![CDATA[
Module Module1
Sub Test()
Dim c = ]]>.Value)
For i = 0 To 3000
code.Append("""asdf"" + ")
Next
code.AppendLine(<![CDATA["last"
End Sub
End Module]]>.Value)
Dim tree = VisualBasicSyntaxTree.ParseText(code.ToString())
Dim trivia = tree.GetRoot().FindTrivia(4000)
' no stack overflow
End Sub
#Region "Equality Verifications"
<Fact>
Public Sub Test_GlobalImportsEqual()
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Text
Imports Microsoft.CodeAnalysis.Text
Imports Roslyn.Test.Utilities
Imports Xunit
Imports Microsoft.CodeAnalysis.VisualBasic.Extensions.SyntaxTreeExtensions
Imports System.Threading
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Public Class VisualBasicExtensionsTests
<WorkItem(6536, "https://github.com/dotnet/roslyn/issues/6536")>
<Fact>
Public Sub TestFindTrivia_NoStackOverflowOnLargeExpression()
Dim code As New StringBuilder()
code.Append(<![CDATA[
Module Module1
Sub Test()
Dim c = ]]>.Value)
For i = 0 To 3000
code.Append("""asdf"" + ")
Next
code.AppendLine(<![CDATA["last"
End Sub
End Module]]>.Value)
Dim tree = VisualBasicSyntaxTree.ParseText(code.ToString())
Dim trivia = tree.FindTriviaToLeft(4000, CancellationToken.None)
' no stack overflow
End Sub
End Class
End Namespace
\ No newline at end of file
......@@ -92,6 +92,7 @@
<DesignTime>True</DesignTime>
</Compile>
<Compile Include="VisualBasicCommandLineArgumentsFactoryServiceTests.vb" />
<Compile Include="VisualBasicExtensionsTests.vb" />
<Compile Include="VisualBasicSyntaxFactsServiceTests.vb" />
</ItemGroup>
<ItemGroup>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册