// 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
");
}
}
}