Skip to content

Commit

Permalink
Fix S2589 FP: Discard pattern in switch statement (#8485)
Browse files Browse the repository at this point in the history
  • Loading branch information
zsolt-kolbay-sonarsource authored Dec 20, 2023
1 parent da53571 commit 6dda358
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ OperationKindEx.PropertyReference when operation.ToPropertyReference() is { Prop
internal static IPropertyReferenceOperationWrapper? AsPropertyReference(this IOperation operation) =>
operation.As(OperationKindEx.PropertyReference, IPropertyReferenceOperationWrapper.FromOperation);

internal static IRecursivePatternOperationWrapper? AsRecursivePattern(this IOperation operation) =>
operation.As(OperationKindEx.RecursivePattern, IRecursivePatternOperationWrapper.FromOperation);

internal static ITupleOperationWrapper? AsTuple(this IOperation operation) =>
operation.As(OperationKindEx.Tuple, ITupleOperationWrapper.FromOperation);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,18 @@ public override ProgramState ConditionEvaluated(SymbolicContext context)
private bool IsIgnored(ProgramState state, IOperation operation) =>
operation.Kind is OperationKindEx.Literal
|| IsVarPattern(operation)
|| IsDiscardPattern(operation)
|| IsDiscardPattern(state, operation)
|| operation.TrackedSymbol(state) is IFieldSymbol { IsConst: true }
|| operation.Syntax.Ancestors().Any(x => IsInsideUsingDeclaration(x) || IsLockStatement(x));

private static bool IsVarPattern(IOperation operation) =>
operation.AsIsPattern()?.Pattern.WrappedOperation.AsDeclarationPattern()?.MatchesNull is true;

private static bool IsDiscardPattern(IOperation operation) =>
operation.AsIsPattern() is { } pattern
&& pattern.Pattern.WrappedOperation.Kind is OperationKindEx.DiscardPattern;
private static bool IsDiscardPattern(ProgramState state, IOperation operation) =>
operation.Kind is OperationKindEx.DiscardPattern
|| (operation.AsIsPattern() is { } isPattern
&& (isPattern.Pattern.WrappedOperation.Kind is OperationKindEx.DiscardPattern
|| (isPattern.Pattern.WrappedOperation.AsRecursivePattern() is {} recursivePattern && recursivePattern.DeconstructionSubpatterns.All(x => IsDiscardPattern(state, x)))));

public override void ExecutionCompleted()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,22 +269,49 @@ var value when value.HasFlag(Flags.Bar) => 2, // Compliant
}

// https://github.com/SonarSource/sonar-dotnet/issues/8008
namespace Repro_8008
public class Repro_8008
{
class Person
public int Compare(string name1, string name2) => (name1, name2) switch
{
public int? Age { get; set; }
}
(null, null) => 0,
(null, _) => 1,
(_, null) => -1,
(_, _) => Comparer<string>.Default.Compare(name1, name2)
};

public int NestedTuples(string name1, string name2, string name3) => ((name1, name2), name3) switch
{
((null, null), null) => 42,
((null, null), _) => 43,
((_, _), null) => 44,
((_, _), _) => 45
};

public int DeeperNestedTuples(string name1, string name2, string name3, string name4) => (((name1, name2), name3), name4) switch
{
(((null, null), null), null) => 42,
(((_, _), null), null) => 43,
(((_, _), _), null) => 44,
(((_, _), _), _) => 45,
};

class Double_Wildcard_FP
public int TupleWithKnownNullConstraint()
{
public int Compare(Person x, Person y) => (x.Age, y.Age) switch
string name1 = null;
string name2 = null;
return (name1, name2) switch
{
(null, null) => 0,
(null, _) => 1,
(_, null) => -1,
(_, _) => Comparer<int>.Default.Compare(x.Age.Value, y.Age.Value) // Noncompliant {{Change this condition so that it does not always evaluate to 'True'.}}
//^^^^^^
(null, null) => 0, // FN
(null, _) => 1, // FN
(_, null) => -1, // FN
(_, _) => Comparer<string>.Default.Compare(name1, name2)
};
}

public int TupleWithDeclaration(string name1, string name2) =>
(name1, name2) switch
{
("A", "B") => 0,
(var x, _) => -1, // Noncompliant - FP
};
}

0 comments on commit 6dda358

Please sign in to comment.