Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.NET 8 and C# 12: add repros and UTs for rules starting with R in SonarWay #8093

Merged
merged 16 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ public void ParameterValidationInYieldShouldBeWrapped_CSharp11() =>
builder.AddPaths("ParameterValidationInYieldShouldBeWrapped.CSharp11.cs")
.WithOptions(ParseOptionsHelper.FromCSharp11)
.Verify();
#endif

#if NET8_0_OR_GREATER

[TestMethod]
public void ParameterValidationInYieldShouldBeWrapped_CSharp12() =>
builder.AddPaths("ParameterValidationInYieldShouldBeWrapped.CSharp12.cs")
.WithOptions(ParseOptionsHelper.FromCSharp12)
.Verify();

#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public void ParametersCorrectOrder_CSharp8() =>
public void ParametersCorrectOrder_CSharp11() =>
builderCS.AddPaths("ParametersCorrectOrder.CSharp11.cs").WithOptions(ParseOptionsHelper.FromCSharp11).Verify();

[TestMethod]
public void ParametersCorrectOrder_CSharp12() =>
builderCS.AddPaths("ParametersCorrectOrder.CSharp12.cs").WithOptions(ParseOptionsHelper.FromCSharp12).Verify();

#endif

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ public void PartCreationPolicyShouldBeUsedWithExportAttribute_CSharp9() =>
.WithOptions(ParseOptionsHelper.FromCSharp9)
.Verify();

[TestMethod]
public void PartCreationPolicyShouldBeUsedWithExportAttribute_CSharp12() =>
builderCS.AddPaths("PartCreationPolicyShouldBeUsedWithExportAttribute.CSharp12.cs")
.WithOptions(ParseOptionsHelper.FromCSharp12)
.Verify();

#endif

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,33 +31,37 @@ public class PropertiesAccessCorrectFieldTest

[TestMethod]
public void PropertiesAccessCorrectField_CS() =>
builderCS.AddPaths(@"PropertiesAccessCorrectField.cs").AddReferences(AdditionalReferences).Verify();
builderCS.AddPaths("PropertiesAccessCorrectField.cs").AddReferences(AdditionalReferences).Verify();

[TestMethod]
public void PropertiesAccessCorrectField_CSharp8() =>
builderCS.AddPaths(@"PropertiesAccessCorrectField.CSharp8.cs").WithOptions(ParseOptionsHelper.FromCSharp8).Verify();
builderCS.AddPaths("PropertiesAccessCorrectField.CSharp8.cs").WithOptions(ParseOptionsHelper.FromCSharp8).Verify();

#if NET

[TestMethod]
public void PropertiesAccessCorrectField_CSharp9() =>
builderCS.AddPaths(@"PropertiesAccessCorrectField.CSharp9.cs").WithOptions(ParseOptionsHelper.FromCSharp9).Verify();
builderCS.AddPaths("PropertiesAccessCorrectField.CSharp9.cs").WithOptions(ParseOptionsHelper.FromCSharp9).Verify();

[TestMethod]
public void PropertiesAccessCorrectField_CSharp12() =>
builderCS.AddPaths("PropertiesAccessCorrectField.CSharp12.cs").WithOptions(ParseOptionsHelper.FromCSharp12).Verify();

#else

[TestMethod]
public void PropertiesAccessCorrectField_CS_NetFramework() =>
builderCS.AddPaths(@"PropertiesAccessCorrectField.NetFramework.cs").AddReferences(AdditionalReferences).Verify();
builderCS.AddPaths("PropertiesAccessCorrectField.NetFramework.cs").AddReferences(AdditionalReferences).Verify();

[TestMethod]
public void PropertiesAccessCorrectField_VB_NetFramework() =>
builderVB.AddPaths(@"PropertiesAccessCorrectField.NetFramework.vb").AddReferences(AdditionalReferences).Verify();
builderVB.AddPaths("PropertiesAccessCorrectField.NetFramework.vb").AddReferences(AdditionalReferences).Verify();

#endif

[TestMethod]
public void PropertiesAccessCorrectField_VB() =>
builderVB.AddPaths(@"PropertiesAccessCorrectField.vb").AddReferences(AdditionalReferences).Verify();
builderVB.AddPaths("PropertiesAccessCorrectField.vb").AddReferences(AdditionalReferences).Verify();

private static IEnumerable<MetadataReference> AdditionalReferences =>
NuGetMetadataReference.MvvmLightLibs("5.4.1.1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ public void PublicMethodWithMultidimensionalArray_CSharp11() =>
.WithOptions(ParseOptionsHelper.FromCSharp11)
.Verify();

[TestMethod]
public void PublicMethodWithMultidimensionalArray_CSharp12() =>
builderCS.AddPaths("PublicMethodWithMultidimensionalArray.CSharp12.cs")
.WithOptions(ParseOptionsHelper.FromCSharp12)
.Verify();

#endif

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ public void RedundancyInConstructorDestructorDeclaration_CSharp10() =>
.WithOptions(ParseOptionsHelper.FromCSharp10)
.Verify();

[TestMethod]
public void RedundancyInConstructorDestructorDeclaration_CSharp12() =>
builder.AddPaths("RedundancyInConstructorDestructorDeclaration.CSharp12.cs")
.WithOptions(ParseOptionsHelper.FromCSharp12)
.Verify();

[TestMethod]
public void RedundancyInConstructorDestructorDeclaration_CodeFix_CSharp9() =>
codeFixBuilderRemoveBaseCall.AddPaths("RedundancyInConstructorDestructorDeclaration.CSharp9.cs")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ public void RedundantArgument_CSharp9() =>
.WithTopLevelStatements()
.Verify();

[TestMethod]
public void RedundantArgument_CSharp12() =>
builder.AddPaths("RedundantArgument.CSharp12.cs")
.WithOptions(ParseOptionsHelper.FromCSharp12)
.Verify();

#endif

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,30 @@ public void RedundantDeclaration_CSharp10_CodeFix_ExplicitDelegate() =>
.WithOptions(ParseOptionsHelper.FromCSharp10)
.VerifyCodeFix();

[TestMethod]
public void RedundantDeclaration_CSharp12() =>
builder.AddPaths("RedundantDeclaration.CSharp12.cs")
.WithOptions(ParseOptionsHelper.FromCSharp12)
.Verify();

[TestMethod]
public void RedundantDeclaration_CSharp12_CodeFix_ArraySize() =>
codeFixBuilder.AddPaths("RedundantDeclaration.CSharp12.cs")
.WithCodeFix<RedundantDeclarationCodeFix>()
.WithCodeFixTitle(RedundantDeclarationCodeFix.TitleRedundantArraySize)
.WithCodeFixedPaths("RedundantDeclaration.CSharp12.ArraySize.Fixed.cs")
.WithOptions(ParseOptionsHelper.FromCSharp12)
.VerifyCodeFix();

[TestMethod]
public void RedundantDeclaration_CSharp12_CodeFix_LambdaParameterType() =>
codeFixBuilder.AddPaths("RedundantDeclaration.CSharp12.cs")
.WithCodeFix<RedundantDeclarationCodeFix>()
.WithCodeFixTitle(RedundantDeclarationCodeFix.TitleRedundantLambdaParameterType)
.WithCodeFixedPaths("RedundantDeclaration.CSharp12.LambdaParameterType.Fixed.cs")
.WithOptions(ParseOptionsHelper.FromCSharp12)
.VerifyCodeFix();

#endif

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections;
using System.Collections.Generic;

class InlineArrays
{
IEnumerable<int> Invalid(Buffer? buffer) // Noncompliant
{
if (buffer == null)
throw new ArgumentNullException(nameof(buffer)); // Secondary

foreach (var item in new Buffer())
yield return item;
}

IEnumerable<int> Valid(Buffer? buffer) // Compliant
{
if (buffer == null)
throw new ArgumentNullException(nameof(buffer));
return Generator(buffer.Value);

IEnumerable<int> Generator(Buffer buffer)
{
foreach (var item in buffer)
yield return item;
}
}

[System.Runtime.CompilerServices.InlineArray(10)]
struct Buffer
{
int arrayItem;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,39 @@ public static IEnumerable<int> WithFunc(string foo)
}
}
}

class NullCoalescing
{
IEnumerable<int> Invalid(int? i) // FN
{
_ = i ?? throw new ArgumentNullException(nameof(i));

yield return 1;
}

IEnumerable<int> ValidWithSecondMethod(int? i) // Compliant
{
_ = i ?? throw new ArgumentNullException(nameof(i));
return SecondMethod();
}

IEnumerable<int> SecondMethod() { yield return 1; }

IEnumerable<int> ValidWithLocalFunction(int? i) // Compliant
{
_ = i ?? throw new ArgumentNullException(nameof(i));
return LocalFunction();

IEnumerable<int> LocalFunction() { yield return 1; }
}
}

class NullCoalescingAssignment
{
IEnumerable<int> NullableInlineArray(int? i) // FN
{
_ = i ?? throw new ArgumentNullException(nameof(i));

yield return 1;
}
cristian-ambrosini-sonarsource marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,43 @@ public SomeClass()
}
}
}

namespace Repro_8072
{
public class Lambdas
cristian-ambrosini-sonarsource marked this conversation as resolved.
Show resolved Hide resolved
{
Func<int, int, int> F1 = (int a, int b) => a + b;

void InvokedFromAnotherLambda()
{
var f1 = (int a, int b) => a + b;
var paramsFullyInverted = (int a, int b) => f1(b, a); // FN
var paramsFullyInvertedWithAdditionalParamAfter = (int a, int b, string s) => f1(b, a); // FN
var paramsFullyInvertedWithAdditionalParamBefore = (string s, int a, int b) => f1(b, a); // FN

var f2 = (int a, int b, int c) => a + b + c;
var paramsPartiallyInvertedFirstAndSecond = (int a, int b, int c) => f2(b, a, c); // FN
var paramsPartiallyInvertedFirstAndLast = (int a, int b, int c) => f2(c, b, a); // FN
var paramsPartiallyInvertedSecondAndLast = (int a, int b, int c) => f2(a, c, b); // FN
}

void InvokedFromLocalFunction()
{
var f1 = (int a, int b) => a + b;
var f2 = (int a, int b, int c) => a + b + c;

int FullyInverted(int a, int b) => f1(b, a);
int FullyInvertedWithAdditionalParamAfter(int a, int b, string c) => f1(b, a);
int FullyInvertedWithAdditionalParamBefore(string c, int a, int b) => f1(b, a);
cristian-ambrosini-sonarsource marked this conversation as resolved.
Show resolved Hide resolved

int PartiallyInvertedFirstAndSecond(int a, int b, int c) => f2(b, a, c); // FN
int PartiallyInvertedFirstAndLast(int a, int b, int c) => f2(c, b, a); // FN
int PartiallyInvertedSecondAndLast(int a, int b, int c) => f2(a, c, b); // FN
}

void InvokedFromAMethod(int a, int b)
{
F1(b, a); // FN
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using System;

namespace Tests.Diagnostics
{
public interface IInterface
{
static virtual void SomeMethod(int a, int b) { } // Secondary
cristian-ambrosini-sonarsource marked this conversation as resolved.
Show resolved Hide resolved
}

public class SomeClass<T> where T : IInterface
{
public SomeClass()
{
int a = 1;
int b = 2;

T.SomeMethod(b, a); // Noncompliant
}
}
}

// https://github.com/SonarSource/sonar-dotnet/issues/8071
namespace Repro_8071
{
class BaseConstructor
{
class Base(int a, int b)
{
Base(int a, int b, string c) : this(b, a) { } // FN: ctor params inverted with additional param after
Base(string c, int a, int b) : this(b, a) { } // FN: ctor params inverted with additional param before
}

class ParamsFullyInverted(int a, int b) : Base(b, a); // FN
class ParamsPartiallyInverted(int a, int b, int c) : Base(b, a); // FN
class ParamsFullyInvertedWithAdditionalParamAfter(int a, int b, string s) : Base(b, a); // FN
class ParamsFullyInvertedWithAdditionalParamBefore(string s, int a, int b) : Base(b, a); // FN
}

class WithRecordStructs
{
void Basics(int a, int b, int c)
{
_ = new SomeRecord(b, a); // Noncompliant
}

void WithPromotion(short a, short b)
{
_ = new SomeRecord(b, a); // Noncompliant
}

void WithCasting(long a, long b)
{
_ = new SomeRecord((int)b, (int)a); // FN
}

record SomeRecord(int a, int b)
{
public SomeRecord(int a, int b, string c) : this(b, a) { } // FN
public SomeRecord(string c, int a, int b) : this(b, a) { } // FN
}
}

class WithRecords
{
void Basics(int a, int b, int c)
{
_ = new SomeRecordStruct(b, a); // Noncompliant
}

void WithPromotion(short a, short b)
{
_ = new SomeRecordStruct(b, a); // Noncompliant
}

void WithCasting(long a, long b)
{
_ = new SomeRecordStruct((int)b, (int)a); // FN
}

record struct SomeRecordStruct(int a, int b)
{
public SomeRecordStruct(int a, int b, string c) : this(b, a) { } // FN
public SomeRecordStruct(string c, int a, int b) : this(b, a) { } // FN
}
}
}

namespace Repro_8072
cristian-ambrosini-sonarsource marked this conversation as resolved.
Show resolved Hide resolved
{
public class DefaultLambdaParameters
{
void InvokedFromAnotherLambda()
{
var f1 = (int a, int b) => a + b;
var paramsFullyInverted = (int a, int b) => f1(b, a); // FN
var paramsFullyInvertedWithAdditionalParamAfter = (int a, int b, string s) => f1(b, a); // FN
var paramsFullyInvertedWithAdditionalParamBefore = (string s, int a, int b) => f1(b, a); // FN

var f2 = (int a, int b, int c) => a + b + c;
var paramsPartiallyInvertedFirstAndSecond = (int a, int b, int c) => f2(b, a, c); // FN
var paramsPartiallyInvertedFirstAndLast = (int a, int b, int c) => f2(c, b, a); // FN
var paramsPartiallyInvertedSecondAndLast = (int a, int b, int c) => f2(a, c, b); // FN
}

void InvokedFromLocalFunction()
{
var f = (int a, int b) => a + b;

int SomeLocalFunction(int a, int b) => f(b, a);
}
}
}
Loading