Skip to content

Commit 2926117

Browse files
committed
Merge pull request #1491 from pdelvo/firstInLinePerf
2 parents bceaf44 + ee0bdfc commit 2926117

3 files changed

Lines changed: 72 additions & 3 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
2+
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
3+
4+
namespace StyleCop.Analyzers.Test.HelperTests
5+
{
6+
using System.Linq;
7+
using Analyzers.Helpers;
8+
using Microsoft.CodeAnalysis;
9+
using Microsoft.CodeAnalysis.CSharp;
10+
using Xunit;
11+
12+
public class TokenHelperTests
13+
{
14+
[Fact]
15+
public void TestIsFirstInLineSpecialCase()
16+
{
17+
string testCode = @"class MyClass {
18+
} /// <summary>
19+
/// Text
20+
/// </summary>
21+
struct MyStruct { }";
22+
var syntaxTree = CSharpSyntaxTree.ParseText(testCode);
23+
var root = syntaxTree.GetRoot();
24+
25+
Assert.True(root.DescendantTokens().Single(i => i.IsKind(SyntaxKind.StructKeyword)).IsFirstInLine());
26+
}
27+
28+
[Fact]
29+
public void TestIsLastInLineSpecialCase()
30+
{
31+
string testCode = @"class MyClass {
32+
} /// <summary>
33+
/// Text
34+
/// </summary>
35+
struct /**
36+
Foo
37+
**/ MyStruct { }";
38+
var syntaxTree = CSharpSyntaxTree.ParseText(testCode);
39+
var root = syntaxTree.GetRoot();
40+
41+
Assert.True(root.DescendantTokens().Single(i => i.IsKind(SyntaxKind.StructKeyword)).IsLastInLine());
42+
}
43+
}
44+
}

StyleCop.Analyzers/StyleCop.Analyzers.Test/StyleCop.Analyzers.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@
169169
<Compile Include="Helpers\DiagnosticVerifier.Helper.cs" />
170170
<Compile Include="Helpers\ExclusionTestAnalyzer.cs" />
171171
<Compile Include="Helpers\TestDiagnosticProvider.cs" />
172+
<Compile Include="HelperTests\TokenHelperTests.cs" />
172173
<Compile Include="HelperTests\TriviaHelperTests.cs" />
173174
<Compile Include="LayoutRules\SA1500\SA1500UnitTests.Blocks.cs" />
174175
<Compile Include="LayoutRules\SA1500\SA1500UnitTests.Classes.cs" />

StyleCop.Analyzers/StyleCop.Analyzers/Helpers/TokenHelpers.cs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,15 @@ internal static class TokenHelper
1818
/// <returns>true if token is first in line, otherwise false.</returns>
1919
internal static bool IsFirstInLine(this SyntaxToken token)
2020
{
21-
SyntaxToken previousToken = token.GetPreviousToken();
22-
return previousToken.IsKind(SyntaxKind.None) || previousToken.GetEndLine() < token.GetLine();
21+
var fullLineSpan = token.SyntaxTree.GetLineSpan(token.FullSpan);
22+
23+
if (token.SyntaxTree == null || fullLineSpan.StartLinePosition.Character == 0)
24+
{
25+
return true;
26+
}
27+
28+
var tokenLineSpan = token.SyntaxTree.GetLineSpan(token.Span);
29+
return tokenLineSpan.StartLinePosition.Line != fullLineSpan.StartLinePosition.Line;
2330
}
2431

2532
/// <summary>
@@ -29,7 +36,24 @@ internal static bool IsFirstInLine(this SyntaxToken token)
2936
/// <returns>true if token is last in line, otherwise false.</returns>
3037
internal static bool IsLastInLine(this SyntaxToken token)
3138
{
32-
SyntaxToken nextToken = token.GetNextToken();
39+
var fullLineSpan = token.SyntaxTree.GetLineSpan(token.FullSpan);
40+
41+
if (token.SyntaxTree == null || fullLineSpan.EndLinePosition.Character == 0)
42+
{
43+
return true;
44+
}
45+
46+
var tokenLineSpan = token.SyntaxTree.GetLineSpan(token.Span);
47+
48+
if (tokenLineSpan.EndLinePosition.Line != fullLineSpan.EndLinePosition.Line
49+
|| token.SyntaxTree.Length == token.FullSpan.End)
50+
{
51+
return true;
52+
}
53+
54+
// Use the slow path because we cant be sure if a multi line trivia is following this
55+
// token.
56+
var nextToken = token.GetNextToken();
3357
return nextToken.IsKind(SyntaxKind.None) || token.GetEndLine() < nextToken.GetLine();
3458
}
3559

0 commit comments

Comments
 (0)