|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Basic.Reference.Assemblies;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.DiaSymReader;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.UnitTests
{
public class LocalsTests : ExpressionCompilerTestBase
{
[Fact]
public void NoLocals()
{
var source =
@"class C
{
static void M()
{
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Equal(0, assembly.Count);
Assert.Equal(0, locals.Count);
locals.Free();
});
}
[Fact]
public void Locals()
{
var source =
@"class C
{
void M(int[] a)
{
string b;
a[1]++;
lock (new C())
{
#line 999
int c = 3;
b = a[c].ToString();
}
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M", atLineNumber: 999);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(4, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //b
C V_1,
bool V_2,
int V_3) //c
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "a", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //b
C V_1,
bool V_2,
int V_3) //c
IL_0000: ldarg.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "b", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //b
C V_1,
bool V_2,
int V_3) //c
IL_0000: ldloc.0
IL_0001: ret
}
");
VerifyLocal(testData, typeName, locals[3], "<>m3", "c", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //b
C V_1,
bool V_2,
int V_3) //c
IL_0000: ldloc.3
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInSwitch()
{
var source =
@"class C
{
void M(object o)
{
switch (o)
{
case string s:
var a = s;
#line 1000
return;
case int s:
#line 2000
return;
default:
return;
}
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(4, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //a
string V_1, //s
int V_2,
object V_3,
object V_4)
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "o", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //a
string V_1, //s
int V_2,
object V_3,
object V_4)
IL_0000: ldarg.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "a", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //a
string V_1, //s
int V_2,
object V_3,
object V_4)
IL_0000: ldloc.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[3], "<>m3", "s", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //a
string V_1, //s
int V_2,
object V_3,
object V_4)
IL_0000: ldloc.1
IL_0001: ret
}");
locals.Free();
context = CreateMethodContext(runtime, "C.M", atLineNumber: 2000);
testData = new CompilationTestData();
locals = ArrayBuilder<LocalAndMethod>.GetInstance();
assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(4, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //a
string V_1,
int V_2, //s
object V_3,
object V_4)
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "o", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //a
string V_1,
int V_2, //s
object V_3,
object V_4)
IL_0000: ldarg.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "a", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //a
string V_1,
int V_2, //s
object V_3,
object V_4)
IL_0000: ldloc.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[3], "<>m3", "s", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //a
string V_1,
int V_2, //s
object V_3,
object V_4)
IL_0000: ldloc.2
IL_0001: ret
}");
locals.Free();
});
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16594")]
public void LocalsInSwitchWithLambda()
{
var source =
@"class C
{
System.Action M(object o)
{
switch (o)
{
case string s:
var a = s;
#line 1000
return () =>
{
#line 2000
System.Console.WriteLine(s + a);
};
case int s:
#line 3000
return () =>
{
#line 4000
System.Console.WriteLine(s);
};
default:
return null;
}
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
object V_1,
object V_2,
System.Action V_3)
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "o", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
object V_1,
object V_2,
System.Action V_3)
IL_0000: ldarg.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "a", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
object V_1,
object V_2,
System.Action V_3)
IL_0000: ldloc.0
IL_0001: ldfld ""string C.<>c__DisplayClass0_0.a""
IL_0006: ret
}");
// We should be able to evaluate "s" within this context, https://github.com/dotnet/roslyn/issues/16594.
// VerifyLocal(testData, typeName, locals[3], "<>m3", "s", expectedILOpt:
//@"{
// // Code size 8 (0x8)
// .maxstack 1
// .locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
// object V_1,
// string V_2,
// int V_3,
// object V_4,
// object V_5,
// int? V_6,
// C.<>c__DisplayClass0_0 V_7, //CS$<>8__locals1
// System.Action V_8,
// C.<>c__DisplayClass0_2 V_9)
// IL_0000: ldloc.s V_7
// IL_0002: ldfld ""string C.<>c__DisplayClass0_0.s""
// IL_0007: ret
//}");
locals.Free();
context = CreateMethodContext(runtime, "C.M", atLineNumber: 3000);
testData = new CompilationTestData();
locals = ArrayBuilder<LocalAndMethod>.GetInstance();
assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
object V_1,
object V_2,
System.Action V_3)
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "o", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
object V_1,
object V_2,
System.Action V_3)
IL_0000: ldarg.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "a", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
object V_1,
object V_2,
System.Action V_3)
IL_0000: ldloc.0
IL_0001: ldfld ""string C.<>c__DisplayClass0_0.a""
IL_0006: ret
}");
// We should be able to evaluate "s" within this context, https://github.com/dotnet/roslyn/issues/16594.
// VerifyLocal(testData, typeName, locals[3], "<>m3", "s", expectedILOpt:
//@"{
// // Code size 8 (0x8)
// .maxstack 1
// .locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
// object V_1,
// string V_2,
// int V_3,
// object V_4,
// object V_5,
// int? V_6,
// C.<>c__DisplayClass0_0 V_7,
// System.Action V_8,
// C.<>c__DisplayClass0_2 V_9) //CS$<>8__locals2
// IL_0000: ldloc.s V_9
// IL_0002: ldfld ""int C.<>c__DisplayClass0_2.s""
// IL_0007: ret
//}");
locals.Free();
context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<M>b__0", atLineNumber: 2000);
testData = new CompilationTestData();
locals = ArrayBuilder<LocalAndMethod>.GetInstance();
assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(1, locals.Count);
// We should be able to evaluate "s" within this context, https://github.com/dotnet/roslyn/issues/16594.
// VerifyLocal(testData, typeName, locals[0], "<>m0", "s", expectedILOpt:
//@"{
// // Code size 7 (0x7)
// .maxstack 1
// IL_0000: ldarg.0
// IL_0001: ldfld ""string C.<>c__DisplayClass0_0.s""
// IL_0006: ret
//}");
VerifyLocal(testData, typeName, locals[0], "<>m0", "a", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""string C.<>c__DisplayClass0_0.a""
IL_0006: ret
}");
locals.Free();
context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<M>b__1", atLineNumber: 4000);
testData = new CompilationTestData();
locals = ArrayBuilder<LocalAndMethod>.GetInstance();
assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(1, locals.Count);
// We should be able to evaluate "s" within this context, https://github.com/dotnet/roslyn/issues/16594.
// VerifyLocal(testData, typeName, locals[0], "<>m0", "s", expectedILOpt:
//@"{
// // Code size 7 (0x7)
// .maxstack 1
// IL_0000: ldarg.0
// IL_0001: ldfld ""int C.<>c__DisplayClass0_2.s""
// IL_0006: ret
//}");
VerifyLocal(testData, typeName, locals[0], "<>m0", "a", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""string C.<>c__DisplayClass0_0.a""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInSwitchWithAwait()
{
var source =
@"
using System.Threading.Tasks;
class C
{
async Task<object> F()
{
return new object();
}
async Task<object> M(object o)
{
switch (o)
{
case string s:
var a = s;
#line 1000
await F();
System.Console.WriteLine(s + a);
return o;
case int s:
#line 2000
await F();
System.Console.WriteLine(s);
return o;
default:
return o;
}
}
}";
var compilation0 = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll,
references: new[] { SystemRef_v4_0_30319_17929, SystemCoreRef_v4_0_30319_17929, CSharpRef });
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>d__1.MoveNext", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(4, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
C.<M>d__1 V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
System.Exception V_6)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<M>d__1.<>4__this""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "o", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
C.<M>d__1 V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
System.Exception V_6)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<M>d__1.o""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "a", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
C.<M>d__1 V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
System.Exception V_6)
IL_0000: ldarg.0
IL_0001: ldfld ""string C.<M>d__1.<a>5__1""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[3], "<>m3", "s", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
C.<M>d__1 V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
System.Exception V_6)
IL_0000: ldarg.0
IL_0001: ldfld ""string C.<M>d__1.<s>5__2""
IL_0006: ret
}");
locals.Free();
context = CreateMethodContext(runtime, "C.<M>d__1.MoveNext", atLineNumber: 2000);
testData = new CompilationTestData();
locals = ArrayBuilder<LocalAndMethod>.GetInstance();
assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(4, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
C.<M>d__1 V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
System.Exception V_6)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<M>d__1.<>4__this""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "o", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
C.<M>d__1 V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
System.Exception V_6)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<M>d__1.o""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "a", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
C.<M>d__1 V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
System.Exception V_6)
IL_0000: ldarg.0
IL_0001: ldfld ""string C.<M>d__1.<a>5__1""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[3], "<>m3", "s", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
object V_1,
object V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
C.<M>d__1 V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
System.Exception V_6)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<M>d__1.<s>5__3""
IL_0006: ret
}");
locals.Free();
});
}
/// <summary>
/// No local signature (debugging a .dmp with no heap). Local
/// names are known but types are not so the locals are dropped.
/// Expressions that do not involve locals can be evaluated however.
/// </summary>
[Fact]
public void NoLocalSignature()
{
var source =
@"class C
{
void M(int[] a)
{
string b;
a[1]++;
lock (new C())
{
#line 999
int c = 3;
b = a[c].ToString();
}
}
}";
var comp = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(comp, references: null, includeLocalSignatures: false, includeIntrinsicAssembly: true, validator: runtime =>
{
var context = CreateMethodContext(
runtime,
methodName: "C.M",
atLineNumber: 999);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "a", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}");
locals.Free();
string error;
testData = new CompilationTestData();
context.CompileExpression("b", out error, testData);
Assert.Equal("error CS0103: The name 'b' does not exist in the current context", error);
testData = new CompilationTestData();
context.CompileExpression("a[1]", out error, testData);
string actualIL = testData.GetMethodData("<>x.<>m0").GetMethodIL();
AssertEx.AssertEqualToleratingWhitespaceDifferences(actualIL,
@"{
// Code size 4 (0x4)
.maxstack 2
IL_0000: ldarg.1
IL_0001: ldc.i4.1
IL_0002: ldelem.i4
IL_0003: ret
}");
});
}
[ConditionalFact(typeof(IsRelease), Reason = "https://github.com/dotnet/roslyn/issues/25702")]
public void LocalsAndPseudoVariables()
{
var source =
@"class C
{
void M(object o)
{
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var aliases = ImmutableArray.Create(
ExceptionAlias(typeof(System.IO.IOException)),
ReturnValueAlias(2, typeof(string)),
ReturnValueAlias(),
ObjectIdAlias(2, typeof(bool)),
VariableAlias("o", "C"));
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var diagnostics = DiagnosticBag.GetInstance();
var testData = new CompilationTestData();
context.CompileGetLocals(
locals,
argumentsOnly: true,
aliases: aliases,
diagnostics: diagnostics,
typeName: out typeName,
testData: testData);
Assert.Equal(1, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "o");
locals.Clear();
testData = new CompilationTestData();
context.CompileGetLocals(
locals,
argumentsOnly: false,
aliases: aliases,
diagnostics: diagnostics,
typeName: out typeName,
testData: testData);
diagnostics.Free();
Assert.Equal(6, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "$exception", "Error", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt:
@"{
// Code size 11 (0xb)
.maxstack 1
IL_0000: call ""System.Exception Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetException()""
IL_0005: castclass ""System.IO.IOException""
IL_000a: ret
}");
// $ReturnValue is suppressed since it always matches the last $ReturnValueN
VerifyLocal(testData, typeName, locals[1], "<>m1", "$ReturnValue2", "Method M2 returned", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt:
@"{
// Code size 12 (0xc)
.maxstack 1
IL_0000: ldc.i4.2
IL_0001: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetReturnValue(int)""
IL_0006: castclass ""string""
IL_000b: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "$2", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt:
@"{
// Code size 16 (0x10)
.maxstack 1
IL_0000: ldstr ""$2""
IL_0005: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)""
IL_000a: unbox.any ""bool""
IL_000f: ret
}");
VerifyLocal(testData, typeName, locals[3], "<>m3", "o", expectedILOpt:
@"{
// Code size 16 (0x10)
.maxstack 1
IL_0000: ldstr ""o""
IL_0005: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)""
IL_000a: castclass ""C""
IL_000f: ret
}");
VerifyLocal(testData, typeName, locals[4], "<>m4", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[5], "<>m5", "o", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}");
locals.Free();
// Confirm that the Watch window is unaffected by the filtering in the Locals window.
string error;
context.CompileExpression("$ReturnValue", DkmEvaluationFlags.TreatAsExpression, aliases, out error);
Assert.Null(error);
});
}
[Fact]
public void This()
{
var source =
@"class C
{
void M(object @this)
{
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "@this", expectedILOpt: // Native EE uses "this" rather than "@this".
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void ArgumentsOnly()
{
var source =
@"class C
{
void M<T>(T x)
{
object y = x;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: true, typeName: out typeName, testData: testData);
Assert.Equal(1, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0<T>", "x", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (object V_0) //y
IL_0000: ldarg.1
IL_0001: ret
}",
expectedGeneric: true);
locals.Free();
});
}
/// <summary>
/// Compiler-generated locals should be ignored.
/// </summary>
[Fact]
public void CompilerGeneratedLocals()
{
var source =
@"class C
{
static bool F(object[] args)
{
if (args == null)
{
return true;
}
foreach (var o in args)
{
#line 999
}
((System.Func<object>)(() => args[0]))();
return false;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.F", atLineNumber: 999);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "args", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
bool V_1,
bool V_2,
object[] V_3,
int V_4,
object V_5) //o
IL_0000: ldloc.0
IL_0001: ldfld ""object[] C.<>c__DisplayClass0_0.args""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "o", expectedILOpt:
@"{
// Code size 3 (0x3)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
bool V_1,
bool V_2,
object[] V_3,
int V_4,
object V_5) //o
IL_0000: ldloc.s V_5
IL_0002: ret
}");
locals.Free();
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/928113")]
public void Constants()
{
var source =
@"class C
{
const int x = 2;
static int F(int w)
{
#line 888
w.ToString(); // Force a non-hidden sequence point.
const int y = 3;
const object v = null;
if ((v == null) || (w < 2))
{
const string z = ""str"";
#line 999
string u = z;
w += z.Length;
}
return w + x + y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.F", atLineNumber: 888);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "w");
VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt: @"
{
// Code size 2 (0x2)
.maxstack 1
.locals init (bool V_0,
string V_1,
int V_2)
IL_0000: ldc.i4.3
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "v", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt: @"
{
// Code size 2 (0x2)
.maxstack 1
.locals init (bool V_0,
string V_1,
int V_2)
IL_0000: ldnull
IL_0001: ret
}");
locals.Free();
context = CreateMethodContext(
runtime,
methodName: "C.F",
atLineNumber: 999);
testData = new CompilationTestData();
locals = ArrayBuilder<LocalAndMethod>.GetInstance();
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(5, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "w");
VerifyLocal(testData, typeName, locals[1], "<>m1", "u");
VerifyLocal(testData, typeName, locals[2], "<>m2", "y", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult);
VerifyLocal(testData, typeName, locals[3], "<>m3", "v", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult);
VerifyLocal(testData, typeName, locals[4], "<>m4", "z", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt:
@"{
// Code size 6 (0x6)
.maxstack 1
.locals init (bool V_0,
string V_1, //u
int V_2)
IL_0000: ldstr ""str""
IL_0005: ret
}");
locals.Free();
});
}
[Fact]
public void ConstantEnum()
{
var source =
@"enum E { A, B }
class C
{
static void M(E x)
{
const E y = E.B;
}
static void Main()
{
M(E.A);
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugExe);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(2, locals.Count);
var method = (MethodSymbol)testData.GetMethodData("<>x.<>m0").Method;
Assert.Equal(method.Parameters[0].Type, method.ReturnType);
VerifyLocal(testData, "<>x", locals[0], "<>m0", "x", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ret
}");
method = (MethodSymbol)testData.GetMethodData("<>x.<>m1").Method;
Assert.Equal(method.Parameters[0].Type, method.ReturnType);
VerifyLocal(testData, "<>x", locals[1], "<>m1", "y", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldc.i4.1
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void ConstantEnumAndTypeParameter()
{
var source =
@"class C<T>
{
enum E { A }
internal static void M<U>() where U : T
{
const C<T>.E t = E.A;
const C<U>.E u = 0;
}
}
class P
{
static void Main()
{
C<object>.M<string>();
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugExe);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, "<>x<T>", locals[0], "<>m0<U>", "t", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldc.i4.0
IL_0001: ret
}",
expectedGeneric: true);
VerifyLocal(testData, "<>x<T>", locals[1], "<>m1<U>", "u", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldc.i4.0
IL_0001: ret
}",
expectedGeneric: true);
VerifyLocal(testData, "<>x<T>", locals[2], "<>m2<U>", "<>TypeVariables", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt:
@"{
// Code size 6 (0x6)
.maxstack 1
IL_0000: newobj ""<>c__TypeVariables<T, U>..ctor()""
IL_0005: ret
}",
expectedGeneric: true);
testData.GetMethodData("<>c__TypeVariables<T, U>..ctor").VerifyIL(
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
public void CapturedLocalsOutsideLambda()
{
var source =
@"class C
{
static void F(System.Func<object> f)
{
}
void M(C x)
{
var y = new C();
F(() => x ?? y ?? this);
if (x != null)
{
#line 999
var z = 6;
var w = 7;
F(() => y ?? (object)w);
}
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(
runtime,
methodName: "C.M",
atLineNumber: 999);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass1_0 V_0, //CS$<>8__locals0
bool V_1,
C.<>c__DisplayClass1_1 V_2, //CS$<>8__locals1
int V_3) //z
IL_0000: ldloc.0
IL_0001: ldfld ""C C.<>c__DisplayClass1_0.<>4__this""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass1_0 V_0, //CS$<>8__locals0
bool V_1,
C.<>c__DisplayClass1_1 V_2, //CS$<>8__locals1
int V_3) //z
IL_0000: ldloc.0
IL_0001: ldfld ""C C.<>c__DisplayClass1_0.x""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "z", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass1_0 V_0, //CS$<>8__locals0
bool V_1,
C.<>c__DisplayClass1_1 V_2, //CS$<>8__locals1
int V_3) //z
IL_0000: ldloc.3
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[3], "<>m3", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass1_0 V_0, //CS$<>8__locals0
bool V_1,
C.<>c__DisplayClass1_1 V_2, //CS$<>8__locals1
int V_3) //z
IL_0000: ldloc.0
IL_0001: ldfld ""C C.<>c__DisplayClass1_0.y""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[4], "<>m4", "w", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass1_0 V_0, //CS$<>8__locals0
bool V_1,
C.<>c__DisplayClass1_1 V_2, //CS$<>8__locals1
int V_3) //z
IL_0000: ldloc.2
IL_0001: ldfld ""int C.<>c__DisplayClass1_1.w""
IL_0006: ret
}");
Assert.Equal(5, locals.Count);
locals.Free();
});
}
[Fact]
public void CapturedLocalsInsideLambda()
{
var source =
@"class C
{
static void F(System.Func<object, object> f)
{
f(null);
}
void M()
{
var x = new object();
F(_1 =>
{
var y = new object();
F(_2 => y);
return x ?? this;
});
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass1_0.<M>b__0");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass1_1 V_0, //CS$<>8__locals0
object V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<>c__DisplayClass1_0.<>4__this""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "_1", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass1_1 V_0, //CS$<>8__locals0
object V_1)
IL_0000: ldarg.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "x", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass1_1 V_0, //CS$<>8__locals0
object V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<>c__DisplayClass1_0.x""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[3], "<>m3", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass1_1 V_0, //CS$<>8__locals0
object V_1)
IL_0000: ldloc.0
IL_0001: ldfld ""object C.<>c__DisplayClass1_1.y""
IL_0006: ret
}");
Assert.Equal(4, locals.Count);
locals.Free();
});
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18273")]
public void CapturedLocalInNestedLambda()
{
var source = @"
using System;
class C
{
void M() { }
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
context.CompileExpression("new Action(() => { int x; new Func<int>(() => x).Invoke(); }).Invoke()", out var error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
// Code size 37 (0x25)
.maxstack 2
IL_0000: ldsfld ""System.Action <>x.<>c.<>9__0_0""
IL_0005: dup
IL_0006: brtrue.s IL_001f
IL_0008: pop
IL_0009: ldsfld ""<>x.<>c <>x.<>c.<>9""
IL_000e: ldftn ""void <>x.<>c.<<>m0>b__0_0()""
IL_0014: newobj ""System.Action..ctor(object, System.IntPtr)""
IL_0019: dup
IL_001a: stsfld ""System.Action <>x.<>c.<>9__0_0""
IL_001f: callvirt ""void System.Action.Invoke()""
IL_0024: ret
}");
});
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18273")]
public void CapturedLocalInNestedLocalFunction()
{
var source = @"
using System;
class C
{
void M() { }
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
context.CompileExpression(
@"new Action<int>(x =>
{
int y;
int F() => x + y;
F();
}).Invoke(1)",
out var error,
testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
// Code size 38 (0x26)
.maxstack 2
IL_0000: ldsfld ""System.Action<int> <>x.<>c.<>9__0_0""
IL_0005: dup
IL_0006: brtrue.s IL_001f
IL_0008: pop
IL_0009: ldsfld ""<>x.<>c <>x.<>c.<>9""
IL_000e: ldftn ""void <>x.<>c.<<>m0>b__0_0(int)""
IL_0014: newobj ""System.Action<int>..ctor(object, System.IntPtr)""
IL_0019: dup
IL_001a: stsfld ""System.Action<int> <>x.<>c.<>9__0_0""
IL_001f: ldc.i4.1
IL_0020: callvirt ""void System.Action<int>.Invoke(int)""
IL_0025: ret
}");
});
}
[Fact]
public void RefReadOnlyLocalFunction()
{
var source = @"
using System;
class C
{
void M() { }
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
context.CompileExpression(
@"new Action(() =>
{
int y = 0;
ref readonly int F(ref int x) => ref x;
F(ref y);
}).Invoke()",
out var error,
testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
// Code size 37 (0x25)
.maxstack 2
IL_0000: ldsfld ""System.Action <>x.<>c.<>9__0_0""
IL_0005: dup
IL_0006: brtrue.s IL_001f
IL_0008: pop
IL_0009: ldsfld ""<>x.<>c <>x.<>c.<>9""
IL_000e: ldftn ""void <>x.<>c.<<>m0>b__0_0()""
IL_0014: newobj ""System.Action..ctor(object, System.IntPtr)""
IL_0019: dup
IL_001a: stsfld ""System.Action <>x.<>c.<>9__0_0""
IL_001f: callvirt ""void System.Action.Invoke()""
IL_0024: ret
}");
});
}
[Fact]
public void NestedLambdas()
{
var source =
@"using System;
class C
{
static void Main()
{
Func<object, object, object, object, Func<object, object, object, Func<object, object, Func<object, object>>>> f = (x1, x2, x3, x4) =>
{
if (x1 == null) return null;
return (y1, y2, y3) =>
{
if ((y1 ?? x2) == null) return null;
return (z1, z2) =>
{
if ((z1 ?? y2 ?? x3) == null) return null;
return w1 =>
{
if ((z2 ?? y3 ?? x4) == null) return null;
return w1;
};
};
};
};
f(1, 2, 3, 4)(5, 6, 7)(8, 9)(10);
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c.<Main>b__0_0");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x1");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x2", expectedILOpt:
@"
{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
bool V_1,
System.Func<object, object, object, System.Func<object, object, System.Func<object, object>>> V_2)
IL_0000: ldloc.0
IL_0001: ldfld ""object C.<>c__DisplayClass0_0.x2""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "x3");
VerifyLocal(testData, typeName, locals[3], "<>m3", "x4");
Assert.Equal(4, locals.Count);
locals.Free();
context = CreateMethodContext(
runtime,
methodName: "C.<>c__DisplayClass0_0.<Main>b__1");
testData = new CompilationTestData();
locals = ArrayBuilder<LocalAndMethod>.GetInstance();
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "y1");
VerifyLocal(testData, typeName, locals[1], "<>m1", "y2", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
bool V_1,
System.Func<object, object, System.Func<object, object>> V_2)
IL_0000: ldloc.0
IL_0001: ldfld ""object C.<>c__DisplayClass0_1.y2""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "y3");
VerifyLocal(testData, typeName, locals[3], "<>m3", "x2");
VerifyLocal(testData, typeName, locals[4], "<>m4", "x3", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
bool V_1,
System.Func<object, object, System.Func<object, object>> V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<>c__DisplayClass0_0.x3""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[5], "<>m5", "x4");
Assert.Equal(6, locals.Count);
locals.Free();
context = CreateMethodContext(
runtime,
methodName: "C.<>c__DisplayClass0_1.<Main>b__2");
testData = new CompilationTestData();
locals = ArrayBuilder<LocalAndMethod>.GetInstance();
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "z1");
VerifyLocal(testData, typeName, locals[1], "<>m1", "z2", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_2 V_0, //CS$<>8__locals0
bool V_1,
System.Func<object, object> V_2)
IL_0000: ldloc.0
IL_0001: ldfld ""object C.<>c__DisplayClass0_2.z2""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "y2");
VerifyLocal(testData, typeName, locals[3], "<>m3", "y3");
VerifyLocal(testData, typeName, locals[4], "<>m4", "x2");
VerifyLocal(testData, typeName, locals[5], "<>m5", "x3", expectedILOpt:
@"{
// Code size 12 (0xc)
.maxstack 1
.locals init (C.<>c__DisplayClass0_2 V_0, //CS$<>8__locals0
bool V_1,
System.Func<object, object> V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""C.<>c__DisplayClass0_0 C.<>c__DisplayClass0_1.CS$<>8__locals1""
IL_0006: ldfld ""object C.<>c__DisplayClass0_0.x3""
IL_000b: ret
}");
VerifyLocal(testData, typeName, locals[6], "<>m6", "x4");
Assert.Equal(7, locals.Count);
locals.Free();
context = CreateMethodContext(
runtime,
methodName: "C.<>c__DisplayClass0_2.<Main>b__3");
testData = new CompilationTestData();
locals = ArrayBuilder<LocalAndMethod>.GetInstance();
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "w1");
VerifyLocal(testData, typeName, locals[1], "<>m1", "z2", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (bool V_0,
object V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<>c__DisplayClass0_2.z2""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "y2");
VerifyLocal(testData, typeName, locals[3], "<>m3", "y3");
VerifyLocal(testData, typeName, locals[4], "<>m4", "x2");
VerifyLocal(testData, typeName, locals[5], "<>m5", "x3");
VerifyLocal(testData, typeName, locals[6], "<>m6", "x4", expectedILOpt:
@"{
// Code size 17 (0x11)
.maxstack 1
.locals init (bool V_0,
object V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""C.<>c__DisplayClass0_1 C.<>c__DisplayClass0_2.CS$<>8__locals2""
IL_0006: ldfld ""C.<>c__DisplayClass0_0 C.<>c__DisplayClass0_1.CS$<>8__locals1""
IL_000b: ldfld ""object C.<>c__DisplayClass0_0.x4""
IL_0010: ret
}");
Assert.Equal(7, locals.Count);
locals.Free();
});
}
/// <summary>
/// Should not include "this" inside display class
/// instance method if "this" is not captured.
/// </summary>
[Theory]
[MemberData(nameof(NonNullTypesTrueAndFalseDebugDll))]
public void NoThisInsideDisplayClassInstanceMethod(CSharpCompilationOptions options)
{
var source =
@"using System;
class C
{
void M<T>(T x) where T : class
{
Func<object, Func<T, object>> f = y =>
{
return z =>
{
return x ?? (object)y ?? z;
};
};
f(2)(x);
}
}";
var compilation0 = CreateCompilation(source, options: options);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<M>b__0");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, "<>x<T>", locals[0], "<>m0", "y");
VerifyLocal(testData, "<>x<T>", locals[1], "<>m1", "x");
VerifyLocal(testData, "<>x<T>", locals[2], "<>m2", "<>TypeVariables", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult);
locals.Free();
context = CreateMethodContext(
runtime,
methodName: "C.<>c__DisplayClass0_1.<M>b__1");
testData = new CompilationTestData();
locals = ArrayBuilder<LocalAndMethod>.GetInstance();
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(4, locals.Count);
VerifyLocal(testData, "<>x<T>", locals[0], "<>m0", "z");
VerifyLocal(testData, "<>x<T>", locals[1], "<>m1", "y");
VerifyLocal(testData, "<>x<T>", locals[2], "<>m2", "x");
VerifyLocal(testData, "<>x<T>", locals[3], "<>m3", "<>TypeVariables", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult);
locals.Free();
});
}
[Fact]
public void GenericMethod()
{
var source =
@"class A<T>
{
struct B<U, V>
{
void M<W>(A<U>.B<V, object>[] o)
{
var t = default(T);
var u = default(U);
var w = default(W);
}
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "A.B.M");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(6, locals.Count);
VerifyLocal(testData, "<>x<T, U, V>", locals[0], "<>m0<W>", "this", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (T V_0, //t
U V_1, //u
W V_2) //w
IL_0000: ldarg.0
IL_0001: ldobj ""A<T>.B<U, V>""
IL_0006: ret
}",
expectedGeneric: true);
var method = (MethodSymbol)testData.GetMethodData("<>x<T, U, V>.<>m0<W>").Method;
var containingType = method.ContainingType;
var returnType = (NamedTypeSymbol)method.ReturnType;
Assert.Equal(containingType.TypeParameters[1], returnType.TypeArguments()[0]);
Assert.Equal(containingType.TypeParameters[2], returnType.TypeArguments()[1]);
returnType = returnType.ContainingType;
Assert.Equal(containingType.TypeParameters[0], returnType.TypeArguments()[0]);
VerifyLocal(testData, "<>x<T, U, V>", locals[1], "<>m1<W>", "o", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (T V_0, //t
U V_1, //u
W V_2) //w
IL_0000: ldarg.1
IL_0001: ret
}",
expectedGeneric: true);
method = (MethodSymbol)testData.GetMethodData("<>x<T, U, V>.<>m1<W>").Method;
// method.ReturnType: A<U>.B<V, object>[]
returnType = (NamedTypeSymbol)((ArrayTypeSymbol)method.ReturnType).ElementType;
Assert.Equal(containingType.TypeParameters[2], returnType.TypeArguments()[0]);
returnType = returnType.ContainingType;
Assert.Equal(containingType.TypeParameters[1], returnType.TypeArguments()[0]);
VerifyLocal(testData, "<>x<T, U, V>", locals[2], "<>m2<W>", "t", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (T V_0, //t
U V_1, //u
W V_2) //w
IL_0000: ldloc.0
IL_0001: ret
}",
expectedGeneric: true);
method = (MethodSymbol)testData.GetMethodData("<>x<T, U, V>.<>m2<W>").Method;
containingType = method.ContainingType;
Assert.Equal(containingType.TypeParameters[0], method.ReturnType);
VerifyLocal(testData, "<>x<T, U, V>", locals[3], "<>m3<W>", "u", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (T V_0, //t
U V_1, //u
W V_2) //w
IL_0000: ldloc.1
IL_0001: ret
}",
expectedGeneric: true);
method = (MethodSymbol)testData.GetMethodData("<>x<T, U, V>.<>m3<W>").Method;
containingType = method.ContainingType;
Assert.Equal(containingType.TypeParameters[1], method.ReturnType);
VerifyLocal(testData, "<>x<T, U, V>", locals[4], "<>m4<W>", "w", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (T V_0, //t
U V_1, //u
W V_2) //w
IL_0000: ldloc.2
IL_0001: ret
}",
expectedGeneric: true);
method = (MethodSymbol)testData.GetMethodData("<>x<T, U, V>.<>m4<W>").Method;
Assert.Equal(method.TypeParameters[0], method.ReturnType);
VerifyLocal(testData, "<>x<T, U, V>", locals[5], "<>m5<W>", "<>TypeVariables", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt:
@"{
// Code size 6 (0x6)
.maxstack 1
.locals init (T V_0, //t
U V_1, //u
W V_2) //w
IL_0000: newobj ""<>c__TypeVariables<T, U, V, W>..ctor()""
IL_0005: ret
}",
expectedGeneric: true);
method = (MethodSymbol)testData.GetMethodData("<>x<T, U, V>.<>m5<W>").Method;
returnType = (NamedTypeSymbol)method.ReturnType;
Assert.Equal(containingType.TypeParameters[0], returnType.TypeArguments()[0]);
Assert.Equal(containingType.TypeParameters[1], returnType.TypeArguments()[1]);
Assert.Equal(containingType.TypeParameters[2], returnType.TypeArguments()[2]);
Assert.Equal(method.TypeParameters[0], returnType.TypeArguments()[3]);
// Verify <>c__TypeVariables type was emitted (#976772).
using (var metadata = ModuleMetadata.CreateFromImage(ImmutableArray.CreateRange(assembly)))
{
var reader = metadata.MetadataReader;
var typeDef = reader.GetTypeDef("<>c__TypeVariables");
reader.CheckTypeParameters(typeDef.GetGenericParameters(), "T", "U", "V", "W");
}
locals.Free();
});
}
[Fact]
public void GenericLambda()
{
var source =
@"class C<T> where T : class
{
static void M<U>(T t)
{
var u = default(U);
System.Func<object> f = () => { return t ?? (object)u; };
f();
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<M>b__0");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, "<>x<T, U>", locals[0], "<>m0", "t");
VerifyLocal(testData, "<>x<T, U>", locals[1], "<>m1", "u", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (object V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""U C<T>.<>c__DisplayClass0_0<U>.u""
IL_0006: ret
}",
expectedGeneric: false);
VerifyLocal(testData, "<>x<T, U>", locals[2], "<>m2", "<>TypeVariables", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult);
var method = (MethodSymbol)testData.GetMethodData("<>x<T, U>.<>m1").Method;
var containingType = method.ContainingType;
Assert.Equal(containingType.TypeParameters[1], method.ReturnType);
locals.Free();
});
}
[Fact]
public void Iterator_InstanceMethod()
{
var source =
@"using System.Collections;
class C
{
private readonly object[] c;
internal C(object[] c)
{
this.c = c;
}
internal IEnumerable F()
{
foreach (var o in c)
{
#line 999
yield return o;
}
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<F>d__2.MoveNext", atLineNumber: 999);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, "<>x", locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<F>d__2.<>4__this""
IL_0006: ret
}");
VerifyLocal(testData, "<>x", locals[1], "<>m1", "o", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<F>d__2.<o>5__3""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
public void Iterator_StaticMethod_Generic()
{
var source =
@"using System.Collections.Generic;
class C
{
static IEnumerable<T> F<T>(T[] o)
{
for (int i = 0; i < o.Length; i++)
{
#line 999
T t = default(T);
yield return t;
yield return o[i];
}
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(
runtime,
methodName: "C.<F>d__0.MoveNext",
atLineNumber: 999);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, "<>x<T>", locals[0], "<>m0", "o", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
int V_1,
bool V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""T[] C.<F>d__0<T>.o""
IL_0006: ret
}");
VerifyLocal(testData, "<>x<T>", locals[1], "<>m1", "i", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
int V_1,
bool V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<F>d__0<T>.<i>5__1""
IL_0006: ret
}");
VerifyLocal(testData, "<>x<T>", locals[2], "<>m2", "t", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
int V_1,
bool V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""T C.<F>d__0<T>.<t>5__2""
IL_0006: ret
}");
VerifyLocal(testData, "<>x<T>", locals[3], "<>m3", "<>TypeVariables", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult);
Assert.Equal(4, locals.Count);
locals.Free();
});
}
[Fact]
public void Async_InstanceMethod_Generic()
{
var source =
@"using System.Threading.Tasks;
struct S<T> where T : class
{
T x;
internal async Task<object> F<U>(U y) where U : class
{
var z = default(T);
return this.x ?? (object)y ?? z;
}
}";
var compilation0 = CreateCompilationWithMscorlib45(
source,
options: TestOptions.DebugDll,
references: new[] { SystemRef_v4_0_30319_17929, SystemCoreRef_v4_0_30319_17929, CSharpRef });
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "S.<F>d__1.MoveNext");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, "<>x<T, U>", locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
object V_1,
System.Exception V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""S<T> S<T>.<F>d__1<U>.<>4__this""
IL_0006: ret
}");
VerifyLocal(testData, "<>x<T, U>", locals[1], "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
object V_1,
System.Exception V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""U S<T>.<F>d__1<U>.y""
IL_0006: ret
}");
VerifyLocal(testData, "<>x<T, U>", locals[2], "<>m2", "z", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
object V_1,
System.Exception V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""T S<T>.<F>d__1<U>.<z>5__1""
IL_0006: ret
}");
VerifyLocal(testData, "<>x<T, U>", locals[3], "<>m3", "<>TypeVariables", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult);
Assert.Equal(4, locals.Count);
locals.Free();
});
}
[Fact]
public void Async_StaticMethod_01()
{
var source =
@"using System.Threading.Tasks;
class C
{
static async Task<object> F(object o)
{
return o;
}
static async Task M(object x)
{
var y = await F(x);
await F(y);
}
}";
var compilation0 = CreateCompilationWithMscorlib45(
source,
options: TestOptions.DebugDll,
references: new[] { SystemRef_v4_0_30319_17929, SystemCoreRef_v4_0_30319_17929, CSharpRef });
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>d__1.MoveNext");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, "<>x", locals[0], "<>m0", "x", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Runtime.CompilerServices.TaskAwaiter<object> V_1,
C.<M>d__1 V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
System.Exception V_4)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<M>d__1.x""
IL_0006: ret
}");
VerifyLocal(testData, "<>x", locals[1], "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Runtime.CompilerServices.TaskAwaiter<object> V_1,
C.<M>d__1 V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
System.Exception V_4)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<M>d__1.<y>5__1""
IL_0006: ret
}");
Assert.Equal(2, locals.Count);
locals.Free();
});
}
[Fact]
public void Async_StaticMethod_02()
{
var source =
@"using System.Threading.Tasks;
class C
{
static async Task<object> F(object o)
{
return o;
}
static async Task M(object x)
{
{
#line 1000
int y = (int)await F(x);
await F(y);
}
{
#line 2000
long y = (long)await F(x);
await F(y);
}
}
}";
var compilation0 = CreateCompilationWithMscorlib45(
source,
options: TestOptions.DebugDll,
references: new[] { SystemRef_v4_0_30319_17929, SystemCoreRef_v4_0_30319_17929, CSharpRef });
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>d__1.MoveNext", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, "<>x", locals[0], "<>m0", "x", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Runtime.CompilerServices.TaskAwaiter<object> V_1,
C.<M>d__1 V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
System.Runtime.CompilerServices.TaskAwaiter<object> V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
System.Exception V_6)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<M>d__1.x""
IL_0006: ret
}");
VerifyLocal(testData, "<>x", locals[1], "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Runtime.CompilerServices.TaskAwaiter<object> V_1,
C.<M>d__1 V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
System.Runtime.CompilerServices.TaskAwaiter<object> V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
System.Exception V_6)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<M>d__1.<y>5__1""
IL_0006: ret
}");
Assert.Equal(2, locals.Count);
locals.Free();
context = CreateMethodContext(runtime, "C.<M>d__1.MoveNext", atLineNumber: 2000);
testData = new CompilationTestData();
locals = ArrayBuilder<LocalAndMethod>.GetInstance();
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, "<>x", locals[0], "<>m0", "x", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Runtime.CompilerServices.TaskAwaiter<object> V_1,
C.<M>d__1 V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
System.Runtime.CompilerServices.TaskAwaiter<object> V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
System.Exception V_6)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<M>d__1.x""
IL_0006: ret
}
");
VerifyLocal(testData, "<>x", locals[1], "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Runtime.CompilerServices.TaskAwaiter<object> V_1,
C.<M>d__1 V_2,
System.Runtime.CompilerServices.TaskAwaiter<object> V_3,
System.Runtime.CompilerServices.TaskAwaiter<object> V_4,
System.Runtime.CompilerServices.TaskAwaiter<object> V_5,
System.Exception V_6)
IL_0000: ldarg.0
IL_0001: ldfld ""long C.<M>d__1.<y>5__3""
IL_0006: ret
}");
Assert.Equal(2, locals.Count);
locals.Free();
});
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/10649")]
[WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/995976")]
public void AsyncAndLambda()
{
var source =
@"using System;
using System.Threading.Tasks;
class C
{
static async Task F()
{
}
static void G(Action a)
{
a();
}
async static Task<int> M(int x)
{
int y = x + 1;
await F();
G(() => { x += 2; y += 2; });
x += y;
return x;
}
}";
var compilation0 = CreateCompilationWithMscorlib45(
source,
options: TestOptions.DebugDll,
references: new[] { SystemRef_v4_0_30319_17929, SystemCoreRef_v4_0_30319_17929, CSharpRef });
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>d__2.MoveNext");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, "<>x", locals[0], "<>m0", "x", expectedILOpt:
@"{
// Code size 12 (0xc)
.maxstack 1
.locals init (int V_0,
int V_1,
System.Runtime.CompilerServices.TaskAwaiter V_2,
C.<M>d__2 V_3,
System.Exception V_4)
IL_0000: ldarg.0
IL_0001: ldfld ""C.<>c__DisplayClass2_0 C.<M>d__2.<>8__1""
IL_0006: ldfld ""int C.<>c__DisplayClass2_0.x""
IL_000b: ret
}");
VerifyLocal(testData, "<>x", locals[1], "<>m1", "y", expectedILOpt:
@"{
// Code size 12 (0xc)
.maxstack 1
.locals init (int V_0,
int V_1,
System.Runtime.CompilerServices.TaskAwaiter V_2,
C.<M>d__2 V_3,
System.Exception V_4)
IL_0000: ldarg.0
IL_0001: ldfld ""C.<>c__DisplayClass2_0 C.<M>d__2.<>8__1""
IL_0006: ldfld ""int C.<>c__DisplayClass2_0.y""
IL_000b: ret
}");
locals.Free();
});
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/2240")]
public void AsyncLambda()
{
var source =
@"using System;
using System.Threading.Tasks;
class C
{
static void M()
{
Func<int, Task> f = async (x) =>
{
var y = 42;
};
}
}";
var compilation0 = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, methodName: "C.<>c.<<M>b__0_0>d.MoveNext");
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var testData = new CompilationTestData();
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, "<>x", locals[0], "<>m0", "x", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Exception V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c.<<M>b__0_0>d.x""
IL_0006: ret
}");
VerifyLocal(testData, "<>x", locals[1], "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Exception V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c.<<M>b__0_0>d.<y>5__1""
IL_0006: ret
}");
locals.Free();
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/996571")]
public void MissingReference()
{
var source0 =
@"public class A
{
}
public struct B
{
}";
var source1 =
@"class C
{
static void M(A a, B b, C c)
{
}
}";
var compilation0 = CreateCompilation(
source0,
options: TestOptions.DebugDll,
assemblyName: "Comp1");
var compilation1 = CreateCompilation(
source1,
options: TestOptions.DebugDll,
references: new[] { compilation0.EmitToImageReference() });
// no reference to compilation0
WithRuntimeInstance(compilation1, new[] { MscorlibRef }, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData, expectedDiagnostics: new[]
{
// error CS0012: The type 'A' is defined in an assembly that is not referenced. You must add a reference to assembly 'Comp1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
Diagnostic(ErrorCode.ERR_NoTypeDef).WithArguments("A", "Comp1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 1)
});
Assert.Equal(0, locals.Count);
locals.Free();
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/996571")]
public void MissingReference_2()
{
var source0 =
@"public interface I
{
}";
var source1 =
@"class C
{
static void M<T>(object o) where T : I
{
}
}";
var compilation0 = CreateCompilation(
source0,
options: TestOptions.DebugDll,
assemblyName: "Comp1");
var compilation1 = CreateCompilation(
source1,
options: TestOptions.DebugDll,
references: new[] { compilation0.EmitToImageReference() });
// no reference to compilation0
WithRuntimeInstance(compilation1, new[] { MscorlibRef }, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData, expectedDiagnostics: new[]
{
// error CS0012: The type 'I' is defined in an assembly that is not referenced. You must add a reference to assembly 'Comp1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
Diagnostic(ErrorCode.ERR_NoTypeDef).WithArguments("I", "Comp1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 1)
});
Assert.Equal(0, locals.Count);
locals.Free();
});
}
[Fact]
public void AssignmentToLockLocal()
{
var source = @"
class C
{
void M(object o)
{
lock(o)
{
#line 999
int x = 1;
}
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(
runtime,
methodName: "C.M",
atLineNumber: 999);
string error;
var testData = new CompilationTestData();
context.CompileExpression("o = null", out error, testData);
Assert.Null(error); // In regular code, there would be an error about modifying a lock local.
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
// Code size 5 (0x5)
.maxstack 2
.locals init (object V_0,
bool V_1,
int V_2) //x
IL_0000: ldnull
IL_0001: dup
IL_0002: starg.s V_1
IL_0004: ret
}");
testData = new CompilationTestData();
context.CompileAssignment("o", "null", out error, testData);
Assert.Null(error); // In regular code, there would be an error about modifying a lock local.
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
// Code size 4 (0x4)
.maxstack 1
.locals init (object V_0,
bool V_1,
int V_2) //x
IL_0000: ldnull
IL_0001: starg.s V_1
IL_0003: ret
}");
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1015887")]
public void LocalDoubleConstant()
{
var source = @"
class C
{
static void M()
{
const double d = 2.74745778612482E-266;
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(1, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "d", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt:
@"{
// Code size 10 (0xa)
.maxstack 1
IL_0000: ldc.r8 2.74745778612482E-266
IL_0009: ret
}");
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1015887")]
public void LocalByteConstant()
{
var source = @"
class C
{
static void M()
{
const byte b = 254;
byte c = 0;
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
string error;
context.CompileAssignment("c", "(byte)(b + 3)", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
// Code size 3 (0x3)
.maxstack 1
.locals init (byte V_0) //c
IL_0000: ldc.i4.1
IL_0001: stloc.0
IL_0002: ret
}
");
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1015887")]
public void LocalDecimalConstant()
{
var source = @"
class C
{
static void M()
{
const decimal d = 1.5M;
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, methodName: "C.M");
string errorMessage;
var testData = new CompilationTestData();
context.CompileAssignment("d", "Nothing", out errorMessage, testData);
Assert.Equal("error CS0131: The left-hand side of an assignment must be a variable, property or indexer", errorMessage);
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(1, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "d", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt:
@"{
// Code size 12 (0xc)
.maxstack 5
IL_0000: ldc.i4.s 15
IL_0002: ldc.i4.0
IL_0003: ldc.i4.0
IL_0004: ldc.i4.0
IL_0005: ldc.i4.1
IL_0006: newobj ""decimal..ctor(int, int, int, bool, byte)""
IL_000b: ret
}");
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1022165"), WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1028883"), WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1034204")]
public void KeywordIdentifiers()
{
var source = @"
class C
{
void M(int @null)
{
int @this = 1;
char @true = 't';
string @namespace = ""NS"";
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(5, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt: @"
{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //this
char V_1, //true
string V_2) //namespace
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "@null", expectedILOpt: @"
{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //this
char V_1, //true
string V_2) //namespace
IL_0000: ldarg.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "@this", expectedILOpt: @"
{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //this
char V_1, //true
string V_2) //namespace
IL_0000: ldloc.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[3], "<>m3", "@true", expectedILOpt: @"
{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //this
char V_1, //true
string V_2) //namespace
IL_0000: ldloc.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[4], "<>m4", "@namespace", expectedILOpt: @"
{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //this
char V_1, //true
string V_2) //namespace
IL_0000: ldloc.2
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void ExtensionIterator()
{
var source = @"
static class C
{
static System.Collections.IEnumerable F(this int x)
{
yield return x;
}
}
";
var expectedIL = @"
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<F>d__0.x""
IL_0006: ret
}";
var compilation0 = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<F>d__0.MoveNext");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(1, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: expectedIL);
Assert.Equal(SpecialType.System_Int32, ((MethodSymbol)testData.GetMethodData(typeName + ".<>m0").Method).ReturnType.SpecialType);
locals.Free();
testData = new CompilationTestData();
string error;
context.CompileExpression("x", out error, testData);
Assert.Null(error);
var methodData = testData.GetMethodData("<>x.<>m0");
methodData.VerifyIL(expectedIL);
Assert.Equal(SpecialType.System_Int32, ((MethodSymbol)methodData.Method).ReturnType.SpecialType);
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1063254")]
public void OverloadedIteratorDifferentParameterTypes_ArgumentsOnly()
{
var source = @"
using System.Collections.Generic;
class C
{
IEnumerable<int> M1(int x, int y)
{
int local = 0;
yield return local;
}
IEnumerable<float> M1(int x, float y)
{
float local = 0.0F;
yield return local;
}
static IEnumerable<float> M2(int x, float y)
{
float local = 0;
yield return local;
}
static IEnumerable<T> M2<T>(int x, T y)
{
T local = default(T);
yield return local;
}
static IEnumerable<int> M2(int x, int y)
{
int local = 0;
yield return local;
}
}";
var compilation = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation, runtime =>
{
string displayClassName;
string typeName;
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
CompilationTestData testData;
var ilTemplate = @"
{{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""{0} C.{1}.{2}""
IL_0006: ret
}}";
// M1(int, int)
displayClassName = "<M1>d__0";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 2, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: string.Format(ilTemplate, "int", displayClassName, "x"));
VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedILOpt: string.Format(ilTemplate, "int", displayClassName, "y"));
locals.Clear();
// M1(int, float)
displayClassName = "<M1>d__1";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 2, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: string.Format(ilTemplate, "int", displayClassName, "x"));
VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedILOpt: string.Format(ilTemplate, "float", displayClassName, "y"));
locals.Clear();
// M2(int, float)
displayClassName = "<M2>d__2";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 2, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: string.Format(ilTemplate, "int", displayClassName, "x"));
VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedILOpt: string.Format(ilTemplate, "float", displayClassName, "y"));
locals.Clear();
// M2(int, T)
displayClassName = "<M2>d__3";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 2, typeName: out typeName, testData: out testData);
typeName += "<T>";
displayClassName += "<T>";
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: string.Format(ilTemplate, "int", displayClassName, "x"));
VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedILOpt: string.Format(ilTemplate, "T", displayClassName, "y"));
locals.Clear();
// M2(int, int)
displayClassName = "<M2>d__4";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 2, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: string.Format(ilTemplate, "int", displayClassName, "x"));
VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedILOpt: string.Format(ilTemplate, "int", displayClassName, "y"));
locals.Clear();
locals.Free();
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1063254")]
public void OverloadedAsyncDifferentParameterTypes_ArgumentsOnly()
{
var source = @"
using System.Threading.Tasks;
class C
{
async Task<int> M1(int x)
{
int local = 0;
return local;
}
async Task<float> M1(int x, float y)
{
float local = 0.0F;
return local;
}
static async Task<float> M2(int x, float y)
{
float local = 0;
return local;
}
static async Task<T> M2<T>(T x)
{
T local = default(T);
return local;
}
static async Task<int> M2(int x)
{
int local = 0;
return local;
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation, runtime =>
{
string displayClassName;
string typeName;
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
CompilationTestData testData;
var ilTemplate = @"
{{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
{0} V_1,
System.Exception V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""{1} C.{2}.{3}""
IL_0006: ret
}}";
// M1(int)
displayClassName = "<M1>d__0";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 1, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: string.Format(ilTemplate, "int", "int", displayClassName, "x"));
locals.Clear();
// M1(int, float)
displayClassName = "<M1>d__1";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 2, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: string.Format(ilTemplate, "float", "int", displayClassName, "x"));
VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedILOpt: string.Format(ilTemplate, "float", "float", displayClassName, "y"));
locals.Clear();
// M2(int, float)
displayClassName = "<M2>d__2";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 2, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: string.Format(ilTemplate, "float", "int", displayClassName, "x"));
VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedILOpt: string.Format(ilTemplate, "float", "float", displayClassName, "y"));
locals.Clear();
// M2(T)
displayClassName = "<M2>d__3";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 1, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName + "<T>", locals[0], "<>m0", "x", expectedILOpt: string.Format(ilTemplate, "T", "T", displayClassName + "<T>", "x"));
locals.Clear();
// M2(int)
displayClassName = "<M2>d__4";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 1, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: string.Format(ilTemplate, "int", "int", displayClassName, "x"));
locals.Clear();
locals.Free();
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1063254")]
public void MultipleLambdasDifferentParameterNames_ArgumentsOnly()
{
var source = @"
using System;
class C
{
void M1(int x)
{
Action<int> a = y => x.ToString();
Func<int, int> f = z => x;
}
static void M2<T>(int x)
{
Action<int> a = y => y.ToString();
Func<int, int> f = z => z;
Func<T, T> g = t => t;
}
}";
var compilation = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation, runtime =>
{
string displayClassName;
string typeName;
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
CompilationTestData testData;
var voidRetILTemplate = @"
{{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.{0}
IL_0001: ret
}}";
var funcILTemplate = @"
{{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.{0}
IL_0001: ret
}}";
// y => x.ToString()
displayClassName = "<>c__DisplayClass0_0";
GetLocals(runtime, "C." + displayClassName + ".<M1>b__0", argumentsOnly: true, locals: locals, count: 1, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "y", expectedILOpt: string.Format(voidRetILTemplate, 1));
locals.Clear();
// z => x
displayClassName = "<>c__DisplayClass0_0";
GetLocals(runtime, "C." + displayClassName + ".<M1>b__1", argumentsOnly: true, locals: locals, count: 1, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "z", expectedILOpt: string.Format(funcILTemplate, 1));
locals.Clear();
// y => y.ToString()
displayClassName = "<>c__1";
GetLocals(runtime, "C." + displayClassName + ".<M2>b__1_0", argumentsOnly: true, locals: locals, count: 1, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName + "<T>", locals[0], "<>m0", "y", expectedILOpt: string.Format(voidRetILTemplate, 1));
locals.Clear();
// z => z
displayClassName = "<>c__1";
GetLocals(runtime, "C." + displayClassName + ".<M2>b__1_1", argumentsOnly: true, locals: locals, count: 1, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName + "<T>", locals[0], "<>m0", "z", expectedILOpt: string.Format(funcILTemplate, 1));
locals.Clear();
// t => t
displayClassName = "<>c__1";
GetLocals(runtime, "C." + displayClassName + ".<M2>b__1_2", argumentsOnly: true, locals: locals, count: 1, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName + "<T>", locals[0], "<>m0", "t", expectedILOpt: string.Format(funcILTemplate, 1));
locals.Clear();
locals.Free();
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1063254")]
public void OverloadedRegularMethodDifferentParameterTypes_ArgumentsOnly()
{
var source = @"
class C
{
void M1(int x, int y)
{
int local = 0;
}
string M1(int x, string y)
{
string local = null;
return local;
}
static void M2(int x, string y)
{
string local = null;
}
static T M2<T>(int x, T y)
{
T local = default(T);
return local;
}
static int M2(int x, ref int y)
{
int local = 0;
return local;
}
}";
var compilation = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation, runtime =>
{
string typeName;
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
CompilationTestData testData;
var voidRetILTemplate = @"
{{
// Code size 2 (0x2)
.maxstack 1
.locals init ({0} V_0) //local
IL_0000: ldarg.{1}
IL_0001: ret
}}";
var funcILTemplate = @"
{{
// Code size 2 (0x2)
.maxstack 1
.locals init ({0} V_0, //local
{0} V_1)
IL_0000: ldarg.{1}
IL_0001: ret
}}";
var refParamILTemplate = @"
{{
// Code size 3 (0x3)
.maxstack 1
.locals init ({0} V_0, //local
{0} V_1)
IL_0000: ldarg.{1}
IL_0001: ldind.i4
IL_0002: ret
}}";
// M1(int, int)
GetLocals(runtime, "C.M1(Int32,Int32)", argumentsOnly: true, locals: locals, count: 2, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: string.Format(voidRetILTemplate, "int", 1));
VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedILOpt: string.Format(voidRetILTemplate, "int", 2));
locals.Clear();
// M1(int, string)
GetLocals(runtime, "C.M1(Int32,String)", argumentsOnly: true, locals: locals, count: 2, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: string.Format(funcILTemplate, "string", 1));
VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedILOpt: string.Format(funcILTemplate, "string", 2));
locals.Clear();
// M2(int, string)
GetLocals(runtime, "C.M2(Int32,String)", argumentsOnly: true, locals: locals, count: 2, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: string.Format(voidRetILTemplate, "string", 0));
VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedILOpt: string.Format(voidRetILTemplate, "string", 1));
locals.Clear();
// M2(int, T)
GetLocals(runtime, "C.M2(Int32,T)", argumentsOnly: true, locals: locals, count: 2, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0<T>", "x", expectedILOpt: string.Format(funcILTemplate, "T", 0), expectedGeneric: true);
VerifyLocal(testData, typeName, locals[1], "<>m1<T>", "y", expectedILOpt: string.Format(funcILTemplate, "T", 1), expectedGeneric: true);
locals.Clear();
// M2(int, int)
GetLocals(runtime, "C.M2(Int32,Int32)", argumentsOnly: true, locals: locals, count: 2, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: string.Format(funcILTemplate, "int", 0));
VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedILOpt: string.Format(refParamILTemplate, "int", 1));
locals.Clear();
locals.Free();
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1063254")]
public void MultipleMethodsLocalConflictsWithParameterName_ArgumentsOnly()
{
var source = @"
using System.Collections.Generic;
using System.Threading.Tasks;
class C<T>
{
IEnumerable<int> M1()
{
int x = 0;
yield return x;
}
IEnumerable<int> M1(int x)
{
yield return x;
}
IEnumerable<int> M2(int x)
{
yield return x;
}
IEnumerable<int> M2()
{
int x = 0;
yield return x;
}
static async Task<T> M3()
{
T x = default(T);
return x;
}
static async Task<T> M3<T>(T x)
{
return x;
}
static async Task<T> M4<T>(T x)
{
return x;
}
static async Task<T> M4()
{
T x = default(T);
return x;
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation, runtime =>
{
string displayClassName;
string typeName;
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
CompilationTestData testData;
var iteratorILTemplate = @"
{{
// Code size 7 (0x7)
.maxstack 1
.locals init ({0} V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""{0} C<T>.{1}.{2}""
IL_0006: ret
}}";
var asyncILTemplate = @"
{{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
{0} V_1,
System.Exception V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""{0} C<T>.{1}.{2}""
IL_0006: ret
}}";
// M1()
displayClassName = "<M1>d__0";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 0, typeName: out typeName, testData: out testData);
locals.Clear();
// M1(int)
displayClassName = "<M1>d__1";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 1, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName + "<T>", locals[0], "<>m0", "x", expectedILOpt: string.Format(iteratorILTemplate, "int", displayClassName, "x"));
locals.Clear();
// M2(int)
displayClassName = "<M2>d__2";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 1, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName + "<T>", locals[0], "<>m0", "x", expectedILOpt: string.Format(iteratorILTemplate, "int", displayClassName, "x"));
locals.Clear();
// M2()
displayClassName = "<M2>d__3";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 0, typeName: out typeName, testData: out testData);
locals.Clear();
// M3()
displayClassName = "<M3>d__4";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 0, typeName: out typeName, testData: out testData);
locals.Clear();
// M3(int)
displayClassName = "<M3>d__5";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 1, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName + "<T, T>", locals[0], "<>m0", "x", expectedILOpt: string.Format(asyncILTemplate, "T", displayClassName + "<T>", "x"));
locals.Clear();
// M4(int)
displayClassName = "<M4>d__6";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 1, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName + "<T, T>", locals[0], "<>m0", "x", expectedILOpt: string.Format(asyncILTemplate, "T", displayClassName + "<T>", "x"));
locals.Clear();
// M4()
displayClassName = "<M4>d__7";
GetLocals(runtime, "C." + displayClassName + ".MoveNext", argumentsOnly: true, locals: locals, count: 0, typeName: out typeName, testData: out testData);
locals.Clear();
locals.Free();
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1115030")]
public void CatchInAsyncStateMachine()
{
var source =
@"using System;
using System.Threading.Tasks;
class C
{
static object F()
{
throw new ArgumentException();
}
static async Task M()
{
object o;
try
{
o = F();
}
catch (Exception e)
{
#line 999
o = e;
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation, runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>d__1.MoveNext", atLineNumber: 999);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "o", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Exception V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<M>d__1.<o>5__1""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "e", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Exception V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""System.Exception C.<M>d__1.<e>5__2""
IL_0006: ret
}");
locals.Free();
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1115030")]
public void CatchInIteratorStateMachine()
{
var source =
@"using System;
using System.Collections;
class C
{
static object F()
{
throw new ArgumentException();
}
static IEnumerable M()
{
object o;
try
{
o = F();
}
catch (Exception e)
{
#line 999
o = e;
}
yield return o;
}
}";
var compilation0 = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>d__1.MoveNext", atLineNumber: 999);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "o", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Exception V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<M>d__1.<o>5__1""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "e", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Exception V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""System.Exception C.<M>d__1.<e>5__2""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
public void DuplicateEditorBrowsableAttributes()
{
const string libSource = @"
namespace System.ComponentModel
{
public enum EditorBrowsableState
{
Always = 0,
Never = 1,
Advanced = 2
}
[AttributeUsage(AttributeTargets.All)]
internal sealed class EditorBrowsableAttribute : Attribute
{
public EditorBrowsableAttribute(EditorBrowsableState state) { }
}
}
";
const string source = @"
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
class C
{
void M()
{
}
}
";
var libRef = CreateCompilation(libSource).EmitToImageReference();
var comp = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(comp, new[] { MscorlibRef, SystemRef, SystemCoreRef, SystemXmlLinqRef, libRef }, runtime =>
{
string typeName;
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
CompilationTestData testData;
GetLocals(runtime, "C.M", argumentsOnly: false, locals: locals, count: 1, typeName: out typeName, testData: out testData);
Assert.Equal("this", locals.Single().LocalName);
locals.Free();
});
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/2089")]
public void MultipleThisFields()
{
var source =
@"using System;
using System.Threading.Tasks;
class C
{
async static Task F(Action a)
{
a();
}
void G(string s)
{
}
async void M()
{
string s = null;
await F(() => G(s));
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation, runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>d__2.MoveNext()");
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var testData = new CompilationTestData();
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, "<>x", locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Runtime.CompilerServices.TaskAwaiter V_1,
C.<M>d__2 V_2,
System.Exception V_3)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<M>d__2.<>4__this""
IL_0006: ret
}");
VerifyLocal(testData, "<>x", locals[1], "<>m1", "s", expectedILOpt:
@"{
// Code size 12 (0xc)
.maxstack 1
.locals init (int V_0,
System.Runtime.CompilerServices.TaskAwaiter V_1,
C.<M>d__2 V_2,
System.Exception V_3)
IL_0000: ldarg.0
IL_0001: ldfld ""C.<>c__DisplayClass2_0 C.<M>d__2.<>8__1""
IL_0006: ldfld ""string C.<>c__DisplayClass2_0.s""
IL_000b: ret
}");
locals.Free();
});
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/2336")]
public void LocalsOnAsyncMethodClosingBrace()
{
var source =
@"using System;
using System.Threading.Tasks;
class C
{
async void M()
{
string s = null;
#line 999
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation, runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>d__0.MoveNext()", atLineNumber: 999);
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var testData = new CompilationTestData();
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, "<>x", locals[0], "<>m0", "this");
VerifyLocal(testData, "<>x", locals[1], "<>m1", "s");
locals.Free();
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1139013")]
public void TransparentIdentifiers_FromParameter()
{
const string source = @"
using System.Linq;
class C
{
void M(string[] args)
{
var concat =
from x in args
let y = x.ToString()
let z = x.GetHashCode()
select x + y + z;
}
}
";
const string methodName = "C.<>c.<M>b__0_2";
const string zIL = @"
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.1
IL_0001: ldfld ""int <>f__AnonymousType1<<>f__AnonymousType0<string, string>, int>.<z>i__Field""
IL_0006: ret
}
";
const string xIL = @"
{
// Code size 12 (0xc)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.1
IL_0001: ldfld ""<>f__AnonymousType0<string, string> <>f__AnonymousType1<<>f__AnonymousType0<string, string>, int>.<<>h__TransparentIdentifier0>i__Field""
IL_0006: ldfld ""string <>f__AnonymousType0<string, string>.<x>i__Field""
IL_000b: ret
}
";
const string yIL = @"
{
// Code size 12 (0xc)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.1
IL_0001: ldfld ""<>f__AnonymousType0<string, string> <>f__AnonymousType1<<>f__AnonymousType0<string, string>, int>.<<>h__TransparentIdentifier0>i__Field""
IL_0006: ldfld ""string <>f__AnonymousType0<string, string>.<y>i__Field""
IL_000b: ret
}
";
var comp = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(comp, runtime =>
{
string typeName;
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
CompilationTestData testData;
GetLocals(runtime, methodName, argumentsOnly: false, locals: locals, count: 3, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "z", expectedILOpt: zIL);
VerifyLocal(testData, typeName, locals[1], "<>m1", "x", expectedILOpt: xIL);
VerifyLocal(testData, typeName, locals[2], "<>m2", "y", expectedILOpt: yIL);
locals.Free();
var context = CreateMethodContext(runtime, methodName);
string error;
testData = new CompilationTestData();
context.CompileExpression("z", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(zIL);
testData = new CompilationTestData();
context.CompileExpression("x", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(xIL);
testData = new CompilationTestData();
context.CompileExpression("y", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(yIL);
});
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1139013")]
public void TransparentIdentifiers_FromDisplayClassField()
{
const string source = @"
using System.Linq;
class C
{
void M(string[] args)
{
var concat =
from x in args
let y = x.ToString()
let z = x.GetHashCode()
select x.Select(c => y + z);
}
}
";
const string methodName = "C.<>c__DisplayClass0_0.<M>b__3";
const string cIL = @"
{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.1
IL_0001: ret
}
";
const string zIL = @"
{
// Code size 12 (0xc)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""<>f__AnonymousType1<<>f__AnonymousType0<string, string>, int> C.<>c__DisplayClass0_0.<>h__TransparentIdentifier1""
IL_0006: ldfld ""int <>f__AnonymousType1<<>f__AnonymousType0<string, string>, int>.<z>i__Field""
IL_000b: ret
}
";
const string xIL = @"
{
// Code size 17 (0x11)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""<>f__AnonymousType1<<>f__AnonymousType0<string, string>, int> C.<>c__DisplayClass0_0.<>h__TransparentIdentifier1""
IL_0006: ldfld ""<>f__AnonymousType0<string, string> <>f__AnonymousType1<<>f__AnonymousType0<string, string>, int>.<<>h__TransparentIdentifier0>i__Field""
IL_000b: ldfld ""string <>f__AnonymousType0<string, string>.<x>i__Field""
IL_0010: ret
}
";
const string yIL = @"
{
// Code size 17 (0x11)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""<>f__AnonymousType1<<>f__AnonymousType0<string, string>, int> C.<>c__DisplayClass0_0.<>h__TransparentIdentifier1""
IL_0006: ldfld ""<>f__AnonymousType0<string, string> <>f__AnonymousType1<<>f__AnonymousType0<string, string>, int>.<<>h__TransparentIdentifier0>i__Field""
IL_000b: ldfld ""string <>f__AnonymousType0<string, string>.<y>i__Field""
IL_0010: ret
}
";
var comp = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(comp, runtime =>
{
string typeName;
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
CompilationTestData testData;
GetLocals(runtime, methodName, argumentsOnly: false, locals: locals, count: 4, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "c", expectedILOpt: cIL);
VerifyLocal(testData, typeName, locals[1], "<>m1", "z", expectedILOpt: zIL);
VerifyLocal(testData, typeName, locals[2], "<>m2", "x", expectedILOpt: xIL);
VerifyLocal(testData, typeName, locals[3], "<>m3", "y", expectedILOpt: yIL);
locals.Free();
var context = CreateMethodContext(runtime, methodName);
string error;
testData = new CompilationTestData();
context.CompileExpression("c", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(cIL);
testData = new CompilationTestData();
context.CompileExpression("z", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(zIL);
testData = new CompilationTestData();
context.CompileExpression("x", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(xIL);
testData = new CompilationTestData();
context.CompileExpression("y", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(yIL);
});
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/pull/3236")]
public void AnonymousTypeParameter()
{
const string source = @"
using System.Linq;
class C
{
static void Main(string[] args)
{
var anonymousTypes =
from a in args
select new { Value = a, Length = a.Length };
var values =
from t in anonymousTypes
select t.Value;
}
}
";
const string methodName = "C.<>c.<Main>b__0_1";
const string tIL = @"
{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}
";
var comp = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(comp, runtime =>
{
string typeName;
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
CompilationTestData testData;
GetLocals(runtime, methodName, argumentsOnly: false, locals: locals, count: 1, typeName: out typeName, testData: out testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "t", expectedILOpt: tIL);
locals.Free();
var context = CreateMethodContext(runtime, methodName);
string error;
testData = new CompilationTestData();
context.CompileExpression("t", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(tIL);
});
}
[Fact, WorkItem("https://github.com/aspnet/Home/issues/955")]
public void ConstantWithErrorType()
{
const string source = @"
class Program
{
static void Main()
{
const int a = 1;
}
}";
var comp = CreateCompilation(source, options: TestOptions.DebugExe);
WithRuntimeInstance(comp, runtime =>
{
var badConst = new MockSymUnmanagedConstant(
"a",
1,
(int bufferLength, out int count, byte[] name) =>
{
count = 0;
return Roslyn.Test.Utilities.HResult.E_NOTIMPL;
});
var debugInfo = new MethodDebugInfoBytes.Builder(constants: new[] { badConst }).Build();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
GetLocals(runtime, "Program.Main", debugInfo, locals, count: 0);
locals.Free();
});
}
[Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems?id=298297")]
public void OrderOfArguments_ArgumentsOnly()
{
var source =
@"using System.Collections.Generic;
class C
{
static IEnumerable<object> F(object y, object x)
{
yield return x;
#line 500
DummySequencePoint();
yield return y;
}
static void DummySequencePoint()
{
}
}";
var comp = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDll);
WithRuntimeInstance(comp, runtime =>
{
EvaluationContext context;
context = CreateMethodContext(runtime, "C.<F>d__0.MoveNext", atLineNumber: 500);
string unused;
var locals = new ArrayBuilder<LocalAndMethod>();
context.CompileGetLocals(locals, argumentsOnly: true, typeName: out unused, testData: null);
var names = locals.Select(l => l.LocalName).ToArray();
// The order must confirm the order of the arguments in the method signature.
Assert.Equal(names, new[] { "y", "x" });
locals.Free();
});
comp = CreateCompilationWithMscorlib40(source, options: TestOptions.ReleaseDll);
WithRuntimeInstance(comp, runtime =>
{
EvaluationContext context;
context = CreateMethodContext(runtime, "C.<F>d__0.MoveNext", atLineNumber: 500);
string unused;
var locals = new ArrayBuilder<LocalAndMethod>();
context.CompileGetLocals(locals, argumentsOnly: true, typeName: out unused, testData: null);
var names = locals.Select(l => l.LocalName).ToArray();
// The problem is not fixed in versions before 4.5: the order of arguments can be wrong.
Assert.Equal(names, new[] { "x", "y" });
locals.Free();
});
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55606")]
public void OrderOfArguments_ArgumentsOnly_Async()
{
var source =
@"using System.Collections.Generic;
using System.Threading.Tasks;
class C
{
static async IAsyncEnumerable<object> F(object y, object x)
{
Task.Yield();
yield return x;
#line 500
DummySequencePoint();
yield return y;
}
static void DummySequencePoint()
{
}
}";
var references = TargetFrameworkUtil.Mscorlib461ExtendedReferences.Concat(new[] { Net461.SystemThreadingTasks, TestMetadata.SystemThreadingTasksExtensions.PortableLib });
var comp = CreateEmptyCompilation(new[] { source, AsyncStreamsTypes }, references: references);
WithRuntimeInstance(comp, references, runtime =>
{
EvaluationContext context;
context = CreateMethodContext(runtime, "C.<F>d__0.MoveNext", atLineNumber: 500);
string unused;
var locals = new ArrayBuilder<LocalAndMethod>();
context.CompileGetLocals(locals, argumentsOnly: true, typeName: out unused, testData: null);
var names = locals.Select(l => l.LocalName).ToArray();
// The order must confirm the order of the arguments in the method signature.
Assert.Equal(names, new[] { "y", "x" });
locals.Free();
});
}
/// <summary>
/// CompileGetLocals should skip locals with errors.
/// </summary>
[Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems?id=535899")]
public void SkipPseudoVariablesWithUseSiteErrors()
{
var source =
@"class C
{
static void M(object x)
{
object y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var aliases = ImmutableArray.Create(ReturnValueAlias(1, "UnknownType, UnknownAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"));
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var diagnostics = DiagnosticBag.GetInstance();
var testData = new CompilationTestData();
context.CompileGetLocals(
locals,
argumentsOnly: false,
aliases: aliases,
diagnostics: diagnostics,
typeName: out typeName,
testData: testData);
diagnostics.Verify();
diagnostics.Free();
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x");
VerifyLocal(testData, typeName, locals[1], "<>m1", "y");
locals.Free();
});
}
[Fact]
public void LocalsInFieldInitializer_01()
{
var source =
@"class C
{
#line 1000
bool Test1 = TakeOutParam(1, out var x1);
C() {}
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldloc.0
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInFieldInitializer_02()
{
var source =
@"class C : Base
{
#line 1000
bool Test1 = TakeOutParam(1, out var x1),
Test2 = TakeOutParam(2, out var x2);
C()
#line 2000
: base(TakeOutParam(0, out var x0))
{}
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
}
class Base
{
public Base(bool x) {}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //x1
int V_1,
int V_2)
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //x1
int V_1,
int V_2)
IL_0000: ldloc.0
IL_0001: ret
}");
locals.Free();
});
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1001);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0,
int V_1, //x2
int V_2)
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x2", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0,
int V_1, //x2
int V_2)
IL_0000: ldloc.1
IL_0001: ret
}");
locals.Free();
});
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 2000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0,
int V_1,
int V_2) //x0
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x0", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0,
int V_1,
int V_2) //x0
IL_0000: ldloc.2
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInFieldInitializer_03()
{
var source =
@"class C
{
#line 1000
bool Test1 = TakeOutParam(1, out var x1) && F(() => x1);
C() {}
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
static bool F(System.Func<int> x)
{
throw null;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass1_0 V_0) //CS$<>8__locals0
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass1_0 V_0) //CS$<>8__locals0
IL_0000: ldloc.0
IL_0001: ldfld ""int C.<>c__DisplayClass1_0.x1""
IL_0006: ret
}");
locals.Free();
});
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass1_0.<.ctor>b__0", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(1, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c__DisplayClass1_0.x1""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInFieldInitializer_04()
{
var source =
@"class C
{
#line 1000
bool Test1 = TakeOutParam(1, out var x1) && F(() => x1),
Test2 = TakeOutParam(2, out var x2) && F(() => x2);
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
static bool F(System.Func<int> x)
{
throw null;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass4_0 V_0, //CS$<>8__locals0
C.<>c__DisplayClass4_1 V_1)
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass4_0 V_0, //CS$<>8__locals0
C.<>c__DisplayClass4_1 V_1)
IL_0000: ldloc.0
IL_0001: ldfld ""int C.<>c__DisplayClass4_0.x1""
IL_0006: ret
}");
locals.Free();
});
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass4_0.<.ctor>b__0", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(1, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c__DisplayClass4_0.x1""
IL_0006: ret
}");
locals.Free();
});
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1001);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass4_0 V_0,
C.<>c__DisplayClass4_1 V_1) //CS$<>8__locals1
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x2", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass4_0 V_0,
C.<>c__DisplayClass4_1 V_1) //CS$<>8__locals1
IL_0000: ldloc.1
IL_0001: ldfld ""int C.<>c__DisplayClass4_1.x2""
IL_0006: ret
}");
locals.Free();
});
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass4_1.<.ctor>b__1", atLineNumber: 1001);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(1, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x2", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c__DisplayClass4_1.x2""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInPropertyInitializer_01()
{
var source =
@"class C
{
#line 1000
bool Test1 { get; } = TakeOutParam(1, out var x1);
C() {}
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldloc.0
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInPropertyInitializer_02()
{
var source =
@"class C
{
#line 1000
bool Test1 { get; } = TakeOutParam(1, out var x1) && F(() => x1);
C() {}
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
static bool F(System.Func<int> x)
{
throw null;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass3_0 V_0) //CS$<>8__locals0
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass3_0 V_0) //CS$<>8__locals0
IL_0000: ldloc.0
IL_0001: ldfld ""int C.<>c__DisplayClass3_0.x1""
IL_0006: ret
}");
locals.Free();
});
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass3_0.<.ctor>b__0", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(1, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c__DisplayClass3_0.x1""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInConstructorInitializer_01()
{
var source =
@"class C : Base
{
C()
#line 1000
: base(TakeOutParam(1, out var x1))
{}
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
}
class Base
{
public Base(bool x) {}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldloc.0
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInConstructorInitializer_02()
{
var source =
@"class C : Base
{
C()
: base(TakeOutParam(1, out var x1))
{
#line 1000
;
}
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
}
class Base
{
public Base(bool x) {}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldloc.0
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInConstructorInitializer_03()
{
var source =
@"class C : Base
{
C()
: base(TakeOutParam(1, out var x1))
#line 1000
=> System.Console.WriteLine();
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
}
class Base
{
public Base(bool x) {}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldloc.0
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInConstructorInitializer_04()
{
var source =
@"class C : Base
{
C()
: base(TakeOutParam(1, out var x1))
{
int x2 = 1;
#line 1000
System.Console.WriteLine(x2);
}
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
}
class Base
{
public Base(bool x) {}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //x1
int V_1) //x2
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //x1
int V_1) //x2
IL_0000: ldloc.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "x2", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //x1
int V_1) //x2
IL_0000: ldloc.1
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInConstructorInitializer_05()
{
var source =
@"class C : Base
{
C()
: base(TakeOutParam(1, out var x1))
#line 1000
=> System.Console.WriteLine(TakeOutParam(2, out var x2));
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
}
class Base
{
public Base(bool x) {}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //x1
int V_1) //x2
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //x1
int V_1) //x2
IL_0000: ldloc.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "x2", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //x1
int V_1) //x2
IL_0000: ldloc.1
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInConstructorInitializer_06()
{
var source =
@"class C : Base
{
C()
#line 1000
: base(TakeOutParam(1, out var x1) && F(() => x1))
{}
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
static bool F(System.Func<int> x)
{
throw null;
}
}
class Base
{
public Base(bool x) {}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0) //CS$<>8__locals0
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0) //CS$<>8__locals0
IL_0000: ldloc.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_0.x1""
IL_0006: ret
}");
locals.Free();
});
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<.ctor>b__0", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(1, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_0.x1""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInConstructorInitializer_07()
{
var source =
@"class C
{
C()
#line 1000
: this(TakeOutParam(1, out var x1))
{}
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
C(bool x) {}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 1000);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldloc.0
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInQuery_01()
{
var source =
@"
using System.Linq;
class C
{
C()
{
#line 1000
var q = from a in new [] {1}
where
TakeOutParam(a, out var x1)
select a;
}
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c.<.ctor>b__0_0", atLineNumber: 1002);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "a", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldarg.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0) //x1
IL_0000: ldloc.0
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
public void LocalsInQuery_02()
{
var source =
@"
using System.Linq;
class C
{
C()
{
#line 1000
var q = from a in new [] {1}
where
TakeOutParam(a, out var x1) && F(() => x1)
select a;
}
static bool TakeOutParam(int y, out int x)
{
x = y;
return true;
}
static bool F(System.Func<int> x)
{
throw null;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c.<.ctor>b__0_0", atLineNumber: 1002);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "a", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0) //CS$<>8__locals0
IL_0000: ldarg.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0) //CS$<>8__locals0
IL_0000: ldloc.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_0.x1""
IL_0006: ret
}");
locals.Free();
});
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<.ctor>b__1", atLineNumber: 1002);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(1, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_0.x1""
IL_0006: ret
}");
locals.Free();
});
}
private static void GetLocals(RuntimeInstance runtime, string methodName, bool argumentsOnly, ArrayBuilder<LocalAndMethod> locals, int count, out string typeName, out CompilationTestData testData)
{
var context = CreateMethodContext(runtime, methodName);
testData = new CompilationTestData();
var assembly = context.CompileGetLocals(locals, argumentsOnly, out typeName, testData);
Assert.NotNull(assembly);
if (count == 0)
{
Assert.Equal(0, assembly.Count);
}
else
{
Assert.InRange(assembly.Count, 0, int.MaxValue);
}
Assert.Equal(count, locals.Count);
}
private static void GetLocals(RuntimeInstance runtime, string methodName, MethodDebugInfoBytes debugInfo, ArrayBuilder<LocalAndMethod> locals, int count)
{
ImmutableArray<MetadataBlock> blocks;
Guid moduleVersionId;
ISymUnmanagedReader unused;
int methodToken;
int localSignatureToken;
GetContextState(runtime, methodName, out blocks, out moduleVersionId, out unused, out methodToken, out localSignatureToken);
var symReader = new MockSymUnmanagedReader(
new Dictionary<int, MethodDebugInfoBytes>()
{
{methodToken, debugInfo}
}.ToImmutableDictionary());
var context = CreateMethodContext(
new AppDomain(),
blocks,
symReader,
moduleVersionId,
methodToken,
methodVersion: 1,
ilOffset: 0,
localSignatureToken: localSignatureToken,
kind: MakeAssemblyReferencesKind.AllAssemblies);
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: null);
Assert.NotNull(assembly);
if (count == 0)
{
Assert.Equal(0, assembly.Count);
}
else
{
Assert.InRange(assembly.Count, 0, int.MaxValue);
}
Assert.Equal(count, locals.Count);
}
[Fact]
public void EENamedTypeSymbolNeverSkipsLocalsInit()
{
var source = @"
namespace System.Runtime.CompilerServices
{
public class SkipLocalsInitAttribute : System.Attribute
{
}
}
public class C
{
[System.Runtime.CompilerServices.SkipLocalsInitAttribute]
public void M<T>()
{
var t = default(T);
}
}
";
var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
WithRuntimeInstance(comp, runtime =>
{
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, "<>x", locals[0], "<>m0<T>", "this", expectedILOpt: @"
{
// Code size 2 (0x2)
.maxstack 1
.locals init (T V_0) //t
IL_0000: ldarg.0
IL_0001: ret
}",
expectedGeneric: true);
VerifyLocal(testData, "<>x", locals[1], "<>m1<T>", "t", expectedILOpt: @"
{
// Code size 2 (0x2)
.maxstack 1
.locals init (T V_0) //t
IL_0000: ldloc.0
IL_0001: ret
}",
expectedGeneric: true);
VerifyLocal(testData, "<>x", locals[2], "<>m2<T>", "<>TypeVariables", expectedFlags: DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt: @"
{
// Code size 6 (0x6)
.maxstack 1
.locals init (T V_0) //t
IL_0000: newobj ""<>c__TypeVariables<T>..ctor()""
IL_0005: ret
}",
expectedGeneric: true);
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_01()
{
var source =
@"class C
{
void Test()
{
int x = 0;
int z = 1;
var d1 = () =>
{
x += z;
};
d1();
var d2 = () =>
{
sbyte x = 0;
int y = x;
var d3 = () =>
{
y += z;
};
x = -100;
#line 100
z += x;
#line 200
return d3;
};
d2()();
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<Test>b__1", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(4, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "z", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
sbyte V_1, //x
System.Action V_2, //d3
System.Action V_3)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_0.z""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
sbyte V_1, //x
System.Action V_2, //d3
System.Action V_3)
IL_0000: ldloc.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "d3", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
sbyte V_1, //x
System.Action V_2, //d3
System.Action V_3)
IL_0000: ldloc.2
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[3], "<>m3", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
sbyte V_1, //x
System.Action V_2, //d3
System.Action V_3)
IL_0000: ldloc.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_1.y""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_02()
{
var source =
@"class C
{
void Test()
{
int x = 0;
int z = 1;
var d1 = () =>
{
x += z;
};
d1();
var d2 = () =>
{
sbyte x = 0;
int y = x;
var d3 = () =>
{
#line 100
y += z;
#line 200
};
x = -100;
z += x;
return d3;
};
d2()();
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_1.<Test>b__2", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_1.y""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x", expectedILOpt:
@"{
// Code size 12 (0xc)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""C.<>c__DisplayClass0_0 C.<>c__DisplayClass0_1.CS$<>8__locals1""
IL_0006: ldfld ""int C.<>c__DisplayClass0_0.x""
IL_000b: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "z", expectedILOpt:
@"{
// Code size 12 (0xc)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""C.<>c__DisplayClass0_0 C.<>c__DisplayClass0_1.CS$<>8__locals1""
IL_0006: ldfld ""int C.<>c__DisplayClass0_0.z""
IL_000b: ret
}");
locals.Free();
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_03()
{
var source =
@"class C
{
void Test()
{
int x = 0;
int z = 1;
var d1 = () =>
{
x += z;
};
d1();
var d2 = (sbyte x) =>
{
int y = x;
var d3 = (short x) =>
{
y += z;
};
x = -100;
#line 100
z += x;
#line 200
return d3;
};
d2(-100)(-200);
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<Test>b__1", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(4, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
System.Action<short> V_1, //d3
System.Action<short> V_2)
IL_0000: ldarg.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "z", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
System.Action<short> V_1, //d3
System.Action<short> V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_0.z""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "d3", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
System.Action<short> V_1, //d3
System.Action<short> V_2)
IL_0000: ldloc.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[3], "<>m3", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
System.Action<short> V_1, //d3
System.Action<short> V_2)
IL_0000: ldloc.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_1.y""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_04()
{
var source =
@"class C
{
void Test()
{
int x = 0;
int z = 1;
var d1 = () =>
{
x += z;
};
d1();
var d2 = (sbyte x) =>
{
int y = x;
var d3 = (short x) =>
{
#line 100
y += z;
#line 200
};
x = -100;
z += x;
return d3;
};
d2(-100)(-200);
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_1.<Test>b__2", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_1.y""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "z", expectedILOpt:
@"{
// Code size 12 (0xc)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""C.<>c__DisplayClass0_0 C.<>c__DisplayClass0_1.CS$<>8__locals1""
IL_0006: ldfld ""int C.<>c__DisplayClass0_0.z""
IL_000b: ret
}");
locals.Free();
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_05()
{
var source =
@"class C
{
static void Test()
{
byte x = 0;
#line 100
byte l1 = 1;
#line 200
var d1 = () =>
{
x += l1;
};
var d2 = () =>
{
short x = 0;
short l2 = l1;
var d3 = () =>
{
x += l2;
};
var d4 = () =>
{
int x = 0;
int l3 = 3 + l2;
};
};
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.Test", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(4, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "d1", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
System.Action V_1, //d1
System.Action V_2) //d2
IL_0000: ldloc.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "d2", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
System.Action V_1, //d1
System.Action V_2) //d2
IL_0000: ldloc.2
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "x", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
System.Action V_1, //d1
System.Action V_2) //d2
IL_0000: ldloc.0
IL_0001: ldfld ""byte C.<>c__DisplayClass0_0.x""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[3], "<>m3", "l1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
System.Action V_1, //d1
System.Action V_2) //d2
IL_0000: ldloc.0
IL_0001: ldfld ""byte C.<>c__DisplayClass0_0.l1""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_06()
{
var source =
@"class C
{
static void Test()
{
byte x = 0;
byte l1 = 1;
var d1 = () =>
{
x += l1;
};
var d2 = () =>
{
short x = 0;
#line 100
short l2 = l1;
#line 200
var d3 = () =>
{
x += l2;
};
var d4 = () =>
{
int x = 0;
int l3 = 3 + l2;
};
};
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<Test>b__1", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(5, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "l1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
System.Action V_1, //d3
System.Action V_2) //d4
IL_0000: ldarg.0
IL_0001: ldfld ""byte C.<>c__DisplayClass0_0.l1""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "d3", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
System.Action V_1, //d3
System.Action V_2) //d4
IL_0000: ldloc.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "d4", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
System.Action V_1, //d3
System.Action V_2) //d4
IL_0000: ldloc.2
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[3], "<>m3", "x", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
System.Action V_1, //d3
System.Action V_2) //d4
IL_0000: ldloc.0
IL_0001: ldfld ""short C.<>c__DisplayClass0_1.x""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[4], "<>m4", "l2", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
System.Action V_1, //d3
System.Action V_2) //d4
IL_0000: ldloc.0
IL_0001: ldfld ""short C.<>c__DisplayClass0_1.l2""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_07()
{
var source =
@"class C
{
static void Test()
{
byte x = 0;
byte l1 = 1;
var d1 = () =>
{
x += l1;
};
var d2 = () =>
{
short x = 0;
short l2 = l1;
var d3 = () =>
{
x += l2;
};
var d4 = () =>
{
int x = 0;
#line 100
int l3 = 3 + l2;
#line 200
};
};
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_1.<Test>b__3", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "l2", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0, //x
int V_1) //l3
IL_0000: ldarg.0
IL_0001: ldfld ""short C.<>c__DisplayClass0_1.l2""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //x
int V_1) //l3
IL_0000: ldloc.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "l3", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //x
int V_1) //l3
IL_0000: ldloc.1
IL_0001: ret
}");
locals.Free();
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_11()
{
var source =
@"class C
{
void Test()
{
int x = 0;
int z = 1;
void d1()
{
x += z;
};
void d2()
{
sbyte x = 0;
int y = x;
void d3()
{
y += z;
};
x = -100;
#line 100
z += x;
#line 200
};
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<Test>g__d2|0_1", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "z", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
sbyte V_1) //x
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_0.z""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
sbyte V_1) //x
IL_0000: ldloc.1
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0, //CS$<>8__locals0
sbyte V_1) //x
IL_0000: ldloc.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_1.y""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_12()
{
var source =
@"class C
{
void Test()
{
int x = 0;
int z = 1;
void d1()
{
x += z;
};
void d2()
{
sbyte x = 0;
int y = x;
void d3()
{
#line 100
y += z;
#line 200
};
x = -100;
z += x;
};
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<Test>g__d3|0_2", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_0.x""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "z", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_0.z""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ldfld ""int C.<>c__DisplayClass0_1.y""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_13()
{
var source =
@"class C
{
void Test()
{
int x = 0;
int z = 1;
void d1()
{
x += z;
};
void d2(sbyte x)
{
int y = x;
void d3(short x)
{
y += z;
};
x = -100;
#line 100
z += x;
#line 200
};
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<Test>g__d2|0_1", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0) //CS$<>8__locals0
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "z", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0) //CS$<>8__locals0
IL_0000: ldarg.1
IL_0001: ldfld ""int C.<>c__DisplayClass0_0.z""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0) //CS$<>8__locals0
IL_0000: ldloc.0
IL_0001: ldfld ""int C.<>c__DisplayClass0_1.y""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_14()
{
var source =
@"class C
{
void Test()
{
int x = 0;
int z = 1;
void d1()
{
x += z;
};
void d2(sbyte x)
{
int y = x;
void d3(short x)
{
#line 100
y += z;
#line 200
};
x = -100;
z += x;
};
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<Test>g__d3|0_2", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "z", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ldfld ""int C.<>c__DisplayClass0_0.z""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.2
IL_0001: ldfld ""int C.<>c__DisplayClass0_1.y""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_15()
{
var source =
@"class C
{
static void Test()
{
byte x = 0;
#line 100
byte l1 = 1;
#line 200
void d1()
{
x += l1;
};
void d2()
{
short x = 0;
short l2 = l1;
void d3()
{
x += l2;
};
void d4()
{
int x = 0;
int l3 = 3 + l2;
};
};
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.Test", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(2, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0) //CS$<>8__locals0
IL_0000: ldloc.0
IL_0001: ldfld ""byte C.<>c__DisplayClass0_0.x""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "l1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0) //CS$<>8__locals0
IL_0000: ldloc.0
IL_0001: ldfld ""byte C.<>c__DisplayClass0_0.l1""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_16()
{
var source =
@"class C
{
static void Test()
{
byte x = 0;
byte l1 = 1;
void d1()
{
x += l1;
};
void d2()
{
short x = 0;
#line 100
short l2 = l1;
#line 200
void d3()
{
x += l2;
};
void d4()
{
int x = 0;
int l3 = 3 + l2;
};
};
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<Test>g__d2|0_1", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "l1", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0) //CS$<>8__locals0
IL_0000: ldarg.0
IL_0001: ldfld ""byte C.<>c__DisplayClass0_0.l1""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0) //CS$<>8__locals0
IL_0000: ldloc.0
IL_0001: ldfld ""short C.<>c__DisplayClass0_1.x""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "l2", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_1 V_0) //CS$<>8__locals0
IL_0000: ldloc.0
IL_0001: ldfld ""short C.<>c__DisplayClass0_1.l2""
IL_0006: ret
}");
locals.Free();
});
}
[Fact]
[WorkItem(67177, "https://github.com/dotnet/roslyn/issues/67177")]
public void CapturingAndShadowing_17()
{
var source =
@"class C
{
static void Test()
{
byte x = 0;
byte l1 = 1;
void d1()
{
x += l1;
};
void d2()
{
short x = 0;
short l2 = l1;
void d3()
{
x += l2;
};
void d4()
{
int x = 0;
#line 100
int l3 = 3 + l2;
#line 200
};
};
}
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, runtime =>
{
var context = CreateMethodContext(runtime, "C.<Test>g__d4|0_3", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Equal(3, locals.Count);
VerifyLocal(testData, typeName, locals[0], "<>m0", "l2", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0, //x
int V_1) //l3
IL_0000: ldarg.0
IL_0001: ldfld ""short C.<>c__DisplayClass0_1.l2""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "x", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //x
int V_1) //l3
IL_0000: ldloc.0
IL_0001: ret
}");
VerifyLocal(testData, typeName, locals[2], "<>m2", "l3", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0, //x
int V_1) //l3
IL_0000: ldloc.1
IL_0001: ret
}");
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_00100_CapturedParameterInsideCapturingInstanceMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
int M()
{
#line 100
;
#line 200
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<y>P""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Int32 <>x.<>m1(" + (isStruct ? "ref " : "") + "C <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_00200_CapturedParameterShadowedByLocalInsideCapturingInstanceMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
int M()
{
{
#line 100
string y = null;
#line 200
}
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //y
int V_1)
IL_0000: ldloc.0
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m1(" + (isStruct ? "ref " : "") + "C <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_00300_CapturedParameterShadowedByLocalInsideCapturingInstanceMethod()
{
var source =
@"class C(int y)
{
int M()
{
{
#line 100
string y = null;
#line 200
var d = () => y;
_ = d().Length;
}
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m2", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass2_0 V_0, //CS$<>8__locals0
System.Func<string> V_1, //d
int V_2)
IL_0000: ldloc.0
IL_0001: ldfld ""string C.<>c__DisplayClass2_0.y""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m2");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m2(C <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_00400_CapturedParameterInsideLambdaInInstanceMethod_NoDisplayClass()
{
var source =
@"class C(int y)
{
int M()
{
var d = () =>
{
this.ToString();
#line 100
;
#line 200
};
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>b__2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<y>P""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Int32 <>x.<>m1(C <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_00500_CapturedParameterInsideLambdaInInstanceMethod_WithDisplayClass()
{
var source =
@"class C<T>(T y)
{
T M(string x)
{
var d = () =>
{
this.ToString();
x.ToString();
#line 100
;
#line 200
};
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass2_0.<M>b__0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName + "<T>", y, "<>m2", "y", expectedILOpt:
@"{
// Code size 12 (0xc)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""C<T> C<T>.<>c__DisplayClass2_0.<>4__this""
IL_0006: ldfld ""T C<T>.<y>P""
IL_000b: ret
}");
var methodData = testData.GetMethodData("<>x<T>.<>m2");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("T <>x<T>.<>m2(C<T>.<>c__DisplayClass2_0 <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_00600_CapturedParameterInsideStaticLambdaInInstanceMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
int M()
{
var d = static (string x) =>
{
x.ToString();
#line 100
;
#line 200
};
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c.<M>b__2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_00700_CapturedParameterShadowedByParameterInsideLambdaInInstanceMethod()
{
var source =
@"class C(int y)
{
int M()
{
var d = (string y) =>
{
y.ToString();
this.ToString();
#line 100
;
#line 200
};
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>b__2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m1(C <>4__this, System.String y)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_00800_CapturedParameterShadowedByParameterInsideLambdaInInstanceMethod()
{
var source =
@"class C(int y)
{
int M()
{
var d = (string y) =>
{
y.ToString();
this.ToString();
var d1 = () => y;
_ = d1().Length;
#line 100
;
#line 200
};
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>b__2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass2_0 V_0, //CS$<>8__locals0
System.Func<string> V_1) //d1
IL_0000: ldloc.0
IL_0001: ldfld ""string C.<>c__DisplayClass2_0.y""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m1(C <>4__this, System.String y)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_00900_CapturedParameterShadowedByLocalInsideLambdaInInstanceMethod()
{
var source =
@"class C(int y)
{
int M()
{
var d = (string x) =>
{
string y = x;
y.ToString();
this.ToString();
#line 100
;
#line 200
};
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>b__2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m2", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0) //y
IL_0000: ldloc.0
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m2");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m2(C <>4__this, System.String x)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_01000_CapturedParameterShadowedByLocalInsideLambdaInInstanceMethod()
{
var source =
@"class C(int y)
{
int M()
{
var d = (string x) =>
{
string y = x;
y.ToString();
this.ToString();
var d1 = () => y;
_ = d1().Length;
#line 100
;
#line 200
};
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>b__2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m3", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass2_0 V_0, //CS$<>8__locals0
System.Func<string> V_1) //d1
IL_0000: ldloc.0
IL_0001: ldfld ""string C.<>c__DisplayClass2_0.y""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m3");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m3(C <>4__this, System.String x)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_01100_CapturedParameterInsideLocalFunctionInInstanceMethod_NoDisplayClass()
{
var source =
@"class C(int y)
{
int M()
{
void d()
{
this.ToString();
#line 100
;
#line 200
}
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>g__d|2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<y>P""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Int32 <>x.<>m1(C <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_01200_CapturedParameterInsideLocalFunctionInInstanceMethod_WithDisplayClass()
{
var source =
@"class C(int y)
{
int M(string x)
{
void d()
{
this.ToString();
x.ToString();
#line 100
;
#line 200
}
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>g__d|2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m2", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<y>P""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m2");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Int32 <>x.<>m2(C <>4__this, ref C.<>c__DisplayClass2_0 value)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_01201_CapturedParameterInsideLocalFunctionInInstanceMethod_WithDisplayClass()
{
var source =
@"class C(int value)
{
int M(string x)
{
void d()
{
this.ToString();
x.ToString();
#line 100
;
#line 200
}
return value;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>g__d|2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "value").Single();
VerifyLocal(testData, typeName, y, "<>m2", "value", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<value>P""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m2");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Int32 <>x.<>m2(C <>4__this, ref C.<>c__DisplayClass2_0 value)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_01300_CapturedParameterInsideStaticLocalFunctionInInstanceMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
int M()
{
static void d(string x)
{
x.ToString();
#line 100
;
#line 200
}
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>g__d|2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_01400_CapturedParameterShadowedByParameterInsideLocalFunctionInInstanceMethod()
{
var source =
@"class C(int y)
{
int M()
{
void d(string y)
{
y.ToString();
this.ToString();
#line 100
;
#line 200
}
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>g__d|2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m1(C <>4__this, System.String y)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_01401_CapturedParameterShadowedByParameterInsideLocalFunctionInInstanceMethod()
{
var source =
@"class C(int y)
{
int M(int x)
{
void d(string y)
{
y.ToString();
x.ToString();
this.ToString();
#line 100
;
#line 200
}
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>g__d|2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m1(C <>4__this, System.String y, ref C.<>c__DisplayClass2_0 value)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_01402_CapturedParameterShadowedByParameterInsideLocalFunctionInInstanceMethod()
{
var source =
@"class C(int value)
{
int M(int x)
{
void d(string value)
{
value.ToString();
x.ToString();
this.ToString();
#line 100
;
#line 200
}
return value;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>g__d|2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "value").Single();
VerifyLocal(testData, typeName, y, "<>m1", "value", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m1(C <>4__this, System.String value, ref C.<>c__DisplayClass2_0 value)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_01500_CapturedParameterShadowedByLocalInsideLocalFunctionInInstanceMethod()
{
var source =
@"class C(int y)
{
int M()
{
void d(string x)
{
string y = x;
y.ToString();
this.ToString();
#line 100
;
#line 200
}
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>g__d|2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m2", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0) //y
IL_0000: ldloc.0
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m2");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m2(C <>4__this, System.String x)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_01501_CapturedParameterShadowedByLocalInsideLocalFunctionInInstanceMethod()
{
var source =
@"class C(int y)
{
int M(int z)
{
void d(string x)
{
string y = x;
y.ToString();
z.ToString();
this.ToString();
#line 100
;
#line 200
}
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>g__d|2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m3", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0) //y
IL_0000: ldloc.0
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m3");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m3(C <>4__this, System.String x, ref C.<>c__DisplayClass2_0 value)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_01502_CapturedParameterShadowedByLocalInsideLocalFunctionInInstanceMethod()
{
var source =
@"class C(int value)
{
int M(int z)
{
void d(string x)
{
string value = x;
value.ToString();
z.ToString();
this.ToString();
#line 100
;
#line 200
}
return value;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>g__d|2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "value").Single();
VerifyLocal(testData, typeName, y, "<>m3", "value", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0) //value
IL_0000: ldloc.0
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m3");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m3(C <>4__this, System.String x, ref C.<>c__DisplayClass2_0 value)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_01503_CapturedParameterShadowedByLocalInsideLocalFunctionInInstanceMethod()
{
var source =
@"class C(int y)
{
int M(int z)
{
void d(string value)
{
string y = value;
y.ToString();
z.ToString();
this.ToString();
#line 100
;
#line 200
}
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M>g__d|2_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m3", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0) //y
IL_0000: ldloc.0
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m3");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m3(C <>4__this, System.String value, ref C.<>c__DisplayClass2_0 value)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_01600_CapturedParameterInsideNonCapturingInstanceMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
int M1()
{
return y;
}
void M2()
{
#line 100
;
#line 200
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M2", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<y>P""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Int32 <>x.<>m1(" + (isStruct ? "ref " : "") + "C <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_01601_CapturedParameterInsideNonCapturingInstanceMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C<T>(T y)
{
T M1()
{
return y;
}
void M2()
{
#line 100
;
#line 200
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M2", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName + "<T>", y, "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""T C<T>.<y>P""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x<T>.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("T <>x<T>.<>m1(" + (isStruct ? "ref " : "") + "C<T> <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_01700_CapturedParameterShadowedByParameterInsideNonCapturingInstanceMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
int M1()
{
return y;
}
void M2(string y)
{
#line 100
;
#line 200
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M2", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m1(" + (isStruct ? "ref " : "") + "C <>4__this, System.String y)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_01800_CapturedParameterShadowedByParameterInsideNonCapturingInstanceMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
int M1()
{
return y;
}
void M2(string y)
{
var d = () => y;
_ = d().Length;
#line 100
;
#line 200
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M2", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass3_0 V_0, //CS$<>8__locals0
System.Func<string> V_1) //d
IL_0000: ldloc.0
IL_0001: ldfld ""string C.<>c__DisplayClass3_0.y""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m1(" + (isStruct ? "ref " : "") + "C <>4__this, System.String y)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_01900_CapturedParameterShadowedByLocalInsideNonCapturingInstanceMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
int M1()
{
return y;
}
void M2()
{
string y = null;
#line 100
;
#line 200
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M2", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0) //y
IL_0000: ldloc.0
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m1(" + (isStruct ? "ref " : "") + "C <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_02000_CapturedParameterShadowedByLocalInsideNonCapturingInstanceMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
int M1()
{
return y;
}
void M2()
{
string y = null;
var d = () => y;
_ = d().Length;
#line 100
;
#line 200
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M2", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m2", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass3_0 V_0, //CS$<>8__locals0
System.Func<string> V_1) //d
IL_0000: ldloc.0
IL_0001: ldfld ""string C.<>c__DisplayClass3_0.y""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m2");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m2(" + (isStruct ? "ref " : "") + "C <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_02100_CapturedParameterInsideStaticMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
int M1()
{
return y;
}
static void M2()
{
#line 100
;
#line 200
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M2", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_02200_CapturedParameterInsideLambdaInStaticMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
int M1()
{
return y;
}
static void M2(string x)
{
var d = () =>
{
#line 100
;
#line 200
x.ToString();
};
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass3_0.<M2>b__0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_02300_CapturedParameterInsideLocalFunctionInStaticMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
int M1()
{
return y;
}
static void M2(string x)
{
void d()
{
#line 100
;
#line 200
x.ToString();
}
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<M2>g__d|3_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_02400_CapturedParameterInsideInstanceFieldInitializer(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C<T>(T y)
{
#line 100
T Y = y;
#line 200
T M() => y;
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor(T)", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName + "<T>", y, "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""T C<T>.<y>P""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x<T>.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("T <>x<T>.<>m1(" + (isStruct ? "out " : "") + "C<T> <>4__this, T y)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_02700_CapturedParameterInsideLambdaInInstanceFieldInitializer_NoDisplayClass()
{
var source =
@"class C(int y)
{
System.Func<int> Y = () =>
{
#line 100
return y;
#line 200
};
int M() => y;
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<.ctor>b__0_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<y>P""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Int32 <>x.<>m1(C <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_02800_CapturedParameterInsideLambdaInInstanceFieldInitializer_WithDisplayClass()
{
var source =
@"class C(int y, int x)
{
System.Func<int> Y = () =>
{
#line 100
return y + x;
#line 200
};
int M() => y;
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<.ctor>b__0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m2", "y", expectedILOpt:
@"{
// Code size 12 (0xc)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<>c__DisplayClass0_0.<>4__this""
IL_0006: ldfld ""int C.<y>P""
IL_000b: ret
}");
var methodData = testData.GetMethodData("<>x.<>m2");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Int32 <>x.<>m2(C.<>c__DisplayClass0_0 <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_02900_CapturedParameterInsideLambdaInInstanceFieldInitializer(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y, int x)
{
System.Func<int> Y = () =>
{
#line 100
return x;
#line 200
};
int M() => y;
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<.ctor>b__0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_03000_CapturedParameterInsideLambdaInInstanceFieldInitializer(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
System.Func<int> Y = () =>
{
#line 100
return 1;
#line 200
};
int M() => y;
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c.<.ctor>b__0_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_03100_CapturedParameterInsideLambdaInInstanceFieldInitializer(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
System.Func<int> Y = static () =>
{
#line 100
return 1;
#line 200
};
int M() => y;
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c.<.ctor>b__0_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_03200_CapturedParameterShadowedByParameterInsideLambdaInInstanceFieldInitializer()
{
var source =
@"class C(int y, int x)
{
System.Func<string, int> Y = (string y) =>
{
#line 100
return y.Length + x;
#line 200
};
int M() => y + x;
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<.ctor>b__0_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.1
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m1(C <>4__this, System.String y)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_03300_CapturedParameterShadowedByParameterInsideLambdaInInstanceFieldInitializer()
{
var source =
@"class C(int y, int x)
{
System.Func<string, int> Y = (string y) =>
{
var d = () => y;
_ = d().Length;
#line 100
return y.Length + x;
#line 200
};
int M() => y + x;
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<.ctor>b__0_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
System.Func<string> V_1, //d
int V_2)
IL_0000: ldloc.0
IL_0001: ldfld ""string C.<>c__DisplayClass0_0.y""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m1(C <>4__this, System.String y)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_03400_CapturedParameterShadowedByLocalInsideLambdaInInstanceFieldInitializer()
{
var source =
@"class C(int y, int x)
{
System.Func<string, int> Y = (string z) =>
{
string y = z;
#line 100
return y.Length + x;
#line 200
};
int M() => y + x;
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<.ctor>b__0_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m3", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (string V_0, //y
int V_1)
IL_0000: ldloc.0
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m3");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m3(C <>4__this, System.String z)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_03500_CapturedParameterShadowedByLocalInsideLambdaInInstanceFieldInitializer()
{
var source =
@"class C(int y, int x)
{
System.Func<string, int> Y = (string z) =>
{
string y = z;
var d = () => y;
_ = d().Length;
#line 100
return y.Length + x;
#line 200
};
int M() => y + x;
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<.ctor>b__0_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m4", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (C.<>c__DisplayClass0_0 V_0, //CS$<>8__locals0
System.Func<string> V_1, //d
int V_2)
IL_0000: ldloc.0
IL_0001: ldfld ""string C.<>c__DisplayClass0_0.y""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m4");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.String <>x.<>m4(C <>4__this, System.String z)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_03600_CapturedParameterInsideStaticFieldInitializer(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
#line 100
static int Y = 1;
#line 200
int M() => y;
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C..cctor", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_03700_CapturedParameterInsidePrimaryConstructorInitializer()
{
var source =
@"class C(int y) :
#line 100
Base(1)
#line 200
{
int M() => y;
}
class Base(int x);
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<y>P""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Int32 <>x.<>m1(C <>4__this, System.Int32 y)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_03800_ThisInLambdaUsingCapturedParameterInsideInstanceFieldInitializer_NoDisplayClass()
{
var source =
@"class C(int y)
{
System.Func<int> Y = () =>
{
#line 100
return y;
#line 200
};
int M() => y;
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<.ctor>b__0_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "this").Single();
VerifyLocal(testData, typeName, y, "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m0");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("C <>x.<>m0(C <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_03900_ThisInLambdaUsingCapturedParameterInsideInstanceFieldInitializer_WithDisplayClass()
{
var source =
@"class C(int y, int x)
{
System.Func<int> Y = () =>
{
#line 100
return y + x;
#line 200
};
int M() => y;
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<.ctor>b__0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "this").Single();
VerifyLocal(testData, typeName, y, "<>m0", "this", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<>c__DisplayClass0_0.<>4__this""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m0");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("C <>x.<>m0(C.<>c__DisplayClass0_0 <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_04000_ThisInLambdaUsingCapturedParameterInsidePrimaryConstructorInitializer_NoDisplayClass()
{
var source =
@"class C(int y)
: Base(() =>
{
#line 100
return y;
#line 200
})
{
int M() => y;
}
class Base(System.Func<int> x);
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<.ctor>b__0_0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "this").Single();
VerifyLocal(testData, typeName, y, "<>m0", "this", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m0");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("C <>x.<>m0(C <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_04100_ThisInLambdaUsingCapturedParameterInsidePrimaryConstructorInitializer_WithDisplayClass()
{
var source =
@"class C(int y, int x)
: Base(() =>
{
#line 100
return y + x;
#line 200
})
{
int M() => y;
}
class Base(System.Func<int> x);
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<.ctor>b__0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "this").Single();
VerifyLocal(testData, typeName, y, "<>m0", "this", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C C.<>c__DisplayClass0_0.<>4__this""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m0");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("C <>x.<>m0(C.<>c__DisplayClass0_0 <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_04600_ThisInLambdaUsingNotCapturedParameterInsideInstanceFieldInitializer()
{
var source =
@"class C(int y)
{
System.Func<int> Y = () =>
{
#line 100
return y;
#line 200
};
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.<>c__DisplayClass0_0.<.ctor>b__0", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "this"));
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_04700_CapturedParameterInsideRegularInstanceConstructor(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
public C() : this(1)
{
#line 100
;
#line 200
}
int M()
{
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor()", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<y>P""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Int32 <>x.<>m1(" + (isStruct ? "out " : "") + "C <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_04800_CapturedParameterShadowedByParameterInsideRegularConstructor(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
C(byte y) : this(0)
{
#line 100
_ = y;
#line 200
}
int M() => y;
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor(Byte)", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Byte <>x.<>m1(" + (isStruct ? "out " : "") + "C <>4__this, System.Byte y)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_04900_CapturedParameterInsideRegularInstanceConstructorInitializer(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
public C() :
#line 100
this(1)
#line 200
{
}
int M()
{
return y;
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor()", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<y>P""
IL_0006: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Int32 <>x.<>m1(" + (isStruct ? "out " : "") + "C <>4__this)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_05000_CapturedParameterShadowedByParameterInsideRegularConstructorInitializer(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
C(byte y) :
#line 100
this((int)y)
#line 200
{
}
int M() => y;
}
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor(Byte)", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Byte <>x.<>m1(" + (isStruct ? "out " : "") + "C <>4__this, System.Byte y)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_05100_NotCapturedParameterInsideInstanceMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
void M()
{
#line 100
;
#line 200
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_05200_NotCapturedParameterInsideStaticMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
static void M()
{
#line 100
;
#line 200
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_05300_NotCapturedParameterInsideInstanceFieldInitializer(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
#line 100
int Y = y;
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor(Int32)", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Int32 <>x.<>m1(" + (isStruct ? "out " : "") + "C <>4__this, System.Int32 y)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_05400_NotCapturedParameterInsideStaticFieldInitializer(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
#line 100
static int Y = 1;
#line 200
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C..cctor", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Fact]
public void PrimaryConstructors_05500_NotCapturedParameterInsidePrimaryConstructorInitializer()
{
var source =
@"class C(int y) :
#line 100
Base(1)
#line 200
{
}
class Base(int x);
";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.NotEqual(0, assembly.Count);
var y = locals.Where(l => l.LocalName == "y").Single();
VerifyLocal(testData, typeName, y, "<>m1", "y", expectedILOpt:
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldarg.1
IL_0001: ret
}");
var methodData = testData.GetMethodData("<>x.<>m1");
Assert.True(methodData.Method.IsStatic);
AssertEx.Equal("System.Int32 <>x.<>m1(C <>4__this, System.Int32 y)", ((MethodSymbol)methodData.Method).ToTestDisplayString());
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_05600_NotCapturedParameterInsideRegularInstanceConstructor(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
public C() : this(1)
{
#line 100
;
#line 200
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor()", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_05700_NotCapturedParameterInsideRegularInstanceConstructorInitializer(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
public C() :
#line 100
this(1)
#line 200
{
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C..ctor()", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_05800_NotCapturedParameterShadowedByMemberInsideInstanceMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
int y = y;
void M()
{
#line 100
;
#line 200
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
[Theory]
[CombinatorialData]
public void PrimaryConstructors_05900_NotCapturedParameterShadowedByMemberInsideStaticMethod(bool isStruct)
{
var source =
(isStruct ? "struct" : "class") + @" C(int y)
{
static int y = 1;
static void M()
{
#line 100
;
#line 200
}
}";
var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll);
WithRuntimeInstance(compilation0, targetDebugFormat: DebugInformationFormat.PortablePdb, validator: runtime =>
{
var context = CreateMethodContext(runtime, "C.M", atLineNumber: 100);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.NotNull(assembly);
Assert.Empty(locals.Where(l => l.LocalName == "y"));
locals.Free();
});
}
}
}
|