未验证 提交 4ef834c2 编写于 作者: A Andrew Hall 提交者: GitHub

Merge pull request #40372 from CyrusNajmabadi/highlightPerf

Remove unnecessary allocations in 'keyword highlighting'
......@@ -27,17 +27,13 @@ public AsyncAwaitHighlighter()
protected override bool IsHighlightableNode(SyntaxNode node)
=> node.IsReturnableConstruct();
protected override IEnumerable<TextSpan> GetHighlightsForNode(SyntaxNode node, CancellationToken cancellationToken)
protected override void AddHighlightsForNode(SyntaxNode node, List<TextSpan> highlights, CancellationToken cancellationToken)
{
var spans = new List<TextSpan>();
foreach (var current in WalkChildren(node))
{
cancellationToken.ThrowIfCancellationRequested();
HighlightRelatedKeywords(current, spans);
HighlightRelatedKeywords(current, highlights);
}
return spans;
}
private IEnumerable<SyntaxNode> WalkChildren(SyntaxNode node)
......
......@@ -18,18 +18,7 @@ public CheckedExpressionHighlighter()
{
}
protected override IEnumerable<TextSpan> GetHighlights(
CheckedExpressionSyntax checkedExpressionSyntax, CancellationToken cancellationToken)
{
switch (checkedExpressionSyntax.Kind())
{
case SyntaxKind.CheckedExpression:
case SyntaxKind.UncheckedExpression:
yield return checkedExpressionSyntax.Keyword.Span;
break;
default:
yield break;
}
}
protected override void AddHighlights(CheckedExpressionSyntax checkedExpressionSyntax, List<TextSpan> highlights, CancellationToken cancellationToken)
=> highlights.Add(checkedExpressionSyntax.Keyword.Span);
}
}
......@@ -17,10 +17,7 @@ public CheckedStatementHighlighter()
{
}
protected override IEnumerable<TextSpan> GetHighlights(
CheckedStatementSyntax checkedStatement, CancellationToken cancellationToken)
{
yield return checkedStatement.Keyword.Span;
}
protected override void AddHighlights(CheckedStatementSyntax checkedStatement, List<TextSpan> highlights, CancellationToken cancellationToken)
=> highlights.Add(checkedStatement.Keyword.Span);
}
}
......@@ -18,20 +18,20 @@ public ConditionalPreprocessorHighlighter()
{
}
protected override IEnumerable<TextSpan> GetHighlights(
DirectiveTriviaSyntax directive, CancellationToken cancellationToken)
protected override void AddHighlights(
DirectiveTriviaSyntax directive, List<TextSpan> highlights, CancellationToken cancellationToken)
{
var conditionals = directive.GetMatchingConditionalDirectives(cancellationToken);
if (conditionals == null)
{
yield break;
return;
}
foreach (var conditional in conditionals)
{
yield return TextSpan.FromBounds(
highlights.Add(TextSpan.FromBounds(
conditional.HashToken.SpanStart,
conditional.DirectiveNameToken.Span.End);
conditional.DirectiveNameToken.Span.End));
}
}
}
......
......@@ -21,21 +21,19 @@ public IfStatementHighlighter()
{
}
protected override IEnumerable<TextSpan> GetHighlights(
IfStatementSyntax ifStatement, CancellationToken cancellationToken)
protected override void AddHighlights(
IfStatementSyntax ifStatement, List<TextSpan> highlights, CancellationToken cancellationToken)
{
if (ifStatement.Parent.Kind() != SyntaxKind.ElseClause)
{
return ComputeSpans(ifStatement);
ComputeSpans(ifStatement, highlights);
}
return Enumerable.Empty<TextSpan>();
}
private IEnumerable<TextSpan> ComputeSpans(
IfStatementSyntax ifStatement)
private void ComputeSpans(
IfStatementSyntax ifStatement, List<TextSpan> highlights)
{
yield return ifStatement.IfKeyword.Span;
highlights.Add(ifStatement.IfKeyword.Span);
// Loop to get all the else if parts
while (ifStatement != null && ifStatement.Else != null)
......@@ -48,15 +46,15 @@ public IfStatementHighlighter()
if (OnlySpacesBetween(elseKeyword, elseIfStatement.IfKeyword))
{
// Highlight both else and if tokens if they are on the same line
yield return TextSpan.FromBounds(
highlights.Add(TextSpan.FromBounds(
elseKeyword.SpanStart,
elseIfStatement.IfKeyword.Span.End);
elseIfStatement.IfKeyword.Span.End));
}
else
{
// Highlight the else and if tokens separately
yield return elseKeyword.Span;
yield return elseIfStatement.IfKeyword.Span;
highlights.Add(elseKeyword.Span);
highlights.Add(elseIfStatement.IfKeyword.Span);
}
// Continue the enumeration looking for more else blocks
......@@ -65,7 +63,7 @@ public IfStatementHighlighter()
else
{
// Highlight just the else and we're done
yield return elseKeyword.Span;
highlights.Add(elseKeyword.Span);
break;
}
}
......
......@@ -17,10 +17,7 @@ public LockStatementHighlighter()
{
}
protected override IEnumerable<TextSpan> GetHighlights(
LockStatementSyntax lockStatement, CancellationToken cancellationToken)
{
yield return lockStatement.LockKeyword.Span;
}
protected override void AddHighlights(LockStatementSyntax lockStatement, List<TextSpan> highlights, CancellationToken cancellationToken)
=> highlights.Add(lockStatement.LockKeyword.Span);
}
}
......@@ -22,11 +22,9 @@ public LoopHighlighter()
protected override bool IsHighlightableNode(SyntaxNode node)
=> node.IsContinuableConstruct();
protected override IEnumerable<TextSpan> GetHighlightsForNode(
SyntaxNode node, CancellationToken cancellationToken)
protected override void AddHighlightsForNode(
SyntaxNode node, List<TextSpan> spans, CancellationToken cancellationToken)
{
var spans = new List<TextSpan>();
switch (node)
{
case DoStatementSyntax doStatement:
......@@ -44,8 +42,6 @@ protected override bool IsHighlightableNode(SyntaxNode node)
}
HighlightRelatedKeywords(node, spans, highlightBreaks: true, highlightContinues: true);
return spans;
}
private void HighlightDoStatement(DoStatementSyntax statement, List<TextSpan> spans)
......
......@@ -18,22 +18,22 @@ public RegionHighlighter()
{
}
protected override IEnumerable<TextSpan> GetHighlights(
DirectiveTriviaSyntax directive, CancellationToken cancellationToken)
protected override void AddHighlights(
DirectiveTriviaSyntax directive, List<TextSpan> highlights, CancellationToken cancellationToken)
{
var matchingDirective = directive.GetMatchingDirective(cancellationToken);
if (matchingDirective == null)
{
yield break;
return;
}
yield return TextSpan.FromBounds(
highlights.Add(TextSpan.FromBounds(
directive.HashToken.SpanStart,
directive.DirectiveNameToken.Span.End);
directive.DirectiveNameToken.Span.End));
yield return TextSpan.FromBounds(
highlights.Add(TextSpan.FromBounds(
matchingDirective.HashToken.SpanStart,
matchingDirective.DirectiveNameToken.Span.End);
matchingDirective.DirectiveNameToken.Span.End));
}
}
}
......@@ -9,7 +9,6 @@
using Microsoft.CodeAnalysis.Editor.Implementation.Highlighting;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighlighters
{
......@@ -21,8 +20,8 @@ public ReturnStatementHighlighter()
{
}
protected override IEnumerable<TextSpan> GetHighlights(
ReturnStatementSyntax returnStatement, CancellationToken cancellationToken)
protected override void AddHighlights(
ReturnStatementSyntax returnStatement, List<TextSpan> spans, CancellationToken cancellationToken)
{
var parent = returnStatement
.GetAncestorsOrThis<SyntaxNode>()
......@@ -30,14 +29,10 @@ public ReturnStatementHighlighter()
if (parent == null)
{
return SpecializedCollections.EmptyEnumerable<TextSpan>();
return;
}
var spans = new List<TextSpan>();
HighlightRelatedKeywords(parent, spans);
return spans;
}
/// <summary>
......@@ -52,13 +47,14 @@ private void HighlightRelatedKeywords(SyntaxNode node, List<TextSpan> spans)
spans.Add(EmptySpan(statement.SemicolonToken.Span.End));
break;
default:
foreach (var child in node.ChildNodes())
foreach (var child in node.ChildNodesAndTokens())
{
if (child.IsToken)
continue;
// Only recurse if we have anything to do
if (!child.IsReturnableConstruct())
{
HighlightRelatedKeywords(child, spans);
}
if (!child.AsNode().IsReturnableConstruct())
HighlightRelatedKeywords(child.AsNode(), spans);
}
break;
}
......
......@@ -20,11 +20,9 @@ public SwitchStatementHighlighter()
{
}
protected override IEnumerable<TextSpan> GetHighlights(
SwitchStatementSyntax switchStatement, CancellationToken cancellationToken)
protected override void AddHighlights(
SwitchStatementSyntax switchStatement, List<TextSpan> spans, CancellationToken cancellationToken)
{
var spans = new List<TextSpan>();
spans.Add(switchStatement.SwitchKeyword.Span);
foreach (var switchSection in switchStatement.Sections)
......@@ -37,8 +35,6 @@ public SwitchStatementHighlighter()
HighlightRelatedKeywords(switchSection, spans, highlightBreaks: true, highlightGotos: true);
}
return spans;
}
/// <summary>
......@@ -74,8 +70,12 @@ public SwitchStatementHighlighter()
}
else
{
foreach (var child in node.ChildNodes())
foreach (var childNodeOrToken in node.ChildNodesAndTokens())
{
if (childNodeOrToken.IsToken)
continue;
var child = childNodeOrToken.AsNode();
var highlightBreaksForChild = highlightBreaks && !child.IsBreakableConstruct();
var highlightGotosForChild = highlightGotos && !child.IsKind(SyntaxKind.SwitchStatement);
......
......@@ -17,24 +17,24 @@ public TryStatementHighlighter()
{
}
protected override IEnumerable<TextSpan> GetHighlights(
TryStatementSyntax tryStatement, CancellationToken cancellationToken)
protected override void AddHighlights(
TryStatementSyntax tryStatement, List<TextSpan> highlights, CancellationToken cancellationToken)
{
yield return tryStatement.TryKeyword.Span;
highlights.Add(tryStatement.TryKeyword.Span);
foreach (var catchDeclaration in tryStatement.Catches)
{
yield return catchDeclaration.CatchKeyword.Span;
highlights.Add(catchDeclaration.CatchKeyword.Span);
if (catchDeclaration.Filter != null)
{
yield return catchDeclaration.Filter.WhenKeyword.Span;
highlights.Add(catchDeclaration.Filter.WhenKeyword.Span);
}
}
if (tryStatement.Finally != null)
{
yield return tryStatement.Finally.FinallyKeyword.Span;
highlights.Add(tryStatement.Finally.FinallyKeyword.Span);
}
}
}
......
......@@ -17,10 +17,7 @@ public UnsafeStatementHighlighter()
{
}
protected override IEnumerable<TextSpan> GetHighlights(
UnsafeStatementSyntax unsafeStatement, CancellationToken cancellationToken)
{
yield return unsafeStatement.UnsafeKeyword.Span;
}
protected override void AddHighlights(UnsafeStatementSyntax unsafeStatement, List<TextSpan> highlights, CancellationToken cancellationToken)
=> highlights.Add(unsafeStatement.UnsafeKeyword.Span);
}
}
......@@ -17,10 +17,7 @@ public UsingStatementHighlighter()
{
}
protected override IEnumerable<TextSpan> GetHighlights(
UsingStatementSyntax usingStatement, CancellationToken cancellationToken)
{
yield return usingStatement.UsingKeyword.Span;
}
protected override void AddHighlights(UsingStatementSyntax usingStatement, List<TextSpan> highlights, CancellationToken cancellationToken)
=> highlights.Add(usingStatement.UsingKeyword.Span);
}
}
......@@ -9,7 +9,6 @@
using Microsoft.CodeAnalysis.Editor.Implementation.Highlighting;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.CSharp.KeywordHighlighting.KeywordHighlighters
{
......@@ -21,8 +20,8 @@ public YieldStatementHighlighter()
{
}
protected override IEnumerable<TextSpan> GetHighlights(
YieldStatementSyntax yieldStatement, CancellationToken cancellationToken)
protected override void AddHighlights(
YieldStatementSyntax yieldStatement, List<TextSpan> spans, CancellationToken cancellationToken)
{
var parent = yieldStatement
.GetAncestorsOrThis<SyntaxNode>()
......@@ -30,14 +29,10 @@ public YieldStatementHighlighter()
if (parent == null)
{
return SpecializedCollections.EmptyEnumerable<TextSpan>();
return;
}
var spans = new List<TextSpan>();
HighlightRelatedKeywords(parent, spans);
return spans;
}
/// <summary>
......@@ -56,12 +51,15 @@ private void HighlightRelatedKeywords(SyntaxNode node, List<TextSpan> spans)
spans.Add(EmptySpan(statement.SemicolonToken.Span.End));
break;
default:
foreach (var child in node.ChildNodes())
foreach (var child in node.ChildNodesAndTokens())
{
if (child.IsToken)
continue;
// Only recurse if we have anything to do
if (!child.IsReturnableConstruct())
if (!child.AsNode().IsReturnableConstruct())
{
HighlightRelatedKeywords(child, spans);
HighlightRelatedKeywords(child.AsNode(), spans);
}
}
break;
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class AsyncAnonymousFunctionHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new AsyncAwaitHighlighter();
}
=> new AsyncAwaitHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestSimpleLambda()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class AsyncLocalFunctionHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new AsyncAwaitHighlighter();
}
=> new AsyncAwaitHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestLocalFunction()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class AsyncMethodHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new AsyncAwaitHighlighter();
}
=> new AsyncAwaitHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestExample1_1()
......
......@@ -11,9 +11,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class AwaitHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new AsyncAwaitHighlighter();
}
=> new AsyncAwaitHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestExample2_2()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class CheckedExpressionHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new CheckedExpressionHighlighter();
}
=> new CheckedExpressionHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestExample1_1()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class CheckedStatementHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new CheckedStatementHighlighter();
}
=> new CheckedStatementHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestExample1_1()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class ConditionalPreprocessorHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new ConditionalPreprocessorHighlighter();
}
=> new ConditionalPreprocessorHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestExample1_1()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class IfStatementHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new IfStatementHighlighter();
}
=> new IfStatementHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestIfStatementWithIfAndSingleElse1()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class LockStatementHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new LockStatementHighlighter();
}
=> new LockStatementHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestExample1_1()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class LoopHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new LoopHighlighter();
}
=> new LoopHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestExample1_1()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class RegionHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new RegionHighlighter();
}
=> new RegionHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestExample1_1()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class ReturnStatementHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new ReturnStatementHighlighter();
}
=> new ReturnStatementHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestInLambda()
......
......@@ -11,9 +11,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class SwitchStatementHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new SwitchStatementHighlighter();
}
=> new SwitchStatementHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestExample1_OnSwitchKeyword()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class TryStatementHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new TryStatementHighlighter();
}
=> new TryStatementHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestExample1_1()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class UnsafeStatementHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new UnsafeStatementHighlighter();
}
=> new UnsafeStatementHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestExample1_1()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class UsingStatementHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new UsingStatementHighlighter();
}
=> new UsingStatementHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestExample1_1()
......
......@@ -10,9 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting
public class YieldStatementHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
internal override IHighlighter CreateHighlighter()
{
return new YieldStatementHighlighter();
}
=> new YieldStatementHighlighter();
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestExample1_1()
......
......@@ -8,6 +8,6 @@ namespace Microsoft.CodeAnalysis.Editor
{
internal interface IHighlighter
{
IEnumerable<TextSpan> GetHighlights(SyntaxNode root, int position, CancellationToken cancellationToken);
void AddHighlights(SyntaxNode root, int position, List<TextSpan> highlights, CancellationToken cancellationToken);
}
}
......@@ -8,6 +8,12 @@ namespace Microsoft.CodeAnalysis.Editor
{
internal interface IHighlightingService
{
IEnumerable<TextSpan> GetHighlights(SyntaxNode root, int position, CancellationToken cancellationToken);
/// <summary>
/// Adds all the relevant highlihts to <paramref name="highlights"/> given the specified
/// <paramref name="position"/> in the tree.
/// <para/>
/// Highlights will be unique and will be in sorted order. All highlights will be non-empty.
/// </summary>
void AddHighlights(SyntaxNode root, int position, List<TextSpan> highlights, CancellationToken cancellationToken);
}
}
......@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
......@@ -12,67 +13,85 @@ internal abstract class AbstractKeywordHighlighter<TNode> : AbstractKeywordHighl
{
protected sealed override bool IsHighlightableNode(SyntaxNode node) => node is TNode;
protected sealed override IEnumerable<TextSpan> GetHighlightsForNode(SyntaxNode node, CancellationToken cancellationToken)
=> GetHighlights((TNode)node, cancellationToken);
protected sealed override void AddHighlightsForNode(SyntaxNode node, List<TextSpan> highlights, CancellationToken cancellationToken)
=> AddHighlights((TNode)node, highlights, cancellationToken);
protected abstract IEnumerable<TextSpan> GetHighlights(TNode node, CancellationToken cancellationToken);
protected abstract void AddHighlights(TNode node, List<TextSpan> highlights, CancellationToken cancellationToken);
}
internal abstract class AbstractKeywordHighlighter : IHighlighter
{
private static readonly ObjectPool<List<TextSpan>> s_textSpanListPool = new ObjectPool<List<TextSpan>>(() => new List<TextSpan>());
private static readonly ObjectPool<List<SyntaxToken>> s_tokenListPool = new ObjectPool<List<SyntaxToken>>(() => new List<SyntaxToken>());
protected abstract bool IsHighlightableNode(SyntaxNode node);
public IEnumerable<TextSpan> GetHighlights(
SyntaxNode root, int position, CancellationToken cancellationToken)
public void AddHighlights(
SyntaxNode root, int position, List<TextSpan> highlights, CancellationToken cancellationToken)
{
foreach (var token in GetTokens(root, position))
using (s_textSpanListPool.GetPooledObject(out var tempHighlights))
using (s_tokenListPool.GetPooledObject(out var touchingTokens))
{
for (var parent = token.Parent; parent != null; parent = parent.Parent)
AddTouchingTokens(root, position, touchingTokens);
foreach (var token in touchingTokens)
{
if (IsHighlightableNode(parent))
for (var parent = token.Parent; parent != null; parent = parent.Parent)
{
var highlights = GetHighlightsForNode(parent, cancellationToken);
// Only return them if any of them matched
if (highlights.Any(span => span.IntersectsWith(position)))
if (IsHighlightableNode(parent))
{
// Return the non-empty spans
return highlights.Where(s => !s.IsEmpty).Distinct();
tempHighlights.Clear();
AddHighlightsForNode(parent, tempHighlights, cancellationToken);
if (AnyIntersects(position, tempHighlights))
{
highlights.AddRange(tempHighlights);
return;
}
}
}
}
}
}
private static bool AnyIntersects(int position, List<TextSpan> highlights)
{
foreach (var highlight in highlights)
{
if (highlight.IntersectsWith(position))
{
return true;
}
}
return SpecializedCollections.EmptyEnumerable<TextSpan>();
return false;
}
protected abstract IEnumerable<TextSpan> GetHighlightsForNode(SyntaxNode node, CancellationToken cancellationToken);
protected abstract void AddHighlightsForNode(SyntaxNode node, List<TextSpan> highlights, CancellationToken cancellationToken);
protected TextSpan EmptySpan(int position)
{
return new TextSpan(position, 0);
}
internal static IEnumerable<SyntaxToken> GetTokens(
SyntaxNode root,
int position)
internal static void AddTouchingTokens(SyntaxNode root, int position, List<SyntaxToken> tokens)
{
var tokens1 = GetTokens(root, position, findInsideTrivia: true);
var tokens2 = GetTokens(root, position, findInsideTrivia: false);
return tokens1.Concat(tokens2);
AddTouchingTokens(root, position, tokens, findInsideTrivia: true);
AddTouchingTokens(root, position, tokens, findInsideTrivia: false);
}
private static IEnumerable<SyntaxToken> GetTokens(
SyntaxNode root,
int position,
bool findInsideTrivia)
private static void AddTouchingTokens(SyntaxNode root, int position, List<SyntaxToken> tokens, bool findInsideTrivia)
{
yield return root.FindToken(position - 0, findInsideTrivia);
var token = root.FindToken(position, findInsideTrivia);
if (!tokens.Contains(token))
tokens.Add(token);
if (position > 0)
{
yield return root.FindToken(position - 1, findInsideTrivia);
}
if (position == 0)
return;
var previous = root.FindToken(position - 1, findInsideTrivia);
if (previous.Span.End == position && !tokens.Contains(previous))
tokens.Add(previous);
}
}
}
......@@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
......@@ -27,6 +28,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Highlighting
internal class HighlighterViewTaggerProvider : AsynchronousViewTaggerProvider<KeywordHighlightTag>
{
private readonly IHighlightingService _highlightingService;
private static readonly PooledObjects.ObjectPool<List<TextSpan>> s_listPool = new PooledObjects.ObjectPool<List<TextSpan>>(() => new List<TextSpan>());
// Whenever an edit happens, clear all highlights. When moving the caret, preserve
// highlights if the caret stays within an existing tag.
......@@ -96,11 +98,13 @@ protected override async Task ProduceTagsAsync(TaggerContext<KeywordHighlightTag
}
using (Logger.LogBlock(FunctionId.Tagger_Highlighter_TagProducer_ProduceTags, cancellationToken))
using (s_listPool.GetPooledObject(out var highlights))
{
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var spans = _highlightingService.GetHighlights(root, position, cancellationToken);
foreach (var span in spans)
_highlightingService.AddHighlights(root, position, highlights, cancellationToken);
foreach (var span in highlights)
{
context.AddTag(new TagSpan<KeywordHighlightTag>(span.ToSnapshotSpan(snapshot), KeywordHighlightTag.Instance));
}
......
......@@ -7,7 +7,6 @@
using System.Threading;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.Highlighting
{
......@@ -16,6 +15,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Highlighting
internal class HighlightingService : IHighlightingService
{
private readonly List<Lazy<IHighlighter, LanguageMetadata>> _highlighters;
private static readonly PooledObjects.ObjectPool<List<TextSpan>> s_listPool = new PooledObjects.ObjectPool<List<TextSpan>>(() => new List<TextSpan>());
[ImportingConstructor]
public HighlightingService(
......@@ -24,14 +24,28 @@ internal class HighlightingService : IHighlightingService
_highlighters = highlighters.ToList();
}
public IEnumerable<TextSpan> GetHighlights(
SyntaxNode root, int position, CancellationToken cancellationToken)
public void AddHighlights(
SyntaxNode root, int position, List<TextSpan> highlights, CancellationToken cancellationToken)
{
return _highlighters.Where(h => h.Metadata.Language == root.Language)
.Select(h => h.Value.GetHighlights(root, position, cancellationToken))
.WhereNotNull()
.Flatten()
.Distinct();
using (s_listPool.GetPooledObject(out var tempHighlights))
{
foreach (var highlighter in _highlighters.Where(h => h.Metadata.Language == root.Language))
{
cancellationToken.ThrowIfCancellationRequested();
highlighter.Value.AddHighlights(root, position, tempHighlights, cancellationToken);
}
tempHighlights.Sort();
var lastSpan = default(TextSpan);
foreach (var span in tempHighlights)
{
if (span != lastSpan && !span.IsEmpty)
{
highlights.Add(span);
lastSpan = span;
}
}
}
}
}
}
......@@ -8,8 +8,9 @@
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using Xunit;
using Microsoft.CodeAnalysis.Editor.Implementation.Highlighting;
using Microsoft.CodeAnalysis.Host.Mef;
namespace Microsoft.CodeAnalysis.Editor.UnitTests.KeywordHighlighting
{
......@@ -29,35 +30,34 @@ public abstract class AbstractKeywordHighlighterTests
}
}
private async Task TestAsync(
string markup,
ParseOptions options,
bool optionIsEnabled = true)
private async Task TestAsync(string markup, ParseOptions options)
{
using (var workspace = CreateWorkspaceFromFile(markup, options))
{
var testDocument = workspace.Documents.Single();
var expectedHighlightSpans = testDocument.SelectedSpans ?? new List<TextSpan>();
expectedHighlightSpans = Sort(expectedHighlightSpans);
var cursorSpan = testDocument.AnnotatedSpans["Cursor"].Single();
var textSnapshot = testDocument.GetTextBuffer().CurrentSnapshot;
var document = workspace.CurrentSolution.GetDocument(testDocument.Id);
using var workspace = CreateWorkspaceFromFile(markup, options);
var testDocument = workspace.Documents.Single();
var expectedHighlightSpans = testDocument.SelectedSpans.ToList();
expectedHighlightSpans.Sort();
// If the position being tested is immediately following the keyword,
// we should get the token before this position to find the appropriate
// ancestor node.
var highlighter = CreateHighlighter();
var cursorSpan = testDocument.AnnotatedSpans["Cursor"].Single();
var textSnapshot = testDocument.GetTextBuffer().CurrentSnapshot;
var document = workspace.CurrentSolution.GetDocument(testDocument.Id);
var root = await document.GetSyntaxRootAsync();
var highlighter = CreateHighlighter();
var service = new HighlightingService(new List<Lazy<IHighlighter, LanguageMetadata>>
{
new Lazy<IHighlighter, LanguageMetadata>(() => highlighter, new LanguageMetadata(document.Project.Language)),
});
for (var i = 0; i <= cursorSpan.Length; i++)
{
var position = cursorSpan.Start + i;
var highlightSpans = highlighter.GetHighlights(root, position, CancellationToken.None).ToList();
highlightSpans = Sort(highlightSpans);
var root = await document.GetSyntaxRootAsync();
CheckSpans(root.SyntaxTree, expectedHighlightSpans, highlightSpans);
}
// Check that every point within the span (inclusive) produces the expected set of
// results.
for (var i = 0; i <= cursorSpan.Length; i++)
{
var position = cursorSpan.Start + i;
var highlightSpans = new List<TextSpan>();
service.AddHighlights(root, position, highlightSpans, CancellationToken.None);
CheckSpans(root.SyntaxTree, expectedHighlightSpans, highlightSpans);
}
}
......@@ -85,10 +85,5 @@ private static void CheckSpans(SyntaxTree tree, IList<TextSpan> expectedHighligh
Assert.Equal(tree.GetLineSpan(expected).Span, tree.GetLineSpan(actual).Span);
}
}
private List<TextSpan> Sort(IEnumerable<TextSpan> spans)
{
return spans.OrderBy((s1, s2) => s1.Start - s2.Start).ToList();
}
}
}
......@@ -15,14 +15,12 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim methodBlock = node.GetAncestor(Of MethodBlockBaseSyntax)()
If methodBlock Is Nothing OrElse Not TypeOf methodBlock.BlockStatement Is AccessorStatementSyntax Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)()
With methodBlock
Dim isIterator = False
......@@ -52,8 +50,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.EndBlockStatement.Span)
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,14 +15,12 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(directive As DirectiveTriviaSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(directive As DirectiveTriviaSyntax, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim conditionals = directive.GetMatchingConditionalDirectives(cancellationToken)
If conditionals Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)
For Each conditional In conditionals
If TypeOf conditional Is IfDirectiveTriviaSyntax Then
With DirectCast(conditional, IfDirectiveTriviaSyntax)
......@@ -41,8 +39,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
End With
End If
Next
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,14 +15,12 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim methodBlock = node.GetAncestor(Of MethodBlockBaseSyntax)()
If methodBlock Is Nothing OrElse Not TypeOf methodBlock.BlockStatement Is SubNewStatementSyntax Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)()
With methodBlock
With DirectCast(.BlockStatement, SubNewStatementSyntax)
Dim firstKeyword = If(.Modifiers.Count > 0, .Modifiers.First(), .DeclarationKeyword)
......@@ -36,8 +34,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.EndBlockStatement.Span)
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,22 +15,20 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
If node.IsIncorrectContinueStatement(SyntaxKind.ContinueDoStatement) Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
If node.IsIncorrectExitStatement(SyntaxKind.ExitDoStatement) Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim doLoop = node.GetAncestor(Of DoLoopBlockSyntax)()
If doLoop Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)
With doLoop.DoStatement
If .WhileOrUntilClause IsNot Nothing Then
highlights.Add(TextSpan.FromBounds(.DoKeyword.SpanStart, .WhileOrUntilClause.WhileOrUntilKeyword.Span.End))
......@@ -50,8 +48,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.LoopKeyword.Span)
End If
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,21 +15,19 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim endBlockStatement = TryCast(node, EndBlockStatementSyntax)
If endBlockStatement IsNot Nothing Then
If endBlockStatement.Kind <> SyntaxKind.EndEnumStatement Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
End If
Dim enumBlock = node.GetAncestor(Of EnumBlockSyntax)()
If enumBlock Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)
With enumBlock
With .EnumStatement
Dim firstKeyword = If(.Modifiers.Count > 0, .Modifiers.First(), .EnumKeyword)
......@@ -38,8 +36,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.EndEnumStatement.Span)
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,14 +15,12 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim eventBlock = node.GetAncestor(Of EventBlockSyntax)()
If eventBlock Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)()
With eventBlock
With .EventStatement
' This span calculation should also capture the Custom keyword
......@@ -36,8 +34,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.EndEventStatement.Span)
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,16 +15,14 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overrides Function GetHighlights(eventDeclaration As EventStatementSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overrides Sub AddHighlights(eventDeclaration As EventStatementSyntax, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
' If the ancestor is not a event block, treat this as a single line event.
' Otherwise, let the EventBlockHighlighter take over.
Dim eventBlock = eventDeclaration.GetAncestor(Of EventBlockSyntax)()
If eventBlock IsNot Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)()
With eventDeclaration
Dim firstKeyword = If(.Modifiers.Count > 0, .Modifiers.First(), .DeclarationKeyword)
highlights.Add(TextSpan.FromBounds(firstKeyword.SpanStart, .DeclarationKeyword.Span.End))
......@@ -33,8 +31,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.ImplementsClause.ImplementsKeyword.Span)
End If
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,14 +15,12 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim forBlock = GetForBlockFromNode(node)
If forBlock Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)
If TypeOf forBlock.ForOrForEachStatement Is ForStatementSyntax Then
With DirectCast(forBlock.ForOrForEachStatement, ForStatementSyntax)
highlights.Add(.ForKeyword.Span)
......@@ -49,9 +47,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
If nextStatement IsNot Nothing Then
highlights.Add(nextStatement.NextKeyword.Span)
End If
Return highlights
End Function
End Sub
Private Function GetForBlockFromNode(node As SyntaxNode) As ForOrForEachBlockSyntax
If node.IsIncorrectContinueStatement(SyntaxKind.ContinueForStatement) OrElse
......
......@@ -15,14 +15,12 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim methodBlock = node.GetAncestor(Of MethodBlockBaseSyntax)()
If methodBlock Is Nothing OrElse Not TypeOf methodBlock.BlockStatement Is MethodStatementSyntax Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)()
With methodBlock
Dim isAsync = False
Dim isIterator = False
......@@ -58,8 +56,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.EndBlockStatement.Span)
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,9 +15,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(ifBlock As MultiLineIfBlockSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Dim highlights As New List(Of TextSpan)
Protected Overloads Overrides Sub addHighlights(ifBlock As MultiLineIfBlockSyntax, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
With ifBlock.IfStatement
' ElseIf case
highlights.Add(.IfKeyword.Span)
......@@ -47,8 +45,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
End If
highlights.Add(ifBlock.EndIfStatement.Span)
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,14 +15,12 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim lambdaExpression = node.GetAncestor(Of MultiLineLambdaExpressionSyntax)()
If lambdaExpression Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)()
With lambdaExpression
Dim isAsync = False
Dim isIterator = False
......@@ -50,8 +48,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.EndSubOrFunctionStatement.Span)
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,16 +15,16 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim namespaceBlock = node.GetAncestor(Of NamespaceBlockSyntax)()
If namespaceBlock Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
With namespaceBlock
Return { .NamespaceStatement.NamespaceKeyword.Span,
.EndNamespaceStatement.Span}
highlights.Add(.NamespaceStatement.NamespaceKeyword.Span)
highlights.Add(.EndNamespaceStatement.Span)
End With
End Function
End Sub
End Class
End Namespace
......@@ -15,14 +15,12 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim methodBlock = node.GetAncestor(Of MethodBlockBaseSyntax)()
If methodBlock Is Nothing OrElse Not TypeOf methodBlock.BlockStatement Is OperatorStatementSyntax Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)()
With methodBlock
With DirectCast(.BlockStatement, OperatorStatementSyntax)
Dim firstKeyword = If(.Modifiers.Count > 0, .Modifiers.First(), .DeclarationKeyword)
......@@ -36,8 +34,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.EndBlockStatement.Span)
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,14 +15,12 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim propertyBlock = node.GetAncestor(Of PropertyBlockSyntax)()
If propertyBlock Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)()
With propertyBlock
With .PropertyStatement
Dim firstKeyword = If(.Modifiers.Count > 0, .Modifiers.First(), .DeclarationKeyword)
......@@ -35,8 +33,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.EndPropertyStatement.Span)
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,16 +15,14 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overrides Function GetHighlights(propertyDeclaration As PropertyStatementSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overrides Sub AddHighlights(propertyDeclaration As PropertyStatementSyntax, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
' If the ancestor is not a property block, treat this as an auto-property.
' Otherwise, let the PropertyBlockHighlighter take over.
Dim propertyBlock = propertyDeclaration.GetAncestor(Of PropertyBlockSyntax)()
If propertyBlock IsNot Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)()
With propertyDeclaration
Dim firstKeyword = If(.Modifiers.Count > 0, .Modifiers.First(), .DeclarationKeyword)
highlights.Add(TextSpan.FromBounds(firstKeyword.SpanStart, .DeclarationKeyword.Span.End))
......@@ -33,8 +31,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.ImplementsClause.ImplementsKeyword.Span)
End If
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,7 +15,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(directive As DirectiveTriviaSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(directive As DirectiveTriviaSyntax, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
If TypeOf directive Is RegionDirectiveTriviaSyntax OrElse
TypeOf directive Is EndRegionDirectiveTriviaSyntax Then
......@@ -30,12 +30,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
DirectCast(directive, EndRegionDirectiveTriviaSyntax),
DirectCast(match, EndRegionDirectiveTriviaSyntax))
Return {TextSpan.FromBounds(region.HashToken.SpanStart, region.RegionKeyword.Span.End),
TextSpan.FromBounds(endRegion.HashToken.SpanStart, endRegion.RegionKeyword.Span.End)}
highlights.Add(TextSpan.FromBounds(region.HashToken.SpanStart, region.RegionKeyword.Span.End))
highlights.Add(TextSpan.FromBounds(endRegion.HashToken.SpanStart, endRegion.RegionKeyword.Span.End))
End If
End If
Return Enumerable.Empty(Of TextSpan)()
End Function
End Sub
End Class
End Namespace
......@@ -15,18 +15,16 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
If node.IsIncorrectExitStatement(SyntaxKind.ExitSelectStatement) Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim selectBlock = node.GetAncestor(Of SelectBlockSyntax)()
If selectBlock Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)
With selectBlock
With .SelectStatement
highlights.Add(
......@@ -52,9 +50,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.EndSelectStatement.Span)
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,9 +15,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(ifStatement As SingleLineIfStatementSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Dim highlights As New List(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(ifStatement As SingleLineIfStatementSyntax, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
highlights.Add(ifStatement.IfKeyword.Span)
highlights.Add(ifStatement.ThenKeyword.Span)
......@@ -25,8 +23,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
If ifStatement.ElseClause IsNot Nothing Then
highlights.Add(ifStatement.ElseClause.ElseKeyword.Span)
End If
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,16 +15,16 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim syncLockBlock = node.GetAncestor(Of SyncLockBlockSyntax)()
If syncLockBlock Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
With syncLockBlock
Return { .SyncLockStatement.SyncLockKeyword.Span,
.EndSyncLockStatement.Span}
highlights.Add(.SyncLockStatement.SyncLockKeyword.Span)
highlights.Add(.EndSyncLockStatement.Span)
End With
End Function
End Sub
End Class
End Namespace
......@@ -15,18 +15,16 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
If TypeOf node Is ExitStatementSyntax AndAlso node.Kind <> SyntaxKind.ExitTryStatement Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim tryBlock = node.GetAncestor(Of TryBlockSyntax)()
If tryBlock Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)
With tryBlock
highlights.Add(.TryStatement.TryKeyword.Span)
......@@ -48,10 +46,8 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
End If
highlights.Add(.EndTryStatement.Span)
Return highlights
End With
End Function
End Sub
Private Sub HighlightRelatedStatements(node As SyntaxNode, highlights As List(Of TextSpan))
If node.Kind = SyntaxKind.ExitTryStatement Then
......
......@@ -15,24 +15,22 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim endBlockStatement = TryCast(node, EndBlockStatementSyntax)
If endBlockStatement IsNot Nothing Then
If Not endBlockStatement.IsKind(SyntaxKind.EndClassStatement,
SyntaxKind.EndInterfaceStatement,
SyntaxKind.EndModuleStatement,
SyntaxKind.EndStructureStatement) Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
End If
Dim typeBlock = node.GetAncestor(Of TypeBlockSyntax)()
If typeBlock Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)
With typeBlock
With .BlockStatement
Dim firstKeyword = If(.Modifiers.Count > 0, .Modifiers.First(), .DeclarationKeyword)
......@@ -41,8 +39,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.EndBlockStatement.Span)
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,16 +15,16 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim usingBlock = node.GetAncestor(Of UsingBlockSyntax)()
If usingBlock Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
With usingBlock
Return { .UsingStatement.UsingKeyword.Span,
.EndUsingStatement.Span}
highlights.Add(.UsingStatement.UsingKeyword.Span)
highlights.Add(.EndUsingStatement.Span)
End With
End Function
End Sub
End Class
End Namespace
......@@ -15,22 +15,20 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
If node.IsIncorrectContinueStatement(SyntaxKind.ContinueWhileStatement) Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
If node.IsIncorrectExitStatement(SyntaxKind.ExitWhileStatement) Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim whileBlock = node.GetAncestor(Of WhileBlockSyntax)()
If whileBlock Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
Dim highlights As New List(Of TextSpan)
With whileBlock
highlights.Add(.WhileStatement.WhileKeyword.Span)
......@@ -40,9 +38,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.EndWhileStatement.Span)
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,16 +15,16 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As SyntaxNode, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim withBlock = node.GetAncestor(Of WithBlockSyntax)()
If withBlock Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of TextSpan)()
Return
End If
With withBlock
Return { .WithStatement.WithKeyword.Span,
.EndWithStatement.Span}
highlights.Add(.WithStatement.WithKeyword.Span)
highlights.Add(.EndWithStatement.Span)
End With
End Function
End Sub
End Class
End Namespace
......@@ -15,9 +15,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(xmlComment As XmlCDataSectionSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Dim highlights As New List(Of TextSpan)
Protected Overloads Overrides Sub addHighlights(xmlComment As XmlCDataSectionSyntax, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
With xmlComment
If Not .ContainsDiagnostics AndAlso
Not .HasAncestor(Of DocumentationCommentTriviaSyntax)() Then
......@@ -25,8 +23,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.EndCDataToken.Span)
End If
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,9 +15,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(xmlComment As XmlCommentSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Dim highlights As New List(Of TextSpan)
Protected Overloads Overrides Sub addHighlights(xmlComment As XmlCommentSyntax, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
With xmlComment
If Not .ContainsDiagnostics AndAlso
Not .HasAncestor(Of DocumentationCommentTriviaSyntax)() Then
......@@ -25,8 +23,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.MinusMinusGreaterThanToken.Span)
End If
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,9 +15,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(xmlProcessingInstruction As XmlProcessingInstructionSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Dim highlights As New List(Of TextSpan)
Protected Overloads Overrides Sub addHighlights(xmlProcessingInstruction As XmlProcessingInstructionSyntax, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
With xmlProcessingInstruction
If Not .ContainsDiagnostics AndAlso
Not .HasAncestor(Of DocumentationCommentTriviaSyntax)() Then
......@@ -25,8 +23,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.QuestionGreaterThanToken.Span)
End If
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,9 +15,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(node As XmlNodeSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Dim highlights As New List(Of TextSpan)
Protected Overloads Overrides Sub AddHighlights(node As XmlNodeSyntax, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
Dim xmlElement = node.GetAncestor(Of XmlElementSyntax)()
With xmlElement
If xmlElement IsNot Nothing AndAlso
......@@ -36,8 +34,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
End If
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,9 +15,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(xmlEmbeddExpression As XmlEmbeddedExpressionSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Dim highlights As New List(Of TextSpan)
Protected Overloads Overrides Sub addHighlights(xmlEmbeddExpression As XmlEmbeddedExpressionSyntax, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
With xmlEmbeddExpression
If Not .ContainsDiagnostics AndAlso
Not .HasAncestor(Of DocumentationCommentTriviaSyntax)() Then
......@@ -25,8 +23,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.PercentGreaterThanToken.Span)
End If
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -15,9 +15,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
Public Sub New()
End Sub
Protected Overloads Overrides Function GetHighlights(xmlDocumentPrologue As XmlDeclarationSyntax, cancellationToken As CancellationToken) As IEnumerable(Of TextSpan)
Dim highlights As New List(Of TextSpan)
Protected Overloads Overrides Sub addHighlights(xmlDocumentPrologue As XmlDeclarationSyntax, highlights As List(Of TextSpan), cancellationToken As CancellationToken)
With xmlDocumentPrologue
If Not .ContainsDiagnostics AndAlso
Not .HasAncestor(Of DocumentationCommentTriviaSyntax)() Then
......@@ -25,8 +23,6 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.KeywordHighlighting
highlights.Add(.QuestionGreaterThanToken.Span)
End If
End With
Return highlights
End Function
End Sub
End Class
End Namespace
......@@ -46,6 +46,13 @@ public static PooledObject<List<TItem>> GetPooledObject<TItem>(this ObjectPool<L
return PooledObject<List<TItem>>.Create(pool);
}
public static PooledObject<List<TItem>> GetPooledObject<TItem>(this ObjectPool<List<TItem>> pool, out List<TItem> list)
{
var pooledObject = PooledObject<List<TItem>>.Create(pool);
list = pooledObject.Object;
return pooledObject;
}
public static PooledObject<T> GetPooledObject<T>(this ObjectPool<T> pool) where T : class
{
return new PooledObject<T>(pool, p => p.Allocate(), (p, o) => p.Free(o));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册