Skip to content

Commit 96dfb34

Browse files
authored
Do not report zero length diagnostic (#1590)
1 parent f7ed06f commit 96dfb34

File tree

37 files changed

+441
-402
lines changed

37 files changed

+441
-402
lines changed

ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
### Changed
1717

1818
- Update whitespace formatting rules ([PR](https://github.com/dotnet/roslynator/pull/1576))
19+
- Ensure that diagnostics are not reported with zero length ([PR](https://github.com/dotnet/roslynator/pull/1590))
1920

2021
## [4.12.9] - 2024-10-25
2122

src/Common/CSharp/TriviaBlock.cs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
using System;
44
using System.Diagnostics;
5+
using System.Linq;
56
using Microsoft.CodeAnalysis;
67
using Microsoft.CodeAnalysis.CSharp;
78
using Microsoft.CodeAnalysis.Text;
@@ -49,9 +50,50 @@ private TriviaBlock(
4950

5051
public Location GetLocation()
5152
{
53+
TextSpan span;
54+
if (Kind == TriviaBlockKind.BlankLine)
55+
{
56+
TriviaBlockReader reader = CreateReader();
57+
reader.ReadWhile(trivia => !trivia.IsEndOfLineTrivia());
58+
reader.ReadWhile(trivia => !trivia.IsEndOfLineTrivia());
59+
span = reader.Current.Span;
60+
}
61+
else
62+
{
63+
SyntaxTriviaList triviaList = (!First.IsKind(SyntaxKind.None))
64+
? First.GetTrailingTrivia()
65+
: Second.GetLeadingTrivia();
66+
67+
span = triviaList.LastOrDefault(f => f.IsEndOfLineTrivia()).Span;
68+
69+
if (span.Length == 0)
70+
{
71+
SyntaxTrivia trivia = triviaList.LastOrDefault();
72+
73+
if (trivia.IsKind(SyntaxKind.WhitespaceTrivia))
74+
span = trivia.Span;
75+
}
76+
77+
if (span.Length == 0)
78+
{
79+
if (Second.Span.Length > 0)
80+
{
81+
span = new TextSpan(Second.SpanStart, 1);
82+
}
83+
else if (First.Span.Length > 0)
84+
{
85+
span = new TextSpan(First.Span.End - 1, 1);
86+
}
87+
else
88+
{
89+
span = new TextSpan(Position, 0);
90+
}
91+
}
92+
}
93+
5294
return Location.Create(
5395
(!First.IsKind(SyntaxKind.None)) ? First.SyntaxTree : Second.SyntaxTree,
54-
new TextSpan(Position, 0));
96+
span);
5597
}
5698

5799
public TriviaBlockReader CreateReader()
@@ -125,7 +167,7 @@ private static TriviaBlock Analyze(SyntaxNodeOrToken first, SyntaxNodeOrToken se
125167

126168
while (true)
127169
{
128-
SyntaxTrivia trivia = reader.ReadLine();
170+
SyntaxTrivia trivia = reader.ReadWhile(trivia => trivia.IsWhitespaceTrivia());
129171

130172
if (trivia.IsDirective)
131173
return default;
@@ -169,7 +211,7 @@ private static TriviaBlock Analyze(SyntaxNodeOrToken first, SyntaxNodeOrToken se
169211
}
170212
case SyntaxKind.SingleLineCommentTrivia:
171213
{
172-
if (!reader.Read(SyntaxKind.EndOfLineTrivia))
214+
if (!reader.TryRead(SyntaxKind.EndOfLineTrivia))
173215
return default;
174216

175217
if (first.IsKind(SyntaxKind.None))

src/Common/CSharp/TriviaBlockReader.cs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
22

3+
using System;
34
using System.Diagnostics;
45
using Microsoft.CodeAnalysis;
56
using Microsoft.CodeAnalysis.CSharp;
@@ -32,11 +33,11 @@ internal TriviaBlockReader(SyntaxNodeOrToken first, SyntaxNodeOrToken second)
3233

3334
public readonly SyntaxTrivia Current => _list[_index];
3435

35-
public SyntaxTrivia ReadLine()
36+
public SyntaxTrivia ReadWhile(Func<SyntaxTrivia, bool> predicate)
3637
{
3738
while (MoveNext())
3839
{
39-
if (!Current.IsWhitespaceTrivia())
40+
if (!predicate(Current))
4041
return Current;
4142
}
4243

@@ -46,17 +47,12 @@ public SyntaxTrivia ReadLine()
4647
public void ReadTo(int position)
4748
{
4849
while (MoveNext()
49-
&& Current.SpanStart != position)
50+
&& Current.SpanStart < position)
5051
{
5152
}
5253
}
5354

54-
public bool ReadWhiteSpaceTrivia()
55-
{
56-
return Read(SyntaxKind.WhitespaceTrivia);
57-
}
58-
59-
public bool Read(SyntaxKind kind)
55+
public bool TryRead(SyntaxKind kind)
6056
{
6157
if (Peek().IsKind(kind))
6258
{
@@ -67,7 +63,7 @@ public bool Read(SyntaxKind kind)
6763
return false;
6864
}
6965

70-
public void ReadWhiteSpace()
66+
public void ReadWhiteSpaces()
7167
{
7268
while (Peek().IsWhitespaceOrEndOfLineTrivia())
7369
MoveNext();
@@ -100,7 +96,7 @@ public void ReadBlankLines()
10096
}
10197
}
10298

103-
public readonly SyntaxTrivia Peek(int offset = 0)
99+
private readonly SyntaxTrivia Peek(int offset = 0)
104100
{
105101
offset++;
106102
if (_index + offset < _list.Count)

src/Tests/Formatting.Analyzers.Tests/RCS0001AddBlankLineAfterEmbeddedStatementTests.cs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ void M()
2323
bool f = false;
2424
2525
if (f)
26-
M();[||]
27-
M();
26+
M();[|
27+
|] M();
2828
}
2929
}
3030
", @"
@@ -56,8 +56,8 @@ void M()
5656
if (f)
5757
M();
5858
else if (f)
59-
M();[||]
60-
M();
59+
M();[|
60+
|] M();
6161
}
6262
}
6363
", @"
@@ -91,8 +91,8 @@ void M()
9191
if (f)
9292
M();
9393
else
94-
M();[||]
95-
M();
94+
M();[|
95+
|] M();
9696
}
9797
}
9898
", @"
@@ -127,8 +127,8 @@ void M()
127127
var items = new List<object>();
128128
129129
foreach (object item in items)
130-
M();[||]
131-
M();
130+
M();[|
131+
|] M();
132132
}
133133
}
134134
", @"
@@ -164,8 +164,8 @@ void M()
164164
var items = new List<object>();
165165
166166
foreach ((int a, int b) in new[] { (0, 0) })
167-
M();[||]
168-
M();
167+
M();[|
168+
|] M();
169169
}
170170
}
171171
", @"
@@ -201,8 +201,8 @@ void M()
201201
var items = new List<object>();
202202
203203
for (int i = 0; i < items.Count; i++)
204-
M();[||]
205-
M();
204+
M();[|
205+
|] M();
206206
}
207207
}
208208
", @"
@@ -237,8 +237,8 @@ void M()
237237
bool f = false;
238238
239239
using ((IDisposable)null)
240-
M();[||]
241-
M();
240+
M();[|
241+
|] M();
242242
}
243243
}
244244
", @"
@@ -270,8 +270,8 @@ void M()
270270
bool f = false;
271271
272272
while (f)
273-
M();[||]
274-
M();
273+
M();[|
274+
|] M();
275275
}
276276
}
277277
", @"
@@ -301,8 +301,8 @@ void M()
301301
bool f = false;
302302
303303
lock (null)
304-
M();[||]
305-
M();
304+
M();[|
305+
|] M();
306306
}
307307
}
308308
", @"
@@ -334,8 +334,8 @@ void M()
334334
unsafe
335335
{
336336
fixed (char* p = "")
337-
M();[||]
338-
M();
337+
M();[|
338+
|] M();
339339
}
340340
}
341341
}
@@ -373,8 +373,8 @@ void M()
373373
{
374374
case null:
375375
if (f)
376-
M();[||]
377-
break;
376+
M();[|
377+
|] break;
378378
}
379379
}
380380
}

src/Tests/Formatting.Analyzers.Tests/RCS0003AddBlankLineAfterUsingDirectiveListTests.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ public async Task Test_CompilationUnit_Comment_After()
2222
{
2323
await VerifyDiagnosticAndFixAsync(@"
2424
using System;
25-
using System.Linq;[||]
26-
// x
25+
using System.Linq;[|
26+
|]// x
2727
namespace N
2828
{
2929
}
@@ -43,8 +43,8 @@ public async Task Test_CompilationUnit_DocumentationComment_After()
4343
{
4444
await VerifyDiagnosticAndFixAsync(@"
4545
using System;
46-
using System.Linq;[||]
47-
/// <summary></summary>
46+
using System.Linq;[|
47+
|]/// <summary></summary>
4848
namespace N
4949
{
5050
}
@@ -64,8 +64,8 @@ public async Task Test_CompilationUnit_AssemblyAttribute_After()
6464
{
6565
await VerifyDiagnosticAndFixAsync(@"
6666
using System;
67-
using System.Linq;[||]
68-
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(null, null)]
67+
using System.Linq;[|
68+
|][assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(null, null)]
6969
7070
namespace N
7171
{
@@ -87,8 +87,8 @@ public async Task Test_CompilationUnit_CommentAndAssemblyAttribute_After()
8787
{
8888
await VerifyDiagnosticAndFixAsync(@"
8989
using System;
90-
using System.Linq; // x[||]
91-
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(null, null)]
90+
using System.Linq; // x[|
91+
|][assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(null, null)]
9292
9393
namespace N
9494
{
@@ -110,8 +110,8 @@ public async Task Test_CompilationUnit_NamespaceDeclaration_After()
110110
{
111111
await VerifyDiagnosticAndFixAsync(@"
112112
using System;
113-
using System.Linq;[||]
114-
namespace N
113+
using System.Linq;[|
114+
|]namespace N
115115
{
116116
}
117117
", @"
@@ -131,8 +131,8 @@ await VerifyDiagnosticAndFixAsync(@"
131131
namespace N
132132
{
133133
using System;
134-
using System.Linq;[||]
135-
// x
134+
using System.Linq;[|
135+
|] // x
136136
class C
137137
{
138138
}
@@ -158,8 +158,8 @@ await VerifyDiagnosticAndFixAsync(@"
158158
namespace N
159159
{
160160
using System;
161-
using System.Linq;[||]
162-
/// <summary></summary>
161+
using System.Linq;[|
162+
|] /// <summary></summary>
163163
class C
164164
{
165165
}
@@ -185,8 +185,8 @@ await VerifyDiagnosticAndFixAsync(@"
185185
namespace N
186186
{
187187
using System;
188-
using System.Linq;[||]
189-
class C
188+
using System.Linq;[|
189+
|] class C
190190
{
191191
}
192192
}

src/Tests/Formatting.Analyzers.Tests/RCS0006AddEmptyLineBeforeUsingDirectiveListTests.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ public override CSharpTestOptions Options
2020
[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.AddBlankLineBeforeUsingDirectiveList)]
2121
public async Task Test_Comment_Before()
2222
{
23-
await VerifyDiagnosticAndFixAsync(@"// x[||]
24-
using System;
23+
await VerifyDiagnosticAndFixAsync(@"// x[|
24+
|]using System;
2525
using System.Linq;
2626
2727
namespace N
@@ -42,8 +42,8 @@ namespace N
4242
public async Task Test_Comments_Before()
4343
{
4444
await VerifyDiagnosticAndFixAsync(@"// x
45-
// x[||]
46-
using System;
45+
// x[|
46+
|]using System;
4747
4848
class C;
4949
", @"// x
@@ -59,8 +59,8 @@ class C;
5959
public async Task Test_CommentAndExternAlias_Before()
6060
{
6161
await VerifyDiagnosticAndFixAsync(@"
62-
extern alias x;[||]
63-
using System;
62+
extern alias x;[|
63+
|]using System;
6464
using System.Linq;
6565
6666
namespace N
@@ -82,8 +82,8 @@ namespace N
8282
public async Task Test_Comment_ExternAliasAndComment_Before()
8383
{
8484
await VerifyDiagnosticAndFixAsync(@"
85-
extern alias x; // x[||]
86-
using System;
85+
extern alias x; // x[|
86+
|]using System;
8787
using System.Linq;
8888
8989
namespace N

0 commit comments

Comments
 (0)