Skip to content

Commit

Permalink
Extended property patterns: few more tests (#53874)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcouv authored Jun 8, 2021
1 parent c691fff commit 5de28db
Show file tree
Hide file tree
Showing 5 changed files with 312 additions and 0 deletions.
117 changes: 117 additions & 0 deletions src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests5.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1715,6 +1715,123 @@ class C2
);
}

[Fact]
public void ExtendedPropertyPatterns_EvaluationOrder()
{
var program = @"
if (new C() is { Prop1.True: true, Prop1.Prop2: not null })
{
System.Console.WriteLine(""matched1"");
}
if (new C() is { Prop1.Prop2: not null, Prop1.True: true })
{
System.Console.WriteLine(""matched2"");
}
if (new C() is { Prop1.Prop2: not null, Prop2.True: true })
{
System.Console.WriteLine(""matched3"");
}
if (new C() is { Prop1.Prop2.Prop3.True: true })
{
System.Console.WriteLine(""matched3"");
}
if (new C() is { Prop1: { Prop2.Prop3.True: true } })
{
System.Console.WriteLine(""matched4"");
}
if (new C() is { Prop1.True: false, Prop1.Prop2: not null })
{
throw null;
}
class C
{
public C Prop1 { get { System.Console.Write(""Prop1 ""); return this; } }
public C Prop2 { get { System.Console.Write(""Prop2 ""); return this; } }
public C Prop3 { get { System.Console.Write(""Prop3 ""); return this; } }
public bool True { get { System.Console.Write(""True ""); return true; } }
}
";
CompileAndVerify(program, parseOptions: TestOptions.RegularWithExtendedPropertyPatterns, expectedOutput: @"
Prop1 True Prop2 matched1
Prop1 Prop2 True matched2
Prop1 Prop2 Prop2 True matched3
Prop1 Prop2 Prop3 True matched3
Prop1 Prop2 Prop3 True matched4
Prop1 True");
}

[Fact]
public void ExtendedPropertyPatterns_StaticMembers()
{
var program = @"
_ = new C() is { Static: null }; // 1
_ = new C() is { Instance.Static: null }; // 2
_ = new C() is { Static.Instance: null }; // 3
class C
{
public C Instance { get; set; }
public static C Static { get; set; }
}
";
var comp = CreateCompilation(program, parseOptions: TestOptions.RegularWithExtendedPropertyPatterns);
comp.VerifyEmitDiagnostics(
// (2,18): error CS0176: Member 'C.Static' cannot be accessed with an instance reference; qualify it with a type name instead
// _ = new C() is { Static: null }; // 1
Diagnostic(ErrorCode.ERR_ObjectProhibited, "Static").WithArguments("C.Static").WithLocation(2, 18),
// (3,27): error CS0176: Member 'C.Static' cannot be accessed with an instance reference; qualify it with a type name instead
// _ = new C() is { Instance.Static: null }; // 2
Diagnostic(ErrorCode.ERR_ObjectProhibited, "Static").WithArguments("C.Static").WithLocation(3, 27),
// (4,18): error CS0176: Member 'C.Static' cannot be accessed with an instance reference; qualify it with a type name instead
// _ = new C() is { Static.Instance: null }; // 3
Diagnostic(ErrorCode.ERR_ObjectProhibited, "Static").WithArguments("C.Static").WithLocation(4, 18)
);
}

[Fact]
public void ExtendedPropertyPatterns_Exhaustiveness()
{
var program = @"
_ = new C() switch // 1
{
{ Prop.True: true } => 0
};
_ = new C() switch
{
{ Prop.True: true } => 0,
{ Prop.True: false } => 0
};
#nullable enable
_ = new C() switch // 2
{
{ Prop.Prop: null } => 0
};
class C
{
public C Prop { get => throw null!; }
public bool True { get => throw null!; }
}
";
var comp = CreateCompilation(program, parseOptions: TestOptions.RegularWithExtendedPropertyPatterns);
comp.VerifyEmitDiagnostics(
// (2,13): warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '{ Prop: { True: false } }' is not covered.
// _ = new C() switch // 1
Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("{ Prop: { True: false } }").WithLocation(2, 13),
// (14,13): warning CS8509: The switch expression does not handle all possible values of its input type (it is not exhaustive). For example, the pattern '{ Prop: { Prop: not null } }' is not covered.
// _ = new C() switch // 2
Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustive, "switch").WithArguments("{ Prop: { Prop: not null } }").WithLocation(14, 13)
);
}

public class FlowAnalysisTests : FlowTestBase
{
[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,50 @@ void Method()
expectedIndentation: 20);
}

[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public void ExtendedPropertyPattern()
{
var code = @"
class C
{
void M()
{
_ = this is
{
";
AssertSmartIndent(
code,
indentationLine: 7,
expectedIndentation: 12);
}

[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public void ExtendedPropertyPattern_WithPattern()
{
var code = @"
class C
{
void M()
{
_ = this is
{
A.B: 1,
";
AssertSmartIndent(
code,
indentationLine: 7,
expectedIndentation: 12);
AssertSmartIndent(
code,
indentationLine: 9,
expectedIndentation: 12);
}

[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public void Block()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8934,6 +8934,96 @@ class Blah
" + TestResources.NetFX.ValueTuple.tuplelib_cs, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview));
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)]
public async Task TestConstantPatternInPropertyPattern()
{
await TestInRegularAndScriptAsync(
@"
class C
{
Blah SomeBlah { get; set; }
void M2()
{
object o = null;
if (o is C { SomeBlah: [|MissingConstant|] })
{
}
}
class Blah
{
}
}
",
@"
class C
{
private const Blah MissingConstant;
Blah SomeBlah { get; set; }
void M2()
{
object o = null;
if (o is C { SomeBlah: MissingConstant })
{
}
}
class Blah
{
}
}
", parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview));
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)]
public async Task TestConstantPatternInExtendedPropertyPattern()
{
await TestInRegularAndScriptAsync(
@"
class C
{
C SomeC { get; set; }
Blah SomeBlah { get; set; }
void M2()
{
object o = null;
if (o is C { SomeC.SomeBlah: [|MissingConstant|] })
{
}
}
class Blah
{
}
}
",
@"
class C
{
private const Blah MissingConstant;
C SomeC { get; set; }
Blah SomeBlah { get; set; }
void M2()
{
object o = null;
if (o is C { SomeC.SomeBlah: MissingConstant })
{
}
}
class Blah
{
}
}
", parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview));
}

[WorkItem(9090, "https://github.com/dotnet/roslyn/issues/9090")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)]
public async Task TestPropertyPatternInIsPattern9()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,32 @@ public class C2
End Using
End Function

<WpfTheory, CombinatorialData>
<Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function CompletionOnListPattern_FirstNested(showCompletionInArgumentLists As Boolean) As Task
Using state = TestStateFactory.CreateCSharpTestState(
<Document>
public class C
{
}
public class C2
{
public C2 CProperty { get; set; }
public int IntProperty { get; set; }
void M(C c)
{
_ = c is { $$
}
}
</Document>,
showCompletionInArgumentLists:=showCompletionInArgumentLists, languageVersion:=LanguageVersion.Preview)

' This is the expected behavior until we implement support for list-patterns.
state.SendTypeChars("CP")
Await state.AssertNoCompletionSession()
End Using
End Function

<WpfTheory, CombinatorialData>
<Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function CompletionOnExtendedPropertyPattern_Hidden(showCompletionInArgumentLists As Boolean) As Task
Expand Down
35 changes: 35 additions & 0 deletions src/EditorFeatures/Test2/Rename/InlineRenameTests.vb
Original file line number Diff line number Diff line change
Expand Up @@ -2130,5 +2130,40 @@ class [|C|]
Await VerifyTagsAreCorrect(workspace, "BarGoo")
End Using
End Function

<WpfTheory>
<CombinatorialData, Trait(Traits.Feature, Traits.Features.Rename)>
Public Async Function RenameExtendedProperty(host As RenameTestHost) As Task
Using workspace = CreateWorkspaceWithWaiter(
<Workspace>
<Project Language="C#" CommonReferences="true" LanguageVersion="preview">
<Document>
class C
{
void M()
{
_ = this is { Other.[|Goo|]: not null, Other.Other.[|Goo|]: not null, [|Goo|]: null } ;
}

public C [|$$Goo|] { get; set; }
public C Other { get; set; }
}
</Document>
</Project>
</Workspace>, host)

Dim session = StartSession(workspace)

' Type a bit in the file
Dim caretPosition = workspace.Documents.Single(Function(d) d.CursorPosition.HasValue).CursorPosition.Value
Dim textBuffer = workspace.Documents.Single().GetTextBuffer()

textBuffer.Insert(caretPosition, "Bar")

session.Commit()

Await VerifyTagsAreCorrect(workspace, "BarGoo")
End Using
End Function
End Class
End Namespace

0 comments on commit 5de28db

Please sign in to comment.