Skip to content

Commit

Permalink
fix FP
Browse files Browse the repository at this point in the history
  • Loading branch information
mary-georgiou-sonarsource committed Jul 4, 2024
1 parent 0a1a90e commit 2ab75e6
Showing 1 changed file with 44 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using SonarAnalyzer.SymbolicExecution.Constraints;

namespace SonarAnalyzer.SymbolicExecution.Roslyn.OperationProcessors;
Expand Down Expand Up @@ -89,24 +91,46 @@ private static ProgramState[] ProcessLinqEnumerableAndQueryable(ProgramState sta
// ElementAtOrDefault is intentionally not supported. It's causing many FPs
else if (name is nameof(Enumerable.FirstOrDefault) or nameof(Enumerable.LastOrDefault) or nameof(Enumerable.SingleOrDefault)
&& invocation.TryGetInstance(state) is { } instance
&& instance.TrackedSymbol(state) is { } instanceSymbol)
&& instance.TrackedSymbol(state) is { } instanceSymbol
&& GetElementType(instanceSymbol) is { } elementType)
{
return states.SelectMany(x =>
x[instanceSymbol]?.Constraint<CollectionConstraint>() switch
{
CollectionConstraint constraint when constraint == CollectionConstraint.Empty => x.SetOperationConstraint(invocation, ObjectConstraint.Null).ToArray(),
CollectionConstraint constraint when constraint == CollectionConstraint.NotEmpty => x.SetOperationConstraint(invocation, ObjectConstraint.NotNull).ToArray(),
_ =>
[
x.SetOperationConstraint(invocation, ObjectConstraint.Null),
x.SetOperationConstraint(invocation, ObjectConstraint.NotNull)
]
}).ToArray();
return states.SelectMany(x => GetStuff(x, elementType, instanceSymbol)).ToArray();
}
else
{
return states;
}

IEnumerable<ProgramState> GetStuff(ProgramState state, ITypeSymbol elementType, ISymbol instanceSymbol)
{
if (elementType.IsReferenceType)
{
return state[instanceSymbol]?.Constraint<CollectionConstraint>() switch
{
CollectionConstraint constraint when constraint == CollectionConstraint.Empty => [state.SetOperationConstraint(invocation, ObjectConstraint.Null)],
CollectionConstraint constraint when constraint == CollectionConstraint.NotEmpty =>
[
state,
state.SetOperationConstraint(invocation, ObjectConstraint.NotNull)
],
_ =>
[
state.SetOperationConstraint(invocation, ObjectConstraint.Null),
state.SetOperationConstraint(invocation, ObjectConstraint.NotNull)
]
};
}
else
{
return state[instanceSymbol]?.Constraint<CollectionConstraint>() == CollectionConstraint.Empty
? state.SetOperationConstraint(invocation, ObjectConstraint.Null).ToArray()
: [
state.SetOperationConstraint(invocation, ObjectConstraint.Null),
state.SetOperationConstraint(invocation, ObjectConstraint.NotNull)
]
;
}
}
}

private static ProgramState[] ProcessBoolCollectionMethods(ProgramState state, IInvocationOperationWrapper invocation)
Expand Down Expand Up @@ -137,4 +161,12 @@ static bool HasNoParameters(IMethodSymbol symbol) =>
(symbol.IsExtensionMethod && symbol.Parameters.Length == 1)
|| symbol.Parameters.IsEmpty;
}

private static ITypeSymbol GetElementType(ISymbol instance) =>
instance.GetSymbolType() switch
{
INamedTypeSymbol { TypeArguments: { Length: 1 } typeArguments } => typeArguments.First(),
IArrayTypeSymbol arrayType => arrayType.ElementType,
_ => null
};
}

0 comments on commit 2ab75e6

Please sign in to comment.