// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests.PDB { public class PDBLambdaTests : CSharpPDBTestBase { [WorkItem(539898, "DevDiv")] [Fact] public void SequencePoints_Body() { var source = @" using System; delegate void D(); class C { public static void Main() { D d = () => Console.Write(1); d(); } } "; var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyPdb(@" 0 "); } [Fact, WorkItem(543479, "DevDiv")] public void Nested() { var source = @" using System; class Test { public static int Main() { if (M(1) != 10) return 1; return 0; } static public int M(int p) { Func f1 = delegate(int x) { int q = 2; Func f2 = (y) => { return p + q + x + y; }; return f2(3); }; return f1(4); } } "; var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugExe); c.VerifyPdb(@" 1 "); } [Fact, WorkItem(543479, "DevDiv")] public void InitialSequencePoints() { var source = @" class Test { void Foo(int p) { System.Func f1 = () => p; f1(); } } "; // Specifically note the sequence points at 0x0 in Test.Main, Test.M, and the lambda bodies. var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyPdb(@" 0 "); } [Fact, WorkItem(543479, "DevDiv")] public void Nested_InitialSequencePoints() { var source = @" using System; class Test { public static int Main() { if (M(1) != 10) // can't step into M() at all return 1; return 0; } static public int M(int p) { Func f1 = delegate(int x) { int q = 2; Func f2 = (y) => { return p + q + x + y; }; return f2(3); }; return f1(4); } } "; // Specifically note the sequence points at 0x0 in Test.Main, Test.M, and the lambda bodies. var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyPdb(@" 1 "); } [Fact] public void FieldAndPropertyInitializers() { var source = @" using System; class B { public B(Func f) { } } class C : B { Func FI = () => 1; static Func FS = () => 2; Func P { get; } = () => FS(); public C() : base(() => 3) {} } "; var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyDiagnostics(); c.VerifyPdb(@" 5 6 "); } [Fact] public void ClosuresInCtor() { var source = @" using System; class B { public B(Func f) { } } class C : B { Func f, g, h; public C(int a, int b) : base(() => a) { int c = 1; f = () => b; g = () => f(); h = () => c; } } "; var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyDiagnostics(); c.VerifyPdb(@" 3 "); } [Fact] public void Queries1() { var source = @" using System.Linq; class C { public void M() { int c = 1; var x = from a in new[] { 1, 2, 3 } let b = a + c where b > 10 select b * 10; } } "; var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyDiagnostics(); c.VerifyPdb(@" 0 "); } [Fact] public void Queries_GroupBy1() { var source = @" using System.Linq; class C { void F() { var result = from/*0*/ a in new[] { 1, 2, 3 } join/*1*/ b in new[] { 5 } on a + 1 equals b - 1 group/*2*/ new { a, b = a + 5 } by new { c = a + 4 } into d select/*3*/ d.Key; } } "; var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyDiagnostics(); c.VerifyPdb(@" 0 "); } [Fact] public void ForEachStatement_Array() { string source = @" using System; class C { void G(Func f) {} void F() { foreach (int x0 in new[] { 1 }) // Group #0 { // Group #1 int x1 = 0; G(a => x0); G(a => x1); } } }"; var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyDiagnostics(); // note that the two closures have a different syntax offset c.VerifyPdb("C.F", @" 1 "); } [Fact] public void ForEachStatement_MultidimensionalArray() { string source = @" using System; class C { void G(Func f) {} void F() { foreach (int x0 in new[,] { { 1 } }) // Group #0 { // Group #1 int x1 = 0; G(a => x0); G(a => x1); } } }"; var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyDiagnostics(); // note that the two closures have a different syntax offset c.VerifyPdb("C.F", @" 1 "); } [Fact] public void ForEachStatement_String() { string source = @" using System; class C { void G(Func f) {} void F() { foreach (int x0 in ""1"") // Group #0 { // Group #1 int x1 = 0; G(a => x0); G(a => x1); } } }"; var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyDiagnostics(); // note that the two closures have a different syntax offset c.VerifyPdb("C.F", @" 1 "); } [Fact] public void ForEachStatement_Enumerable() { string source = @" using System; using System.Collections.Generic; class C { void G(Func f) {} void F() { foreach (int x0 in new List()) // Group #0 { // Group #1 int x1 = 0; G(a => x0); G(a => x1); } } }"; var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyDiagnostics(); // note that the two closures have a different syntax offset c.VerifyPdb("C.F", @" 1 "); } [Fact] public void ForStatement1() { string source = @" using System; class C { bool G(Func f) => true; void F() { for (int x0 = 0, x1 = 0; G(a => x0) && G(a => x1);) { int x2 = 0; G(a => x2); } } }"; var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyDiagnostics(); // note that the two closures have a different syntax offset c.VerifyPdb("C.F", @" 1 "); } [Fact] public void SwitchStatement1() { var source = @" using System; class C { bool G(Func f) => true; int a = 1; void F() { int x2 = 1; G(() => x2); switch (a) { case 1: int x0 = 1; G(() => x0); break; case 2: int x1 = 1; G(() => x1); break; } } } "; var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyDiagnostics(); c.VerifyPdb("C.F", @" 2 "); } [Fact] public void UsingStatement1() { string source = @" using System; class C { static bool G(Func f) => true; static int F(object a, object b) => 1; static IDisposable D() => null; static void F() { using (IDisposable x0 = D(), y0 = D()) { int x1 = 1; G(() => x0); G(() => y0); G(() => x1); } } }"; var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); c.VerifyDiagnostics(); // note that the two closures have a different syntax offset c.VerifyPdb("C.F", @" 3 "); } } }