Skip to content

Commit

Permalink
List patterns: main IDE scenarios (#53850)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcouv authored Oct 23, 2021
1 parent 3fc766e commit 2259e13
Show file tree
Hide file tree
Showing 11 changed files with 657 additions and 2 deletions.
30 changes: 30 additions & 0 deletions src/Compilers/CSharp/Portable/Syntax/SyntaxNormalizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,29 @@ private static bool NeedsSeparatorForPositionalPattern(SyntaxToken token, Syntax
return false;
}

private static bool NeedsSeparatorForListPattern(SyntaxToken token, SyntaxToken next)
{
var listPattern = token.Parent as ListPatternSyntax ?? next.Parent as ListPatternSyntax;
if (listPattern == null)
{
return false;
}

// is$$[1, 2]
if (next.IsKind(SyntaxKind.OpenBracketToken))
{
return true;
}

// is [1, 2]$$list
if (token.IsKind(SyntaxKind.OpenBracketToken))
{
return listPattern.Designation is not null;
}

return false;
}

private static bool NeedsSeparator(SyntaxToken token, SyntaxToken next)
{
if (token.Parent == null || next.Parent == null)
Expand Down Expand Up @@ -806,15 +829,22 @@ private static bool NeedsSeparator(SyntaxToken token, SyntaxToken next)
case SyntaxKind.NotKeyword:
return true;
}

if (NeedsSeparatorForPropertyPattern(token, next))
{
return true;
}

if (NeedsSeparatorForPositionalPattern(token, next))
{
return true;
}

if (NeedsSeparatorForListPattern(token, next))
{
return true;
}

return false;
}

Expand Down
24 changes: 24 additions & 0 deletions src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxNormalizerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,30 @@ DeliveryTruck t when (t.GrossWeightClass < 3000) => 10.00m - 2.00m,
TestNormalizeStatement(a, b);
}

[Fact]
public void TestNormalizeListPattern()
{
var text = "_ = this is[ 1,2,.. var rest ];";
var expected = @"_ = this is [1, 2, ..var rest];";
TestNormalizeStatement(text, expected);
}

[Fact]
public void TestNormalizeListPattern_TrailingComma()
{
var text = "_ = this is[ 1,2, 3,];";
var expected = @"_ = this is [1, 2, 3, ];";
TestNormalizeStatement(text, expected);
}

[Fact]
public void TestNormalizeListPattern_EmptyList()
{
var text = "_ = this is[];";
var expected = @"_ = this is [];";
TestNormalizeStatement(text, expected);
}

[Fact, WorkItem(50742, "https://github.com/dotnet/roslyn/issues/50742")]
public void TestLineBreakInterpolations()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,36 @@ public void Array_Nested()
CheckStart(session.Session);
}

[WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)]
public void ListPattern()
{
var code = @"
class C
{
void M(object o)
{
_ = o is $$
}
}
";
var expected = @"
class C
{
void M(object o)
{
_ = o is [
]
}
}
";
using var session = CreateSession(code);
CheckStart(session.Session);
// Open bracket probably should be moved to new line
// Close bracket probably should be aligned with open bracket
// Tracked by https://github.com/dotnet/roslyn/issues/57244
CheckReturn(session.Session, 0, expected);
}

internal static Holder CreateSession(string code)
{
return CreateSession(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4889,6 +4889,51 @@ await TestInMethodAsync(@"
Punctuation.Semicolon);
}

[Theory]
[CombinatorialData]
public async Task TestListPattern(TestHost testHost)
{
await TestInMethodAsync(@"
_ = new int[0] switch
{
case [1, 2]:
break;
case [1, .. var end]:
break;
}",
testHost,
Identifier("_"),
Operators.Equals,
Keyword("new"),
Keyword("int"),
Punctuation.OpenBracket,
Number("0"),
Punctuation.CloseBracket,
ControlKeyword("switch"),
Punctuation.OpenCurly,
Keyword("case"),
Punctuation.OpenBracket,
Number("1"),
Punctuation.Comma,
Number("2"),
Punctuation.CloseBracket,
Punctuation.Colon,
ControlKeyword("break"),
Punctuation.Semicolon,
Keyword("case"),
Punctuation.OpenBracket,
Number("1"),
Punctuation.Comma,
Punctuation.DotDot,
Identifier("var"),
Identifier("end"),
Punctuation.CloseBracket,
Punctuation.Colon,
ControlKeyword("break"),
Punctuation.Semicolon,
Punctuation.CloseCurly);
}

[Theory]
[CombinatorialData]
public async Task TestTupleTypeSyntax(TestHost testHost)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1352,6 +1352,29 @@ await AssertIndentNotUsingSmartTokenFormatterButUsingIndenterAsync(
expectedIndentation: 12);
}

[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task IndentListPattern()
{
var code = @"
class C
{
void Main(object o)
{
var y = o is
[
]
}
}";
// Expected indentation probably should be 12 instead
// Tracked by https://github.com/dotnet/roslyn/issues/57244
await AssertIndentNotUsingSmartTokenFormatterButUsingIndenterAsync(
code,
indentationLine: 7,
expectedIndentation: 8);
}

[Trait(Traits.Feature, Traits.Features.SmartIndent)]
[WpfTheory]
[InlineData("x", "is < 7 and (>= 3 or > 50) or not <= 0;", 12)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7492,6 +7492,70 @@ void M2()
MainDescription($"({FeaturesResources.local_variable}) string? x"));
}

[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task TestVarPatternOnVarKeyword_InListPattern()
{
await TestAsync(
@"class C
{
void M(char[] array)
{
if (array is [ va$$r one ])
{
}
}
}",
MainDescription("struct System.Char"));
}

[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task TestVarPatternOnVariableItself_InListPattern()
{
await TestAsync(
@"class C
{
void M(char[] array)
{
if (array is [ var o$$ne ])
{
}
}
}",
MainDescription($"({FeaturesResources.local_variable}) char one"));
}

[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task TestVarPatternOnVarKeyword_InSlicePattern()
{
await TestAsync(
@"class C
{
void M(char[] array)
{
if (array is [..va$$r one ])
{
}
}
}",
MainDescription("char[]"));
}

[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task TestVarPatternOnVariableItself_InSlicePattern()
{
await TestAsync(
@"class C
{
void M(char[] array)
{
if (array is [ ..var o$$ne ])
{
}
}
}",
MainDescription($"({FeaturesResources.local_variable}) char[]? one"));
}

[WorkItem(53135, "https://github.com/dotnet/roslyn/issues/53135")]
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task TestDocumentationCData()
Expand Down
Loading

0 comments on commit 2259e13

Please sign in to comment.