Skip to content

Commit 68ad4bb

Browse files
committed
Merge pull request #2177 from vweijsters/fix-2176
SA1515 now properly ignores end of line comments when determining consecutive comment lines
2 parents c499451 + 274493b commit 68ad4bb

2 files changed

Lines changed: 48 additions & 4 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/LayoutRules/SA1515UnitTests.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,43 @@ public void TestMethod() { }
210210
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
211211
}
212212

213+
/// <summary>
214+
/// Verifies that a comment between two statements with an end of line comment is handled properly.
215+
/// This is a regression test for #2176
216+
/// </summary>
217+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
218+
[Fact]
219+
public async Task TestCommentBetweenStatementsWithEndOfLineCommentAsync()
220+
{
221+
var testCode = @"
222+
public class TestConstants
223+
{
224+
public const string Constant1 = ""1""; // my end of line comment
225+
// my comment
226+
public const string Constant2 = ""2""; // my second end of line comment
227+
}
228+
";
229+
230+
var fixedTestCode = @"
231+
public class TestConstants
232+
{
233+
public const string Constant1 = ""1""; // my end of line comment
234+
235+
// my comment
236+
public const string Constant2 = ""2""; // my second end of line comment
237+
}
238+
";
239+
240+
DiagnosticResult[] expectedDiagnostic =
241+
{
242+
this.CSharpDiagnostic().WithLocation(5, 3),
243+
};
244+
245+
await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
246+
await this.VerifyCSharpDiagnosticAsync(fixedTestCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
247+
await this.VerifyCSharpFixAsync(testCode, fixedTestCode).ConfigureAwait(false);
248+
}
249+
213250
/// <inheritdoc/>
214251
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
215252
{

StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1515SingleLineCommentMustBePrecededByBlankLine.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,44 +105,50 @@ public override void Initialize(AnalysisContext context)
105105
private static void HandleSyntaxTree(SyntaxTreeAnalysisContext context)
106106
{
107107
var syntaxRoot = context.Tree.GetRoot(context.CancellationToken);
108+
var previousCommentNotOnOwnLine = false;
108109

109110
foreach (var trivia in syntaxRoot.DescendantTrivia().Where(trivia => trivia.IsKind(SyntaxKind.SingleLineCommentTrivia)))
110111
{
111112
if (trivia.FullSpan.Start == 0)
112113
{
113114
// skip the trivia if it is at the start of the file
115+
previousCommentNotOnOwnLine = false;
114116
continue;
115117
}
116118

117119
if (trivia.ToString().StartsWith("////", StringComparison.Ordinal))
118120
{
119121
// ignore commented out code
122+
previousCommentNotOnOwnLine = false;
120123
continue;
121124
}
122125

123126
int triviaIndex;
124-
125-
// PERF: Explicitly cast to IReadOnlyList so we only box once.
126127
var triviaList = TriviaHelper.GetContainingTriviaList(trivia, out triviaIndex);
127128

128129
if (!IsOnOwnLine(triviaList, triviaIndex))
129130
{
130131
// ignore comments after other code elements.
132+
previousCommentNotOnOwnLine = true;
131133
continue;
132134
}
133135

134136
if (IsPrecededByBlankLine(triviaList, triviaIndex))
135137
{
136138
// allow properly formatted blank line comments.
139+
previousCommentNotOnOwnLine = false;
137140
continue;
138141
}
139142

140-
if (IsPrecededBySingleLineCommentOrDocumentation(triviaList, triviaIndex))
143+
if (!previousCommentNotOnOwnLine && IsPrecededBySingleLineCommentOrDocumentation(triviaList, triviaIndex))
141144
{
142145
// allow consecutive single line comments.
146+
previousCommentNotOnOwnLine = false;
143147
continue;
144148
}
145149

150+
previousCommentNotOnOwnLine = false;
151+
146152
if (IsAtStartOfScope(trivia))
147153
{
148154
// allow single line comment at scope start.
@@ -184,7 +190,8 @@ private static bool IsPrecededBySingleLineCommentOrDocumentation<T>(T triviaList
184190
triviaIndex--;
185191
while ((eolCount < 2) && (triviaIndex >= 0))
186192
{
187-
switch (triviaList[triviaIndex].Kind())
193+
var currentTrivia = triviaList[triviaIndex];
194+
switch (currentTrivia.Kind())
188195
{
189196
case SyntaxKind.WhitespaceTrivia:
190197
triviaIndex--;

0 commit comments

Comments
 (0)