Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -3269,4 +3269,88 @@ public void M()
}
}
""");

[Theory, WorkItem("https://github.com/dotnet/roslyn/issues/80082")]
[InlineData("int?")]
[InlineData("int*")]
[InlineData("int[]")]
[InlineData("int")]
[InlineData("A::B")]
[InlineData("List<A>")]
[InlineData("List<int>")]
[InlineData("A.List<A>")]
[InlineData("A.List<int>")]
[InlineData("global::A.List<A>")]
[InlineData("global::A.List<int>")]
[InlineData("(A, B)")]
public Task TestCollectionExpressionCast_NotEmpty_ShouldRemove(string type)
=> TestInRegularAndScriptAsync($$"""
class C
{
public void M()
{
var v = ({{type}})$$([a, b, c]);
}
}
""",
$$"""
class C
{
public void M()
{
var v = ({{type}})[a, b, c];
}
}
""");

[Theory, WorkItem("https://github.com/dotnet/roslyn/issues/80082")]
[InlineData("int?")]
[InlineData("int*")]
[InlineData("int[]")]
[InlineData("int")]
[InlineData("A::B")]
[InlineData("List<A>")]
[InlineData("List<int>")]
[InlineData("A.List<A>")]
[InlineData("A.List<int>")]
[InlineData("global::A.List<A>")]
[InlineData("global::A.List<int>")]
[InlineData("(A, B)")]
[InlineData("A")]
[InlineData("A.B")]
[InlineData("global::A.B")]
public Task TestCollectionExpressionCast_Empty_ShouldRemove(string type)
=> TestInRegularAndScriptAsync($$"""
class C
{
public void M()
{
var v = ({{type}})$$([]);
}
}
""",
$$"""
class C
{
public void M()
{
var v = ({{type}})[];
}
}
""");

[Theory, WorkItem("https://github.com/dotnet/roslyn/issues/80082")]
[InlineData("A")]
[InlineData("A.B")]
[InlineData("global::A.B")]
public Task TestCollectionExpressionCast_NotEmpty_ShouldNotRemove(string type)
=> TestMissingInRegularAndScriptAsync($$"""
class C
{
public void M()
{
var v = ({{type}})$$([a, b, c]);
}
}
""");
}
33 changes: 33 additions & 0 deletions src/Features/CSharpTest/InlineTemporary/InlineTemporaryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5235,4 +5235,37 @@ void M(string[] args)
}
}
""");

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/80081")]
public Task InlineCollectionIntoCast()
=> TestInRegularAndScriptAsync(
"""
using System;
using System.Collections.Generic;
using System.Linq;

class Command: List<int>;

var commands = new[] {1,2,3,4,5,6,7,8 }
.Chunk(3)
.Select(chunk => {
Command [||]command = [..chunk];
return command;
})
.ToList();
""",
"""
using System;
using System.Collections.Generic;
using System.Linq;

class Command: List<int>;

var commands = new[] {1,2,3,4,5,6,7,8 }
.Chunk(3)
.Select(chunk => {
return (Command)([..chunk]);
})
.ToList();
""", new(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)));
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,24 @@ public static bool CanRemoveParentheses(
}

// ([...]) -> [...]
if (expression.IsKind(SyntaxKind.CollectionExpression))
return true;
if (expression is CollectionExpressionSyntax collectionExpression)
{
// For back compat, the language disallows a few forms of casting an collection expression.
// For example: `(A)[1, 2, 3]`. This is because this form already has an interpretation as
// indexing into a parenthesized expression. Check for these cases and only allow if it is
// totally safe. For example `(List<int>)[1, 2, 3]` is still safe as that was not a legal
// expression in the past.
//
// Note: because `(T)[]` is never legal (an empty indexer is not legal), that form is always
// considered a collection expression, regardless of what T is.
if (collectionExpression.Elements.Count == 0)
return true;

return parentExpression is not CastExpressionSyntax
{
Type: IdentifierNameSyntax or QualifiedNameSyntax { Right: IdentifierNameSyntax }
};
}

// int Prop => (x); -> int Prop => x;
if (nodeParent is ArrowExpressionClauseSyntax arrowExpressionClause && arrowExpressionClause.Expression == node)
Expand Down
Loading