44using System . Collections . Generic ;
55using System . ComponentModel . Composition ;
66using System . Linq ;
7+ using System . Net . Http . Headers ;
78using System . Threading ;
89using Microsoft . CodeAnalysis ;
910using Microsoft . CodeAnalysis . CSharp ;
1011using Microsoft . CodeAnalysis . CSharp . Extensions ;
1112using Microsoft . CodeAnalysis . CSharp . Syntax ;
1213using Microsoft . CodeAnalysis . Editor . Implementation . Highlighting ;
14+ using Microsoft . CodeAnalysis . PooledObjects ;
1315using Microsoft . CodeAnalysis . Text ;
1416
1517namespace Microsoft . CodeAnalysis . Editor . CSharp . KeywordHighlighting . KeywordHighlighters
1618{
1719 [ ExportHighlighter ( LanguageNames . CSharp ) ]
1820 internal class AsyncAwaitHighlighter : AbstractKeywordHighlighter
1921 {
22+ private static readonly ObjectPool < Stack < SyntaxNode > > s_stackPool
23+ = new ObjectPool < Stack < SyntaxNode > > ( ( ) => new Stack < SyntaxNode > ( ) ) ;
24+
2025 [ ImportingConstructor ]
2126 public AsyncAwaitHighlighter ( )
2227 {
@@ -28,13 +33,40 @@ protected override bool IsHighlightableNode(SyntaxNode node)
2833 protected override IEnumerable < TextSpan > GetHighlightsForNode ( SyntaxNode node , CancellationToken cancellationToken )
2934 {
3035 var spans = new List < TextSpan > ( ) ;
31- foreach ( var child in node . DescendantNodesAndSelf ( n => ! n . IsReturnableConstruct ( ) ) )
36+
37+ foreach ( var current in WalkChildren ( node ) )
3238 {
33- HighlightRelatedKeywords ( node , spans ) ;
39+ cancellationToken . ThrowIfCancellationRequested ( ) ;
40+ HighlightRelatedKeywords ( current , spans ) ;
3441 }
42+
3543 return spans ;
3644 }
3745
46+ private IEnumerable < SyntaxNode > WalkChildren ( SyntaxNode node )
47+ {
48+ using ( var pooledObject = s_stackPool . GetPooledObject ( ) )
49+ {
50+ var stack = pooledObject . Object ;
51+ stack . Push ( node ) ;
52+
53+ while ( stack . Count > 0 )
54+ {
55+ var current = stack . Pop ( ) ;
56+ yield return current ;
57+
58+ foreach ( var child in current . ChildNodes ( ) )
59+ {
60+ // Only recurse if we have anything to do
61+ if ( ! child . IsReturnableConstruct ( ) )
62+ {
63+ stack . Push ( child ) ;
64+ }
65+ }
66+ }
67+ }
68+ }
69+
3870 private static void HighlightRelatedKeywords ( SyntaxNode node , List < TextSpan > spans )
3971 {
4072 // Highlight async keyword
0 commit comments