Skip to content

Commit

Permalink
Do not report zero length diagnostic (dotnet#1590)
Browse files Browse the repository at this point in the history
  • Loading branch information
josefpihrt authored Dec 4, 2024
1 parent f7ed06f commit 96dfb34
Show file tree
Hide file tree
Showing 37 changed files with 441 additions and 402 deletions.
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

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

## [4.12.9] - 2024-10-25

Expand Down
48 changes: 45 additions & 3 deletions src/Common/CSharp/TriviaBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using System;
using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;
Expand Down Expand Up @@ -49,9 +50,50 @@ private TriviaBlock(

public Location GetLocation()
{
TextSpan span;
if (Kind == TriviaBlockKind.BlankLine)
{
TriviaBlockReader reader = CreateReader();
reader.ReadWhile(trivia => !trivia.IsEndOfLineTrivia());
reader.ReadWhile(trivia => !trivia.IsEndOfLineTrivia());
span = reader.Current.Span;
}
else
{
SyntaxTriviaList triviaList = (!First.IsKind(SyntaxKind.None))
? First.GetTrailingTrivia()
: Second.GetLeadingTrivia();

span = triviaList.LastOrDefault(f => f.IsEndOfLineTrivia()).Span;

if (span.Length == 0)
{
SyntaxTrivia trivia = triviaList.LastOrDefault();

if (trivia.IsKind(SyntaxKind.WhitespaceTrivia))
span = trivia.Span;
}

if (span.Length == 0)
{
if (Second.Span.Length > 0)
{
span = new TextSpan(Second.SpanStart, 1);
}
else if (First.Span.Length > 0)
{
span = new TextSpan(First.Span.End - 1, 1);
}
else
{
span = new TextSpan(Position, 0);
}
}
}

return Location.Create(
(!First.IsKind(SyntaxKind.None)) ? First.SyntaxTree : Second.SyntaxTree,
new TextSpan(Position, 0));
span);
}

public TriviaBlockReader CreateReader()
Expand Down Expand Up @@ -125,7 +167,7 @@ private static TriviaBlock Analyze(SyntaxNodeOrToken first, SyntaxNodeOrToken se

while (true)
{
SyntaxTrivia trivia = reader.ReadLine();
SyntaxTrivia trivia = reader.ReadWhile(trivia => trivia.IsWhitespaceTrivia());

if (trivia.IsDirective)
return default;
Expand Down Expand Up @@ -169,7 +211,7 @@ private static TriviaBlock Analyze(SyntaxNodeOrToken first, SyntaxNodeOrToken se
}
case SyntaxKind.SingleLineCommentTrivia:
{
if (!reader.Read(SyntaxKind.EndOfLineTrivia))
if (!reader.TryRead(SyntaxKind.EndOfLineTrivia))
return default;

if (first.IsKind(SyntaxKind.None))
Expand Down
18 changes: 7 additions & 11 deletions src/Common/CSharp/TriviaBlockReader.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Diagnostics;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
Expand Down Expand Up @@ -32,11 +33,11 @@ internal TriviaBlockReader(SyntaxNodeOrToken first, SyntaxNodeOrToken second)

public readonly SyntaxTrivia Current => _list[_index];

public SyntaxTrivia ReadLine()
public SyntaxTrivia ReadWhile(Func<SyntaxTrivia, bool> predicate)
{
while (MoveNext())
{
if (!Current.IsWhitespaceTrivia())
if (!predicate(Current))
return Current;
}

Expand All @@ -46,17 +47,12 @@ public SyntaxTrivia ReadLine()
public void ReadTo(int position)
{
while (MoveNext()
&& Current.SpanStart != position)
&& Current.SpanStart < position)
{
}
}

public bool ReadWhiteSpaceTrivia()
{
return Read(SyntaxKind.WhitespaceTrivia);
}

public bool Read(SyntaxKind kind)
public bool TryRead(SyntaxKind kind)
{
if (Peek().IsKind(kind))
{
Expand All @@ -67,7 +63,7 @@ public bool Read(SyntaxKind kind)
return false;
}

public void ReadWhiteSpace()
public void ReadWhiteSpaces()
{
while (Peek().IsWhitespaceOrEndOfLineTrivia())
MoveNext();
Expand Down Expand Up @@ -100,7 +96,7 @@ public void ReadBlankLines()
}
}

public readonly SyntaxTrivia Peek(int offset = 0)
private readonly SyntaxTrivia Peek(int offset = 0)
{
offset++;
if (_index + offset < _list.Count)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ void M()
bool f = false;
if (f)
M();[||]
M();
M();[|
|] M();
}
}
", @"
Expand Down Expand Up @@ -56,8 +56,8 @@ void M()
if (f)
M();
else if (f)
M();[||]
M();
M();[|
|] M();
}
}
", @"
Expand Down Expand Up @@ -91,8 +91,8 @@ void M()
if (f)
M();
else
M();[||]
M();
M();[|
|] M();
}
}
", @"
Expand Down Expand Up @@ -127,8 +127,8 @@ void M()
var items = new List<object>();
foreach (object item in items)
M();[||]
M();
M();[|
|] M();
}
}
", @"
Expand Down Expand Up @@ -164,8 +164,8 @@ void M()
var items = new List<object>();
foreach ((int a, int b) in new[] { (0, 0) })
M();[||]
M();
M();[|
|] M();
}
}
", @"
Expand Down Expand Up @@ -201,8 +201,8 @@ void M()
var items = new List<object>();
for (int i = 0; i < items.Count; i++)
M();[||]
M();
M();[|
|] M();
}
}
", @"
Expand Down Expand Up @@ -237,8 +237,8 @@ void M()
bool f = false;
using ((IDisposable)null)
M();[||]
M();
M();[|
|] M();
}
}
", @"
Expand Down Expand Up @@ -270,8 +270,8 @@ void M()
bool f = false;
while (f)
M();[||]
M();
M();[|
|] M();
}
}
", @"
Expand Down Expand Up @@ -301,8 +301,8 @@ void M()
bool f = false;
lock (null)
M();[||]
M();
M();[|
|] M();
}
}
", @"
Expand Down Expand Up @@ -334,8 +334,8 @@ void M()
unsafe
{
fixed (char* p = "")
M();[||]
M();
M();[|
|] M();
}
}
}
Expand Down Expand Up @@ -373,8 +373,8 @@ void M()
{
case null:
if (f)
M();[||]
break;
M();[|
|] break;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public async Task Test_CompilationUnit_Comment_After()
{
await VerifyDiagnosticAndFixAsync(@"
using System;
using System.Linq;[||]
// x
using System.Linq;[|
|]// x
namespace N
{
}
Expand All @@ -43,8 +43,8 @@ public async Task Test_CompilationUnit_DocumentationComment_After()
{
await VerifyDiagnosticAndFixAsync(@"
using System;
using System.Linq;[||]
/// <summary></summary>
using System.Linq;[|
|]/// <summary></summary>
namespace N
{
}
Expand All @@ -64,8 +64,8 @@ public async Task Test_CompilationUnit_AssemblyAttribute_After()
{
await VerifyDiagnosticAndFixAsync(@"
using System;
using System.Linq;[||]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(null, null)]
using System.Linq;[|
|][assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(null, null)]
namespace N
{
Expand All @@ -87,8 +87,8 @@ public async Task Test_CompilationUnit_CommentAndAssemblyAttribute_After()
{
await VerifyDiagnosticAndFixAsync(@"
using System;
using System.Linq; // x[||]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(null, null)]
using System.Linq; // x[|
|][assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(null, null)]
namespace N
{
Expand All @@ -110,8 +110,8 @@ public async Task Test_CompilationUnit_NamespaceDeclaration_After()
{
await VerifyDiagnosticAndFixAsync(@"
using System;
using System.Linq;[||]
namespace N
using System.Linq;[|
|]namespace N
{
}
", @"
Expand All @@ -131,8 +131,8 @@ await VerifyDiagnosticAndFixAsync(@"
namespace N
{
using System;
using System.Linq;[||]
// x
using System.Linq;[|
|] // x
class C
{
}
Expand All @@ -158,8 +158,8 @@ await VerifyDiagnosticAndFixAsync(@"
namespace N
{
using System;
using System.Linq;[||]
/// <summary></summary>
using System.Linq;[|
|] /// <summary></summary>
class C
{
}
Expand All @@ -185,8 +185,8 @@ await VerifyDiagnosticAndFixAsync(@"
namespace N
{
using System;
using System.Linq;[||]
class C
using System.Linq;[|
|] class C
{
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public override CSharpTestOptions Options
[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.AddBlankLineBeforeUsingDirectiveList)]
public async Task Test_Comment_Before()
{
await VerifyDiagnosticAndFixAsync(@"// x[||]
using System;
await VerifyDiagnosticAndFixAsync(@"// x[|
|]using System;
using System.Linq;
namespace N
Expand All @@ -42,8 +42,8 @@ namespace N
public async Task Test_Comments_Before()
{
await VerifyDiagnosticAndFixAsync(@"// x
// x[||]
using System;
// x[|
|]using System;
class C;
", @"// x
Expand All @@ -59,8 +59,8 @@ class C;
public async Task Test_CommentAndExternAlias_Before()
{
await VerifyDiagnosticAndFixAsync(@"
extern alias x;[||]
using System;
extern alias x;[|
|]using System;
using System.Linq;
namespace N
Expand All @@ -82,8 +82,8 @@ namespace N
public async Task Test_Comment_ExternAliasAndComment_Before()
{
await VerifyDiagnosticAndFixAsync(@"
extern alias x; // x[||]
using System;
extern alias x; // x[|
|]using System;
using System.Linq;
namespace N
Expand Down
Loading

0 comments on commit 96dfb34

Please sign in to comment.