Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix S3878 AD0001: Cover the case of ImplicitArrayCreationExpressionSyntax #9456

Merged
merged 8 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
32 changes: 17 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,27 @@ 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[]]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Method(new [] { 1, 2, 3, }); // Compliant, Elements in args: [System.Int32[]]
Method(new[] { 1, 2, 3, }); // Compliant, Elements in args: [System.Int32[]]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add one more test with a multidimensional array

Suggested change
Method(new [] { 1, 2, 3, }); // Compliant, Elements in args: [System.Int32[]]
Method(new[] { 1, 2, 3, }); // Compliant, Elements in args: [System.Int32[]]
Method(new[,] { { 1, 2 } }); // Compliant, Elements in args: [System.Int32[,]]

}
}

Expand Down
Loading