Skip to content

Commit 92e8a2c

Browse files
Update SA1111 to also check the parameter list in primary constructors
#3785
1 parent b5992ef commit 92e8a2c

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/ReadabilityRules/SA1111CSharp11UnitTests.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,20 @@
33

44
namespace StyleCop.Analyzers.Test.CSharp11.ReadabilityRules
55
{
6+
using Microsoft.CodeAnalysis.Testing;
67
using StyleCop.Analyzers.Test.CSharp10.ReadabilityRules;
8+
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
9+
StyleCop.Analyzers.ReadabilityRules.SA1111ClosingParenthesisMustBeOnLineOfLastParameter,
10+
StyleCop.Analyzers.SpacingRules.TokenSpacingCodeFixProvider>;
711

812
public partial class SA1111CSharp11UnitTests : SA1111CSharp10UnitTests
913
{
14+
protected override DiagnosticResult[] GetExpectedResultTestPrimaryConstructorWithParameter()
15+
{
16+
return new[]
17+
{
18+
Diagnostic().WithLocation(0),
19+
};
20+
}
1021
}
1122
}

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/ReadabilityRules/SA1111CSharp9UnitTests.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,60 @@
33

44
namespace StyleCop.Analyzers.Test.CSharp9.ReadabilityRules
55
{
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
69
using StyleCop.Analyzers.Test.CSharp8.ReadabilityRules;
10+
using StyleCop.Analyzers.Test.Helpers;
11+
using Xunit;
12+
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
13+
StyleCop.Analyzers.ReadabilityRules.SA1111ClosingParenthesisMustBeOnLineOfLastParameter,
14+
StyleCop.Analyzers.SpacingRules.TokenSpacingCodeFixProvider>;
715

816
public partial class SA1111CSharp9UnitTests : SA1111CSharp8UnitTests
917
{
18+
[Theory]
19+
[MemberData(nameof(CommonMemberData.TypeKeywordsWhichSupportPrimaryConstructors), MemberType = typeof(CommonMemberData))]
20+
[WorkItem(3785, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3785")]
21+
public async Task TestPrimaryConstructorWithParameterAsync(string typeKeyword)
22+
{
23+
var testCode = $@"
24+
{typeKeyword} Foo(int x
25+
{{|#0:)|}}
26+
{{
27+
}}";
28+
29+
var fixedCode = $@"
30+
{typeKeyword} Foo(int x)
31+
{{
32+
}}";
33+
34+
var expected = this.GetExpectedResultTestPrimaryConstructorWithParameter();
35+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
36+
}
37+
38+
[Theory]
39+
[MemberData(nameof(CommonMemberData.TypeKeywordsWhichSupportPrimaryConstructors), MemberType = typeof(CommonMemberData))]
40+
[WorkItem(3785, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3785")]
41+
public async Task TestPrimaryConstructorWithoutParameterAsync(string typeKeyword)
42+
{
43+
var testCode = $@"
44+
{typeKeyword} Foo(
45+
)
46+
{{
47+
}}";
48+
49+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
50+
}
51+
52+
protected virtual DiagnosticResult[] GetExpectedResultTestPrimaryConstructorWithParameter()
53+
{
54+
return new[]
55+
{
56+
// Diagnostic issued twice because of https://github.com/dotnet/roslyn/issues/53136
57+
Diagnostic().WithLocation(0),
58+
Diagnostic().WithLocation(0),
59+
};
60+
}
1061
}
1162
}

StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1111ClosingParenthesisMustBeOnLineOfLastParameter.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ internal class SA1111ClosingParenthesisMustBeOnLineOfLastParameter : DiagnosticA
6060
SyntaxKind.OperatorDeclaration,
6161
SyntaxKind.ConversionOperatorDeclaration);
6262

63+
private static readonly Action<SyntaxNodeAnalysisContext> TypeDeclarationAction = HandleTypeDeclaration;
6364
private static readonly Action<SyntaxNodeAnalysisContext> BaseMethodDeclarationAction = HandleBaseMethodDeclaration;
6465
private static readonly Action<SyntaxNodeAnalysisContext> LocalFunctionStatementAction = HandleLocalFunctionStatement;
6566
private static readonly Action<SyntaxNodeAnalysisContext> InvocationExpressionAction = HandleInvocationExpression;
@@ -82,6 +83,7 @@ public override void Initialize(AnalysisContext context)
8283
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
8384
context.EnableConcurrentExecution();
8485

86+
context.RegisterSyntaxNodeAction(TypeDeclarationAction, SyntaxKinds.TypeDeclaration);
8587
context.RegisterSyntaxNodeAction(BaseMethodDeclarationAction, HandledMethodSyntaxKinds);
8688
context.RegisterSyntaxNodeAction(LocalFunctionStatementAction, SyntaxKindEx.LocalFunctionStatement);
8789
context.RegisterSyntaxNodeAction(InvocationExpressionAction, SyntaxKind.InvocationExpression);
@@ -216,6 +218,12 @@ private static void HandleLocalFunctionStatement(SyntaxNodeAnalysisContext conte
216218
CheckParameterList(context, localFunctionStatementSyntax.ParameterList);
217219
}
218220

221+
private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context)
222+
{
223+
var typeDeclarationSyntax = (TypeDeclarationSyntax)context.Node;
224+
CheckParameterList(context, typeDeclarationSyntax.ParameterList());
225+
}
226+
219227
private static void CheckParameterList(SyntaxNodeAnalysisContext context, ParameterListSyntax parameterList)
220228
{
221229
if (parameterList == null || parameterList.IsMissing || !parameterList.Parameters.Any())

0 commit comments

Comments
 (0)