Skip to content

Commit 5f00381

Browse files
Update SA1111 to also check the primary constructor argument list in a base list
#3785
1 parent 92e8a2c commit 5f00381

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,52 @@ public async Task TestPrimaryConstructorWithoutParameterAsync(string typeKeyword
4949
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
5050
}
5151

52+
[Theory]
53+
[MemberData(nameof(CommonMemberData.ReferenceTypeKeywordsWhichSupportPrimaryConstructors), MemberType = typeof(CommonMemberData))]
54+
[WorkItem(3785, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3785")]
55+
public async Task TestPrimaryConstructorBaseListWithArgumentsAsync(string typeKeyword)
56+
{
57+
var testCode = $@"
58+
{typeKeyword} Foo(int x)
59+
{{
60+
}}
61+
62+
{typeKeyword} Bar(int x) : Foo(x
63+
{{|#0:)|}}
64+
{{
65+
}}";
66+
67+
var fixedCode = $@"
68+
{typeKeyword} Foo(int x)
69+
{{
70+
}}
71+
72+
{typeKeyword} Bar(int x) : Foo(x)
73+
{{
74+
}}";
75+
76+
var expected = this.GetExpectedResultTestPrimaryConstructorBaseList();
77+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
78+
}
79+
80+
[Theory]
81+
[MemberData(nameof(CommonMemberData.ReferenceTypeKeywordsWhichSupportPrimaryConstructors), MemberType = typeof(CommonMemberData))]
82+
[WorkItem(3785, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3785")]
83+
public async Task TestPrimaryConstructorBaseListWithoutArgumentsAsync(string typeKeyword)
84+
{
85+
var testCode = $@"
86+
{typeKeyword} Foo()
87+
{{
88+
}}
89+
90+
{typeKeyword} Bar(int x) : Foo(
91+
)
92+
{{
93+
}}";
94+
95+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
96+
}
97+
5298
protected virtual DiagnosticResult[] GetExpectedResultTestPrimaryConstructorWithParameter()
5399
{
54100
return new[]
@@ -58,5 +104,15 @@ protected virtual DiagnosticResult[] GetExpectedResultTestPrimaryConstructorWith
58104
Diagnostic().WithLocation(0),
59105
};
60106
}
107+
108+
protected virtual DiagnosticResult[] GetExpectedResultTestPrimaryConstructorBaseList()
109+
{
110+
return new[]
111+
{
112+
// Diagnostic issued twice because of https://github.com/dotnet/roslyn/issues/70488
113+
Diagnostic().WithLocation(0),
114+
Diagnostic().WithLocation(0),
115+
};
116+
}
61117
}
62118
}

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

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

6363
private static readonly Action<SyntaxNodeAnalysisContext> TypeDeclarationAction = HandleTypeDeclaration;
64+
private static readonly Action<SyntaxNodeAnalysisContext> PrimaryConstructorBaseTypeAction = HandlePrimaryConstructorBaseType;
6465
private static readonly Action<SyntaxNodeAnalysisContext> BaseMethodDeclarationAction = HandleBaseMethodDeclaration;
6566
private static readonly Action<SyntaxNodeAnalysisContext> LocalFunctionStatementAction = HandleLocalFunctionStatement;
6667
private static readonly Action<SyntaxNodeAnalysisContext> InvocationExpressionAction = HandleInvocationExpression;
@@ -84,6 +85,7 @@ public override void Initialize(AnalysisContext context)
8485
context.EnableConcurrentExecution();
8586

8687
context.RegisterSyntaxNodeAction(TypeDeclarationAction, SyntaxKinds.TypeDeclaration);
88+
context.RegisterSyntaxNodeAction(PrimaryConstructorBaseTypeAction, SyntaxKindEx.PrimaryConstructorBaseType);
8789
context.RegisterSyntaxNodeAction(BaseMethodDeclarationAction, HandledMethodSyntaxKinds);
8890
context.RegisterSyntaxNodeAction(LocalFunctionStatementAction, SyntaxKindEx.LocalFunctionStatement);
8991
context.RegisterSyntaxNodeAction(InvocationExpressionAction, SyntaxKind.InvocationExpression);
@@ -224,6 +226,12 @@ private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context)
224226
CheckParameterList(context, typeDeclarationSyntax.ParameterList());
225227
}
226228

229+
private static void HandlePrimaryConstructorBaseType(SyntaxNodeAnalysisContext context)
230+
{
231+
var typeDeclarationSyntax = (PrimaryConstructorBaseTypeSyntaxWrapper)context.Node;
232+
CheckArgumentList(context, typeDeclarationSyntax.ArgumentList);
233+
}
234+
227235
private static void CheckParameterList(SyntaxNodeAnalysisContext context, ParameterListSyntax parameterList)
228236
{
229237
if (parameterList == null || parameterList.IsMissing || !parameterList.Parameters.Any())

0 commit comments

Comments
 (0)