Skip to content

Commit

Permalink
Fix S3878 AD0001: Cover the case of ImplicitArrayCreationExpressionSy…
Browse files Browse the repository at this point in the history
…ntax (#9456)
  • Loading branch information
mary-georgiou-sonarsource authored Jun 24, 2024
1 parent fb539c2 commit 9c5b2d1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ protected override ArgumentSyntax LastArgumentIfArrayCreation(SyntaxNode express
: null;

protected override ITypeSymbol ArrayElementType(ArgumentSyntax argument, SemanticModel model) =>
model.GetTypeInfo(((ArrayCreationExpressionSyntax)argument.Expression).Type.ElementType).Type;
argument.Expression switch
{
ArrayCreationExpressionSyntax arrayCreation => model.GetTypeInfo(arrayCreation.Type.ElementType).Type,
ImplicitArrayCreationExpressionSyntax implicitArrayCreation => (model.GetTypeInfo(implicitArrayCreation).Type as IArrayTypeSymbol)?.ElementType,
_ => null
};

private static BaseArgumentListSyntax ArgumentList(SyntaxNode expression) =>
expression switch
Expand Down
37 changes: 22 additions & 15 deletions analyzers/tests/SonarAnalyzer.Test/TestCases/ArrayPassedAsParams.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,25 +81,32 @@ public void Method(params object[] args) { }
public void MethodMixed(int i, params object[] args) { }
public void MethodArray(params Array[] args) { }
public void MethodJaggedArray(params int[][] args) { }
public void MethodImplicitArray(params string[] args) { }

public void CallMethod(dynamic d)
{
Method(new String[] { "1", "2" }); // Noncompliant, elements in args: ["1", "2"]
// The argument given for a parameter array can be a single expression that is implicitly convertible (§10.2) to the parameter array type.
// In this case, the parameter array acts precisely like a value parameter.
// see: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#14625-parameter-arrays
Method(new object[] { new int[] { 1, 2 } }); // FN, elements in args: [System.Int32[]]
Method(new int[] { 1, 2, 3, }); // Compliant, Elements in args: [System.Int32[]]
Method(new String[] { "1", "2" }, new String[] { "1", "2" }); // Compliant, elements in args: [System.String[], System.String[]]
Method(new String[] { "1", "2"}, new int[] { 1, 2}); // Compliant, elements in args: [System.String[], System.Int32[]]
MethodMixed(1, new String[] { "1", "2" }); // Noncompliant
MethodArray(new String[] { "1", "2" }, new String[] { "1", "2" }); // Compliant, elements in args: [System.String[], System.String[]]
MethodArray(new int[] { 1, 2 }, new int[] { 1, 2 }); // Compliant, elements in args: [System.Int32[], System.Int32[]]

MethodJaggedArray(new int[] { 1, 2 }); // Compliant: jagged array [System.Object[]]
Method(d); // Compliant
Method("Hello", 2); // Compliant
Method(new String[] { "1", "2" }); // Noncompliant, elements in args: ["1", "2"]
// The argument given for a parameter array can be a single expression that is implicitly convertible (§10.2) to the parameter array type.
// In this case, the parameter array acts precisely like a value parameter.
// see: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#14625-parameter-arrays
Method(new object[] { new int[] { 1, 2 } }); // FN, elements in args: [System.Int32[]]
Method(new int[] { 1, 2, 3, }); // Compliant, Elements in args: [System.Int32[]]
Method(new String[] { "1", "2" }, new String[] { "1", "2" }); // Compliant, elements in args: [System.String[], System.String[]]
Method(new String[] { "1", "2"}, new int[] { 1, 2}); // Compliant, elements in args: [System.String[], System.Int32[]]
MethodMixed(1, new String[] { "1", "2" }); // Noncompliant
MethodArray(new String[] { "1", "2" }, new String[] { "1", "2" }); // Compliant, elements in args: [System.String[], System.String[]]
MethodArray(new int[] { 1, 2 }, new int[] { 1, 2 }); // Compliant, elements in args: [System.Int32[], System.Int32[]]
MethodJaggedArray(new int[] { 1, 2 }); // Compliant: jagged array [System.Object[]]
Method(d); // Compliant
Method("Hello", 2); // Compliant
string.Format(CultureInfo.InvariantCulture, "{0}.{1}", new object[] { "", new object() });
MethodImplicitArray(new[] { "Hello", "Hi" }); // Noncompliant , Implicit array creation
Method(new[] { 1, 2, 3, }); // Compliant, Elements in args: [System.Int32[]]
Method(new[,] { { 1, 2 } }); // Compliant, Elements in args: [System.Int32[,]]
Method(new object[] { null }); // Compliant
Method(new object[,] { { null } }); // Compliant
Method(new[,] { { new object() } }); // Compliant
Method(new object[][] { new[] { new object() } }); // Compliant
}
}

Expand Down

0 comments on commit 9c5b2d1

Please sign in to comment.