Skip to content

Commit

Permalink
Migrate S2583/S2589: Scaffold the rule for the new SE (#7657)
Browse files Browse the repository at this point in the history
  • Loading branch information
mary-georgiou-sonarsource authored and Tim-Pohlmann committed Aug 8, 2023
1 parent cc54771 commit e4282e7
Show file tree
Hide file tree
Showing 10 changed files with 4,183 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* SonarAnalyzer for .NET
* Copyright (C) 2015-2023 SonarSource SA
* mailto: contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

namespace SonarAnalyzer.SymbolicExecution.Roslyn.RuleChecks.CSharp;

public class ConditionEvaluatesToConstant : ConditionEvaluatesToConstantBase
{
public static readonly DiagnosticDescriptor S2589 = DescriptorFactory.Create(DiagnosticIdCodeSmell, MessageFormat);
public static readonly DiagnosticDescriptor S2583 = DescriptorFactory.Create(DiagnosticIdBug, MessageFormat);
protected override DiagnosticDescriptor Rule => null;
public override bool ShouldExecute() => false;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* SonarAnalyzer for .NET
* Copyright (C) 2015-2023 SonarSource SA
* mailto: contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

namespace SonarAnalyzer.SymbolicExecution.Roslyn.RuleChecks;

public abstract class ConditionEvaluatesToConstantBase : SymbolicRuleCheck
{
protected const string DiagnosticIdCodeSmell = "S2589"; // Code smell
protected const string DiagnosticIdBug = "S2583"; // Bug

protected const string MessageFormat = "{0}";
protected const string MessageFormatBool = "Change this condition so that it does not always evaluate to '{0}'.";
protected const string MessageNull = "Change this expression which always evaluates to 'null'.";
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,62 +21,125 @@
using SonarAnalyzer.Rules.CSharp;
using SonarAnalyzer.SymbolicExecution.Sonar.Analyzers;

using ChecksCS = SonarAnalyzer.SymbolicExecution.Roslyn.RuleChecks.CSharp;
using CS = SonarAnalyzer.Rules.CSharp;

namespace SonarAnalyzer.UnitTest.Rules
{
[TestClass]
public class ConditionEvaluatesToConstantTest
{
private readonly VerifierBuilder sonar = new VerifierBuilder<SymbolicExecutionRunner>().WithBasePath(@"SymbolicExecution\Sonar")
private readonly VerifierBuilder sonar = new VerifierBuilder()
.AddAnalyzer(() => new CS.SymbolicExecutionRunner(AnalyzerConfiguration.AlwaysEnabledWithSonarCfg))
.WithBasePath(@"SymbolicExecution\Sonar")
.WithOnlyDiagnostics(ConditionEvaluatesToConstant.S2583, ConditionEvaluatesToConstant.S2589);

private readonly VerifierBuilder roslynCS = new VerifierBuilder()
.AddAnalyzer(() => new CS.SymbolicExecutionRunner(AnalyzerConfiguration.AlwaysEnabled))
.WithBasePath(@"SymbolicExecution\Roslyn")
.WithOnlyDiagnostics(ChecksCS.ConditionEvaluatesToConstant.S2589);

[DataTestMethod]
[DataRow(ProjectType.Product)]
[DataRow(ProjectType.Test)]
public void ConditionEvaluatesToConstant_CS(ProjectType projectType) =>
public void ConditionEvaluatesToConstant_Sonar_CS(ProjectType projectType) =>
sonar.AddPaths("ConditionEvaluatesToConstant.cs")
.AddReferences(NuGetMetadataReference.MicrosoftExtensionsPrimitives("3.1.7").Concat(TestHelper.ProjectTypeReference(projectType)))
.Verify();

[Ignore] // Fixme: Remove after implementation
[DataTestMethod]
[DataRow(ProjectType.Product)]
[DataRow(ProjectType.Test)]
public void ConditionEvaluatesToConstant_Roslyn_CS(ProjectType projectType) =>
roslynCS.AddPaths("ConditionEvaluatesToConstant.cs")
.AddReferences(NuGetMetadataReference.MicrosoftExtensionsPrimitives("3.1.7").Concat(TestHelper.ProjectTypeReference(projectType)))
.Verify();

[TestMethod]
public void ConditionEvaluatesToConstant_FromCSharp7() =>
public void ConditionEvaluatesToConstant_Sonar_CSharp7() =>
sonar.AddPaths("ConditionEvaluatesToConstant.CSharp7.cs")
.WithOptions(ParseOptionsHelper.FromCSharp7)
.Verify();

[Ignore] // Fixme: Remove after implementation
[TestMethod]
public void ConditionEvaluatesToConstant_FromCSharp8() =>
public void ConditionEvaluatesToConstant_Roslyn_CSharp7() =>
roslynCS.AddPaths("ConditionEvaluatesToConstant.CSharp7.cs")
.WithOptions(ParseOptionsHelper.FromCSharp7)
.Verify();

[TestMethod]
public void ConditionEvaluatesToConstant_Sonar_CSharp8() =>
sonar.AddPaths("ConditionEvaluatesToConstant.CSharp8.cs")
.AddReferences(MetadataReferenceFacade.NETStandard21)
.WithOptions(ParseOptionsHelper.FromCSharp8)
.Verify();

[Ignore] // FIXME: Remove after implementation
[TestMethod]
public void ConditionEvaluatesToConstant_Roslyn_CSharp8() =>
roslynCS.AddPaths("ConditionEvaluatesToConstant.CSharp8.cs")
.AddReferences(MetadataReferenceFacade.NETStandard21)
.WithOptions(ParseOptionsHelper.FromCSharp8)
.Verify();

#if NET

[TestMethod]
public void ConditionEvaluatesToConstant_FromCSharp9() =>
public void ConditionEvaluatesToConstant_Sonar_CSharp9() =>
sonar.AddPaths("ConditionEvaluatesToConstant.CSharp9.cs")
.WithOptions(ParseOptionsHelper.FromCSharp9)
.Verify();

[Ignore] // FIXME: Remove after implementation
[TestMethod]
public void ConditionEvaluatesToConstant_FromCSharp9_TopLevelStatements() =>
public void ConditionEvaluatesToConstant_Roslyn_CSharp9() =>
roslynCS.AddPaths("ConditionEvaluatesToConstant.CSharp9.cs")
.WithOptions(ParseOptionsHelper.FromCSharp9)
.Verify();

[TestMethod]
public void ConditionEvaluatesToConstant_Sonar_CSharp9_TopLevelStatements() =>
sonar.AddPaths("ConditionEvaluatesToConstant.CSharp9.TopLevelStatements.cs")
.WithTopLevelStatements()
.Verify();

[Ignore] // FIXME: Remove after implementation
[TestMethod]
public void ConditionEvaluatesToConstant_FromCSharp10() =>
public void ConditionEvaluatesToConstant_Roslyn_CSharp9_TopLevelStatements() =>
roslynCS.AddPaths("ConditionEvaluatesToConstant.CSharp9.TopLevelStatements.cs")
.WithTopLevelStatements()
.Verify();

[TestMethod]
public void ConditionEvaluatesToConstant_Sonar_CSharp10() =>
sonar.AddPaths("ConditionEvaluatesToConstant.CSharp10.cs")
.WithOptions(ParseOptionsHelper.FromCSharp10)
.WithConcurrentAnalysis(false)
.Verify();

[Ignore] // FIXME: Remove after implementation
[TestMethod]
public void ConditionEvaluatesToConstant_FromCSharp11() =>
public void ConditionEvaluatesToConstant_Roslyn_CSharp10() =>
roslynCS.AddPaths("ConditionEvaluatesToConstant.CSharp10.cs")
.WithOptions(ParseOptionsHelper.FromCSharp10)
.WithConcurrentAnalysis(false)
.Verify();

[TestMethod]
public void ConditionEvaluatesToConstant_Sonar_CSharp11() =>
sonar.AddPaths("ConditionEvaluatesToConstant.CSharp11.cs")
.WithOptions(ParseOptionsHelper.FromCSharp11)
.Verify();

[Ignore] // FIXME: Remove after implementation
[TestMethod]
public void ConditionEvaluatesToConstant_Roslyn_CSharp11() =>
roslynCS.AddPaths("ConditionEvaluatesToConstant.CSharp11.cs")
.WithOptions(ParseOptionsHelper.FromCSharp11)
.Verify();

#endif

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SonarAnalyzer.UnitTest.TestCases;

struct MyStruct
{
public bool x;
public bool y = false;

public MyStruct()
{
x = false;
}
}

class AClass
{
public static void DoSomething()
{
MyStruct myStruct = new();
if (myStruct.x) { } // FN
else if (myStruct.y) { } // FN
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
namespace SonarAnalyzer.UnitTest.TestCases
{
class AClass
{
void DoSomething() { }

void ListPattern()
{
int[] a = new int[] { 1, 2, 3 };
if (a is [1, 2, 3]) // FN
{
DoSomething();
}
}

void ListPattern2()
{
int[] a = new int[] { 1, 2, 3 };
if (a is [1, _, 3]) // FN
{
DoSomething();
}
}

void ListPattern3()
{
int[] a = new int[] { 1, 2, 3 };
if (a is [1, .., 3]) // FN
{
DoSomething();
}
}

void ListPattern4()
{
int[] a = new int[] { 1, 2, 3 };
if (a is [> 0, < 3, < 42]) // FN
{
DoSomething();
}
}
}
}
Loading

0 comments on commit e4282e7

Please sign in to comment.