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 a5d372d commit f19c0eb
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,34 @@ private static ProgramState[] ProcessLinqEnumerableAndQueryable(ProgramState sta
return states.Select(x => x.SetOperationConstraint(invocation, ObjectConstraint.NotNull)).ToArray();
}
// 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))
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
&& GetElementType(instanceSymbol) is { } elementType)
{
return states.SelectMany(x => new List<ProgramState>
{
x.SetOperationConstraint(invocation, ObjectConstraint.Null),
x.SetOperationConstraint(invocation, ObjectConstraint.NotNull)
}).ToArray();
return states.SelectMany(x => ProcessElementOrDefaultMethods(x, invocation, elementType, instanceSymbol)).ToArray();
}
else
{
return states;
}

static IEnumerable<ProgramState> ProcessElementOrDefaultMethods(ProgramState state, IInvocationOperationWrapper invocation, ITypeSymbol elementType, ISymbol instanceSymbol) =>
state[instanceSymbol]?.Constraint<CollectionConstraint>() switch
{
CollectionConstraint constraint when constraint == CollectionConstraint.Empty && elementType.IsReferenceType => [state.SetOperationConstraint(invocation, ObjectConstraint.Null)],
CollectionConstraint constraint when constraint == CollectionConstraint.NotEmpty && elementType.IsReferenceType =>
[
state,
state.SetOperationConstraint(invocation, ObjectConstraint.NotNull)
],
_ when elementType.IsReferenceType =>
[
state.SetOperationConstraint(invocation, ObjectConstraint.Null),
state.SetOperationConstraint(invocation, ObjectConstraint.NotNull)
],
_ => state.SetOperationConstraint(invocation, ObjectConstraint.NotNull).ToArray()
};
}

private static ProgramState[] ProcessBoolCollectionMethods(ProgramState state, IInvocationOperationWrapper invocation)
Expand Down Expand Up @@ -129,4 +145,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
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2085,7 +2085,7 @@ void Method(Exception[] array)
if (array.Any())
{
Exception exception = array.FirstOrDefault();
Console.WriteLine(exception.Message); // Noncompliant - FP
Console.WriteLine(exception.Message); // Compliant - we know that array is not empty
}
}
}
Expand Down

0 comments on commit f19c0eb

Please sign in to comment.