Skip to content

Commit

Permalink
Merge pull request #3791 from bjornhellander/feature/sa1111-primary-c…
Browse files Browse the repository at this point in the history
…tor-3785

Update SA1111 to also check the parameter list in primary constructors
  • Loading branch information
sharwell authored Mar 21, 2024
2 parents f66d17d + 5f00381 commit 6327501
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 175 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,20 @@

namespace StyleCop.Analyzers.Test.CSharp11.ReadabilityRules
{
using Microsoft.CodeAnalysis.Testing;
using StyleCop.Analyzers.Test.CSharp10.ReadabilityRules;
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
StyleCop.Analyzers.ReadabilityRules.SA1111ClosingParenthesisMustBeOnLineOfLastParameter,
StyleCop.Analyzers.SpacingRules.TokenSpacingCodeFixProvider>;

public partial class SA1111CSharp11UnitTests : SA1111CSharp10UnitTests
{
protected override DiagnosticResult[] GetExpectedResultTestPrimaryConstructorWithParameter()
{
return new[]
{
Diagnostic().WithLocation(0),
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,116 @@

namespace StyleCop.Analyzers.Test.CSharp9.ReadabilityRules
{
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using StyleCop.Analyzers.Test.CSharp8.ReadabilityRules;
using StyleCop.Analyzers.Test.Helpers;
using Xunit;
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
StyleCop.Analyzers.ReadabilityRules.SA1111ClosingParenthesisMustBeOnLineOfLastParameter,
StyleCop.Analyzers.SpacingRules.TokenSpacingCodeFixProvider>;

public partial class SA1111CSharp9UnitTests : SA1111CSharp8UnitTests
{
[Theory]
[MemberData(nameof(CommonMemberData.TypeKeywordsWhichSupportPrimaryConstructors), MemberType = typeof(CommonMemberData))]
[WorkItem(3785, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3785")]
public async Task TestPrimaryConstructorWithParameterAsync(string typeKeyword)
{
var testCode = $@"
{typeKeyword} Foo(int x
{{|#0:)|}}
{{
}}";

var fixedCode = $@"
{typeKeyword} Foo(int x)
{{
}}";

var expected = this.GetExpectedResultTestPrimaryConstructorWithParameter();
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
}

[Theory]
[MemberData(nameof(CommonMemberData.TypeKeywordsWhichSupportPrimaryConstructors), MemberType = typeof(CommonMemberData))]
[WorkItem(3785, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3785")]
public async Task TestPrimaryConstructorWithoutParameterAsync(string typeKeyword)
{
var testCode = $@"
{typeKeyword} Foo(
)
{{
}}";

await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

[Theory]
[MemberData(nameof(CommonMemberData.ReferenceTypeKeywordsWhichSupportPrimaryConstructors), MemberType = typeof(CommonMemberData))]
[WorkItem(3785, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3785")]
public async Task TestPrimaryConstructorBaseListWithArgumentsAsync(string typeKeyword)
{
var testCode = $@"
{typeKeyword} Foo(int x)
{{
}}
{typeKeyword} Bar(int x) : Foo(x
{{|#0:)|}}
{{
}}";

var fixedCode = $@"
{typeKeyword} Foo(int x)
{{
}}
{typeKeyword} Bar(int x) : Foo(x)
{{
}}";

var expected = this.GetExpectedResultTestPrimaryConstructorBaseList();
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
}

[Theory]
[MemberData(nameof(CommonMemberData.ReferenceTypeKeywordsWhichSupportPrimaryConstructors), MemberType = typeof(CommonMemberData))]
[WorkItem(3785, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3785")]
public async Task TestPrimaryConstructorBaseListWithoutArgumentsAsync(string typeKeyword)
{
var testCode = $@"
{typeKeyword} Foo()
{{
}}
{typeKeyword} Bar(int x) : Foo(
)
{{
}}";

await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

protected virtual DiagnosticResult[] GetExpectedResultTestPrimaryConstructorWithParameter()
{
return new[]
{
// Diagnostic issued twice because of https://github.com/dotnet/roslyn/issues/53136
Diagnostic().WithLocation(0),
Diagnostic().WithLocation(0),
};
}

protected virtual DiagnosticResult[] GetExpectedResultTestPrimaryConstructorBaseList()
{
return new[]
{
// Diagnostic issued twice because of https://github.com/dotnet/roslyn/issues/70488
Diagnostic().WithLocation(0),
Diagnostic().WithLocation(0),
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -536,13 +536,13 @@ public class ClassName
}

private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult expected, CancellationToken cancellationToken)
=> VerifyCSharpDiagnosticAsync(source, testSettings: null, new[] { expected }, false, cancellationToken);
=> VerifyCSharpDiagnosticAsync(source, testSettings: null, new[] { expected }, ignoreCompilerDiagnostics: false, cancellationToken);

private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult[] expected, CancellationToken cancellationToken)
=> VerifyCSharpDiagnosticAsync(source, testSettings: null, expected, false, cancellationToken);
=> VerifyCSharpDiagnosticAsync(source, testSettings: null, expected, ignoreCompilerDiagnostics: false, cancellationToken);

private static Task VerifyCSharpDiagnosticAsync(string source, string testSettings, DiagnosticResult[] expected, CancellationToken cancellationToken)
=> VerifyCSharpDiagnosticAsync(source, testSettings, expected, false, cancellationToken);
=> VerifyCSharpDiagnosticAsync(source, testSettings, expected, ignoreCompilerDiagnostics: false, cancellationToken);

private static Task VerifyCSharpDiagnosticAsync(string source, string testSettings, DiagnosticResult[] expected, bool ignoreCompilerDiagnostics, CancellationToken cancellationToken)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

#nullable disable

namespace StyleCop.Analyzers.Test.Helpers
{
using System.Collections.Generic;
Expand Down Expand Up @@ -115,7 +113,7 @@ public static IEnumerable<object[]> GenericTypeDeclarationKeywords
}
}

public static IEnumerable<object[]> TypeKeywordsWhichSupportPrimaryConstructors
public static IEnumerable<object[]> ReferenceTypeKeywordsWhichSupportPrimaryConstructors
{
get
{
Expand All @@ -127,22 +125,33 @@ public static IEnumerable<object[]> TypeKeywordsWhichSupportPrimaryConstructors
if (LightupHelpers.SupportsCSharp10)
{
yield return new[] { "record class" };
yield return new[] { "record struct" };
}

if (LightupHelpers.SupportsCSharp12)
{
yield return new[] { "class" };
yield return new[] { "struct" };
}
}
}

public static IEnumerable<object[]> ReferenceTypeKeywordsWhichSupportPrimaryConstructors
public static IEnumerable<object[]> TypeKeywordsWhichSupportPrimaryConstructors
{
get
{
return TypeKeywordsWhichSupportPrimaryConstructors.Where(x => !((string)x[0]).Contains("struct"));
foreach (var keyword in ReferenceTypeKeywordsWhichSupportPrimaryConstructors)
{
yield return keyword;
}

if (LightupHelpers.SupportsCSharp10)
{
yield return new[] { "record struct" };
}

if (LightupHelpers.SupportsCSharp12)
{
yield return new[] { "struct" };
}
}
}
}
Expand Down
Loading

0 comments on commit 6327501

Please sign in to comment.