Skip to content

Commit a6f0ea7

Browse files
committed
Merge pull request #1653 from vweijsters/fix-1623
2 parents c946ae5 + cfd10f9 commit a6f0ea7

4 files changed

Lines changed: 120 additions & 31 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1114UnitTests.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,35 @@ private void SomeOtherMethod(int someParameter)
10671067
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
10681068
}
10691069

1070+
/// <summary>
1071+
/// Verifies that directive trivia will not result in diagnostics.
1072+
/// This is a regression test for #1623
1073+
/// </summary>
1074+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
1075+
[Fact]
1076+
public async Task TestWithDirectiveTriviaAsync()
1077+
{
1078+
var testCode = @"
1079+
public interface ITestInterface1 { }
1080+
1081+
public interface ITestInterface2 { }
1082+
1083+
public class TestClass
1084+
{
1085+
public void TestMethod(
1086+
#if TESTSYMBOL
1087+
ITestInterface1 instance)
1088+
#else
1089+
ITestInterface2 instance)
1090+
#endif
1091+
{
1092+
}
1093+
}
1094+
";
1095+
1096+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
1097+
}
1098+
10701099
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
10711100
{
10721101
yield return new SA1114ParameterListMustFollowDeclaration();

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1115UnitTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,36 @@ public class Foo
10991099
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
11001100
}
11011101

1102+
/// <summary>
1103+
/// Verifies that directive trivia will not result in diagnostics.
1104+
/// This is a regression test for #1623
1105+
/// </summary>
1106+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
1107+
[Fact]
1108+
public async Task TestWithDirectiveTriviaAsync()
1109+
{
1110+
var testCode = @"
1111+
public interface ITestInterface1 { }
1112+
1113+
public interface ITestInterface2 { }
1114+
1115+
public class TestClass
1116+
{
1117+
public void TestMethod(
1118+
int parameter1,
1119+
#if TESTSYMBOL
1120+
ITestInterface1 instance)
1121+
#else
1122+
ITestInterface2 instance)
1123+
#endif
1124+
{
1125+
}
1126+
}
1127+
";
1128+
1129+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
1130+
}
1131+
11021132
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
11031133
{
11041134
yield return new SA1115ParameterMustFollowComma();

StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1114ParameterListMustFollowDeclaration.cs

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace StyleCop.Analyzers.ReadabilityRules
55
{
66
using System.Collections.Immutable;
7+
using System.Linq;
78
using Microsoft.CodeAnalysis;
89
using Microsoft.CodeAnalysis.CSharp;
910
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -64,9 +65,8 @@ public override void Initialize(AnalysisContext context)
6465

6566
private static void HandleCompilationStart(CompilationStartAnalysisContext context)
6667
{
67-
context.RegisterSyntaxNodeActionHonorExclusions(HandleMethodDeclaration, SyntaxKind.MethodDeclaration);
68+
context.RegisterSyntaxNodeActionHonorExclusions(HandleBaseMethodDeclaration, SyntaxKind.MethodDeclaration, SyntaxKind.ConstructorDeclaration, SyntaxKind.OperatorDeclaration);
6869
context.RegisterSyntaxNodeActionHonorExclusions(HandleMethodInvocation, SyntaxKind.InvocationExpression);
69-
context.RegisterSyntaxNodeActionHonorExclusions(HandleConstructorDeclaration, SyntaxKind.ConstructorDeclaration);
7070
context.RegisterSyntaxNodeActionHonorExclusions(HandleObjectCreation, SyntaxKind.ObjectCreationExpression);
7171
context.RegisterSyntaxNodeActionHonorExclusions(HandleIndexerDeclaration, SyntaxKind.IndexerDeclaration);
7272
context.RegisterSyntaxNodeActionHonorExclusions(HandleArrayCreation, SyntaxKind.ArrayCreationExpression);
@@ -77,13 +77,6 @@ private static void HandleCompilationStart(CompilationStartAnalysisContext conte
7777
context.RegisterSyntaxNodeActionHonorExclusions(HandleAnonymousMethod, SyntaxKind.AnonymousMethodExpression);
7878
context.RegisterSyntaxNodeActionHonorExclusions(HandleLambdaExpression, SyntaxKind.ParenthesizedLambdaExpression);
7979
context.RegisterSyntaxNodeActionHonorExclusions(HandleConversionOperatorDeclaration, SyntaxKind.ConversionOperatorDeclaration);
80-
context.RegisterSyntaxNodeActionHonorExclusions(HandleOperatorDeclaration, SyntaxKind.OperatorDeclaration);
81-
}
82-
83-
private static void HandleOperatorDeclaration(SyntaxNodeAnalysisContext context)
84-
{
85-
var operatorDeclaration = (OperatorDeclarationSyntax)context.Node;
86-
AnalyzeParametersList(context, operatorDeclaration.ParameterList);
8780
}
8881

8982
private static void HandleConversionOperatorDeclaration(SyntaxNodeAnalysisContext context)
@@ -155,21 +148,15 @@ private static void HandleObjectCreation(SyntaxNodeAnalysisContext context)
155148
}
156149
}
157150

158-
private static void HandleConstructorDeclaration(SyntaxNodeAnalysisContext context)
159-
{
160-
var constructorDeclaration = (ConstructorDeclarationSyntax)context.Node;
161-
AnalyzeParametersList(context, constructorDeclaration.ParameterList);
162-
}
163-
164151
private static void HandleMethodInvocation(SyntaxNodeAnalysisContext context)
165152
{
166153
var invocationExpression = (InvocationExpressionSyntax)context.Node;
167154
AnalyzeArgumentList(context, invocationExpression.ArgumentList);
168155
}
169156

170-
private static void HandleMethodDeclaration(SyntaxNodeAnalysisContext context)
157+
private static void HandleBaseMethodDeclaration(SyntaxNodeAnalysisContext context)
171158
{
172-
var methodDeclaration = (MethodDeclarationSyntax)context.Node;
159+
var methodDeclaration = (BaseMethodDeclarationSyntax)context.Node;
173160

174161
AnalyzeParametersList(context, methodDeclaration.ParameterList);
175162
}
@@ -391,24 +378,40 @@ private static void AnalyzeParametersList(SyntaxNodeAnalysisContext context, Par
391378
}
392379

393380
var firstParameter = parameterListSyntax.Parameters[0];
381+
int firstParameterLine;
394382

395-
var firstParameterLineSpan = firstParameter.GetLineSpan();
396-
if (!firstParameterLineSpan.IsValid)
383+
if (firstParameter.HasLeadingTrivia && firstParameter.GetLeadingTrivia().All(trivia => IsValidTrivia(trivia)))
397384
{
398-
return;
385+
firstParameterLine = firstParameter.SyntaxTree.GetLineSpan(firstParameter.FullSpan).StartLinePosition.Line;
399386
}
400-
401-
var openParenLineSpan = parameterListSyntax.OpenParenToken.GetLineSpan();
402-
if (!openParenLineSpan.IsValid)
387+
else
403388
{
404-
return;
389+
firstParameterLine = firstParameter.GetLineSpan().StartLinePosition.Line;
405390
}
406391

407-
if (openParenLineSpan.EndLinePosition.Line != firstParameterLineSpan.StartLinePosition.Line &&
408-
openParenLineSpan.EndLinePosition.Line != (firstParameterLineSpan.StartLinePosition.Line - 1))
392+
var parenLine = parameterListSyntax.OpenParenToken.GetLineSpan().EndLinePosition.Line;
393+
394+
if ((firstParameterLine - parenLine) > 1)
409395
{
410396
context.ReportDiagnostic(Diagnostic.Create(Descriptor, firstParameter.GetLocation()));
411397
}
412398
}
399+
400+
private static bool IsValidTrivia(SyntaxTrivia trivia)
401+
{
402+
switch (trivia.Kind())
403+
{
404+
case SyntaxKind.IfDirectiveTrivia:
405+
case SyntaxKind.ElseDirectiveTrivia:
406+
case SyntaxKind.ElifDirectiveTrivia:
407+
case SyntaxKind.EndIfDirectiveTrivia:
408+
case SyntaxKind.DisabledTextTrivia:
409+
case SyntaxKind.WhitespaceTrivia:
410+
return true;
411+
412+
default:
413+
return false;
414+
}
415+
}
413416
}
414417
}

StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1115ParameterMustFollowComma.cs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace StyleCop.Analyzers.ReadabilityRules
55
{
66
using System.Collections.Immutable;
7+
using System.Linq;
78
using Microsoft.CodeAnalysis;
89
using Microsoft.CodeAnalysis.CSharp;
910
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -269,18 +270,44 @@ private static void AnalyzeParameterList(SyntaxNodeAnalysisContext context, Base
269270
return;
270271
}
271272

272-
var previousLine = parameterListSyntax.Parameters[0].GetLineSpan().EndLinePosition.Line;
273+
var previousParameterLine = parameterListSyntax.Parameters[0].GetLineSpan().EndLinePosition.Line;
273274
for (int i = 1; i < parameterListSyntax.Parameters.Count; i++)
274275
{
275276
var currentParameter = parameterListSyntax.Parameters[i];
276-
var lineSpan = currentParameter.GetLineSpan();
277-
var currentLine = lineSpan.StartLinePosition.Line;
278-
if (currentLine - previousLine > 1)
277+
int currentParameterLine;
278+
279+
if (currentParameter.HasLeadingTrivia && currentParameter.GetLeadingTrivia().All(trivia => IsValidTrivia(trivia)))
280+
{
281+
currentParameterLine = currentParameter.SyntaxTree.GetLineSpan(currentParameter.FullSpan).StartLinePosition.Line;
282+
}
283+
else
284+
{
285+
currentParameterLine = currentParameter.GetLineSpan().StartLinePosition.Line;
286+
}
287+
288+
if (currentParameterLine - previousParameterLine > 1)
279289
{
280290
context.ReportDiagnostic(Diagnostic.Create(Descriptor, currentParameter.GetLocation()));
281291
}
282292

283-
previousLine = lineSpan.EndLinePosition.Line;
293+
previousParameterLine = currentParameterLine;
294+
}
295+
}
296+
297+
private static bool IsValidTrivia(SyntaxTrivia trivia)
298+
{
299+
switch (trivia.Kind())
300+
{
301+
case SyntaxKind.IfDirectiveTrivia:
302+
case SyntaxKind.ElseDirectiveTrivia:
303+
case SyntaxKind.ElifDirectiveTrivia:
304+
case SyntaxKind.EndIfDirectiveTrivia:
305+
case SyntaxKind.DisabledTextTrivia:
306+
case SyntaxKind.WhitespaceTrivia:
307+
return true;
308+
309+
default:
310+
return false;
284311
}
285312
}
286313
}

0 commit comments

Comments
 (0)