提交 75756ed8 编写于 作者: M Matt Warren

Merge pull request #3230 from mattwar/GetNextToken

Remove recursion in GetFirstToken and GetLastToken
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis
{
......@@ -51,38 +53,95 @@ internal SyntaxToken GetNextToken(SyntaxToken current, Func<SyntaxToken, bool> p
return GetNextToken(current, predicate, stepInto != null, stepInto);
}
private static readonly ObjectPool<Stack<ChildSyntaxList.Enumerator>> s_childEnumeratorStackPool
= new ObjectPool<Stack<ChildSyntaxList.Enumerator>>(() => new Stack<ChildSyntaxList.Enumerator>(), 10);
internal SyntaxToken GetFirstToken(SyntaxNode current, Func<SyntaxToken, bool> predicate, Func<SyntaxTrivia, bool> stepInto)
{
foreach (var child in current.ChildNodesAndTokens())
var stack = s_childEnumeratorStackPool.Allocate();
try
{
var token = child.IsToken
? GetFirstToken(child.AsToken(), predicate, stepInto)
: GetFirstToken(child.AsNode(), predicate, stepInto);
stack.Push(current.ChildNodesAndTokens().GetEnumerator());
if (token.RawKind != None)
while (stack.Count > 0)
{
return token;
var en = stack.Pop();
if (en.MoveNext())
{
var child = en.Current;
if (child.IsToken)
{
var token = GetFirstToken(child.AsToken(), predicate, stepInto);
if (token.RawKind != None)
{
return token;
}
}
// push this enumerator back, not done yet
stack.Push(en);
if (child.IsNode)
{
stack.Push(child.AsNode().ChildNodesAndTokens().GetEnumerator());
}
}
}
}
return default(SyntaxToken);
return default(SyntaxToken);
}
finally
{
stack.Clear();
s_childEnumeratorStackPool.Free(stack);
}
}
private static readonly ObjectPool<Stack<ChildSyntaxList.Reversed.Enumerator>> s_childReversedEnumeratorStackPool
= new ObjectPool<Stack<ChildSyntaxList.Reversed.Enumerator>>(() => new Stack<ChildSyntaxList.Reversed.Enumerator>(), 10);
internal SyntaxToken GetLastToken(SyntaxNode current, Func<SyntaxToken, bool> predicate, Func<SyntaxTrivia, bool> stepInto)
{
foreach (var child in current.ChildNodesAndTokens().Reverse())
var stack = s_childReversedEnumeratorStackPool.Allocate();
try
{
var token = child.IsToken
? GetLastToken(child.AsToken(), predicate, stepInto)
: GetLastToken(child.AsNode(), predicate, stepInto);
stack.Push(current.ChildNodesAndTokens().Reverse().GetEnumerator());
if (token.RawKind != None)
while (stack.Count > 0)
{
return token;
var en = stack.Pop();
if (en.MoveNext())
{
var child = en.Current;
if (child.IsToken)
{
var token = GetLastToken(child.AsToken(), predicate, stepInto);
if (token.RawKind != None)
{
return token;
}
}
// push this enumerator back, not done yet
stack.Push(en);
if (child.IsNode)
{
stack.Push(child.AsNode().ChildNodesAndTokens().Reverse().GetEnumerator());
}
}
}
}
return default(SyntaxToken);
return default(SyntaxToken);
}
finally
{
stack.Clear();
s_childReversedEnumeratorStackPool.Free(stack);
}
}
private SyntaxToken GetFirstToken(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册