public void DebugOnly() { var source = @"class C { static System.IDisposable F() { return null; } static void M() { lock (F()) { } using (F()) { } } }"; var debug = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); var release = CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseDll); CompilationTestData testData; ImmutableArray<string> names; testData = new CompilationTestData(); debug.EmitToArray(testData: testData); names = GetLocalNames(testData.GetMethodData("C.M")); AssertEx.Equal(new string[] { "CS$2$0000", "CS$520$0001", "CS$3$0002" }, names); testData = new CompilationTestData(); release.EmitToArray(testData: testData); names = GetLocalNames(testData.GetMethodData("C.M")); AssertEx.Equal(new string[] { null, null }, names); }
public void AddressOfLocal() { var source = @"class C { void M() { string s = ""hello""; } }"; var comp = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); WithRuntimeInstance(comp, runtime => { var context = CreateMethodContext(runtime, "C.M"); var testData = new CompilationTestData(); string error; context.CompileExpression("&s", out error, testData); Assert.Null(error); var methodData = testData.GetMethodData("<>x.<>m0"); AssertIsIntPtrPointer(methodData.Method.ReturnType); methodData.VerifyIL(@" { // Code size 4 (0x4) .maxstack 1 .locals init (string V_0) //s IL_0000: ldloca.s V_0 IL_0002: conv.u IL_0003: ret } "); }); }
public void AddressOfParameter() { var source = @"class C { void M(string s) { } }"; var comp = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); var runtime = CreateRuntimeInstance(comp); var context = CreateMethodContext( runtime, methodName: "C.M"); var testData = new CompilationTestData(); string error; context.CompileExpression("&s", out error, testData); Assert.Null(error); var methodData = testData.GetMethodData("<>x.<>m0"); AssertIsIntPtrPointer(methodData.Method.ReturnType); methodData.VerifyIL(@" { // Code size 4 (0x4) .maxstack 1 IL_0000: ldarga.s V_1 IL_0002: conv.u IL_0003: ret } "); }
public void Win8RuntimeAssemblies() { var source = @"class C { static void M(Windows.Storage.StorageFolder f, Windows.Foundation.Collections.PropertySet p) { } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName(), references: WinRtRefs); var runtimeAssemblies = ExpressionCompilerTestHelpers.GetRuntimeWinMds("Windows.Storage", "Windows.Foundation.Collections"); Assert.True(runtimeAssemblies.Length >= 2); byte[] exeBytes; byte[] pdbBytes; ImmutableArray<MetadataReference> references; compilation0.EmitAndGetReferences(out exeBytes, out pdbBytes, out references); var runtime = CreateRuntimeInstance( ExpressionCompilerUtilities.GenerateUniqueName(), ImmutableArray.Create(MscorlibRef).Concat(runtimeAssemblies), // no reference to Windows.winmd exeBytes, new SymReader(pdbBytes)); var context = CreateMethodContext(runtime, "C.M"); ResultProperties resultProperties; string error; var testData = new CompilationTestData(); context.CompileExpression("(p == null) ? f : null", out resultProperties, out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.1 IL_0001: brfalse.s IL_0005 IL_0003: ldnull IL_0004: ret IL_0005: ldarg.0 IL_0006: ret }"); }
public void ExplicitEmbeddedType() { var source = @"using System.Runtime.InteropServices; [TypeIdentifier] [Guid(""863D5BC0-46A1-49AD-97AA-A5F0D441A9D8"")] public interface I { object F(); } class C { void M() { var o = (I)null; } static void Main() { (new C()).M(); } }"; var compilation0 = CSharpTestBase.CreateCompilationWithMscorlib( source, options: TestOptions.DebugExe, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext(runtime, "C.M"); ResultProperties resultProperties; string error; var testData = new CompilationTestData(); var result = context.CompileExpression("this", out resultProperties, out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 2 (0x2) .maxstack 1 .locals init (I V_0) //o IL_0000: ldarg.0 IL_0001: ret }"); }
public void Literal() { var source = @"class C { static void M() { (int, int) o; } }"; var comp = CreateCompilationWithMscorlib(source, new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugDll); WithRuntimeInstance(comp, new[] { ValueTupleRef, SystemRuntimeFacadeRef, MscorlibRef }, runtime => { var context = CreateMethodContext(runtime, "C.M"); var testData = new CompilationTestData(); string error; var result = context.CompileExpression("(A: 1, B: 2)", out error, testData); Assert.Null(error); ReadOnlyCollection<byte> customTypeInfo; var customTypeInfoId = result.GetCustomTypeInfo(out customTypeInfo); ReadOnlyCollection<byte> dynamicFlags; ReadOnlyCollection<string> tupleElementNames; CustomTypeInfo.Decode(customTypeInfoId, customTypeInfo, out dynamicFlags, out tupleElementNames); Assert.Equal(new[] { "A", "B" }, tupleElementNames); var methodData = testData.GetMethodData("<>x.<>m0"); var method = methodData.Method; Assert.True(method.ReturnType.IsTupleType); Assert.NotNull(GetTupleElementNamesAttributeIfAny(method)); methodData.VerifyIL( @"{ // Code size 8 (0x8) .maxstack 2 .locals init ((int, int) V_0) //o IL_0000: ldc.i4.1 IL_0001: ldc.i4.2 IL_0002: newobj ""System.ValueTuple<int, int>..ctor(int, int)"" IL_0007: ret }"); }); }
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 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugExe); byte[] exeBytes; byte[] pdbBytes; ImmutableArray<MetadataReference> references; compilation0.EmitAndGetReferences(out exeBytes, out pdbBytes, out references); var constantSignatures = ImmutableDictionary.CreateRange( new Dictionary<string, byte[]>() { { "t", new byte[] { 0x15, 0x11, 0x10, 0x01, 0x13, 0x00 } }, { "u", new byte[] { 0x15, 0x11, 0x10, 0x01, 0x1e, 0x00 } } }); var runtime = CreateRuntimeInstance(ExpressionCompilerUtilities.GenerateUniqueName(), references, exeBytes, new SymReader(pdbBytes, constantSignatures)); var context = CreateMethodContext( runtime, methodName: "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(locals.Count, 3); VerifyLocal(testData, "<>x<T>", locals[0], "<>m0<U>", "t", 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", 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", 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(); }
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, bool V_1) IL_0000: ldarg.0 IL_0001: ldfld ""int C.<F>d__0.x"" IL_0006: ret }"; var compilation0 = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, methodName: "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(assembly.Count, 0); Assert.Equal(locals.Count, 1); VerifyLocal(testData, typeName, locals[0], "<>m0", "x", expectedILOpt: expectedIL); Assert.Equal(SpecialType.System_Int32, 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, methodData.Method.ReturnType.SpecialType); }
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 compilation0 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); byte[] exeBytes; byte[] pdbBytes; ImmutableArray<MetadataReference> references; compilation0.EmitAndGetReferences(out exeBytes, out pdbBytes, out references); var runtime = CreateRuntimeInstance( ExpressionCompilerUtilities.GenerateUniqueName(), references, exeBytes, new SymReader(pdbBytes), includeLocalSignatures: false); 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(locals.Count, 2); 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(); ResultProperties resultProperties; string error; testData = new CompilationTestData(); context.CompileExpression("b", out resultProperties, out error, testData); Assert.Equal(error, "error CS0103: The name 'b' does not exist in the current context"); testData = new CompilationTestData(); context.CompileExpression("a[1]", out resultProperties, 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 }"); }
public void TypeOutsideModule() { var sourceA = @"using System; public class A<T> { public static void M(Action f) { object o; try { f(); } catch (Exception) { } } }"; var sourceB = @"using System; class E : Exception { internal object F; } class B { static void Main() { A<int>.M(() => { throw new E(); }); } }"; var assemblyNameA = "0A93FF0B-31A2-47C8-B24D-16A2D77AB5C5"; var compilationA = CreateCompilationWithMscorlib(sourceA, options: TestOptions.DebugDll, assemblyName: assemblyNameA); byte[] exeA; byte[] pdbA; ImmutableArray<MetadataReference> referencesA; compilationA.EmitAndGetReferences(out exeA, out pdbA, out referencesA); var metadataA = AssemblyMetadata.CreateFromImage(exeA); var referenceA = metadataA.GetReference(); var assemblyNameB = "9BAC6622-86EB-4EC5-94A1-9A1E6D0C24B9"; var compilationB = CreateCompilationWithMscorlib(sourceB, options: TestOptions.DebugExe, references: new[] { referenceA }, assemblyName: assemblyNameB); byte[] exeB; byte[] pdbB; ImmutableArray<MetadataReference> referencesB; compilationB.EmitAndGetReferences(out exeB, out pdbB, out referencesB); var metadataB = AssemblyMetadata.CreateFromImage(exeB); var referenceB = metadataB.GetReference(); var modulesBuilder = ArrayBuilder<ModuleInstance>.GetInstance(); modulesBuilder.Add(MscorlibRef.ToModuleInstance(fullImage: null, symReader: null)); modulesBuilder.Add(referenceA.ToModuleInstance(fullImage: exeA, symReader: new SymReader(pdbA))); modulesBuilder.Add(referenceB.ToModuleInstance(fullImage: exeB, symReader: new SymReader(pdbB))); modulesBuilder.Add(ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance(fullImage: null, symReader: null)); using (var runtime = new RuntimeInstance(modulesBuilder.ToImmutableAndFree())) { var context = CreateMethodContext( runtime, "A.M"); var aliases = ImmutableArray.Create( ExceptionAlias("E, 9BAC6622-86EB-4EC5-94A1-9A1E6D0C24B9, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"), ObjectIdAlias(1, "A`1[[B, 9BAC6622-86EB-4EC5-94A1-9A1E6D0C24B9, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], 0A93FF0B-31A2-47C8-B24D-16A2D77AB5C5, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")); string error; var testData = new CompilationTestData(); context.CompileExpression( "$exception", DkmEvaluationFlags.TreatAsExpression, aliases, out error, testData); Assert.Null(error); testData.GetMethodData("<>x<T>.<>m0").VerifyIL( @"{ // Code size 11 (0xb) .maxstack 1 .locals init (object V_0) //o IL_0000: call ""System.Exception Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetException()"" IL_0005: castclass ""E"" IL_000a: ret }"); ResultProperties resultProperties; ImmutableArray<AssemblyIdentity> missingAssemblyIdentities; testData = new CompilationTestData(); context.CompileAssignment( "o", "$1", aliases, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Null(error); testData.GetMethodData("<>x<T>.<>m0").VerifyIL( @"{ // Code size 17 (0x11) .maxstack 1 .locals init (object V_0) //o IL_0000: ldstr ""$1"" IL_0005: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_000a: castclass ""A<B>"" IL_000f: stloc.0 IL_0010: ret }"); } }
public void DifferentAssemblyVersion() { var sourceA = @"public class A<T> { }"; var sourceB = @"class B<T> { } class C { static void M() { var o = new A<object>(); } }"; var assemblyNameA = "397300B0-A"; var publicKeyA = ImmutableArray.CreateRange(new byte[] { 0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0xED, 0xD3, 0x22, 0xCB, 0x6B, 0xF8, 0xD4, 0xA2, 0xFC, 0xCC, 0x87, 0x37, 0x04, 0x06, 0x04, 0xCE, 0xE7, 0xB2, 0xA6, 0xF8, 0x4A, 0xEE, 0xF3, 0x19, 0xDF, 0x5B, 0x95, 0xE3, 0x7A, 0x6A, 0x28, 0x24, 0xA4, 0x0A, 0x83, 0x83, 0xBD, 0xBA, 0xF2, 0xF2, 0x52, 0x20, 0xE9, 0xAA, 0x3B, 0xD1, 0xDD, 0xE4, 0x9A, 0x9A, 0x9C, 0xC0, 0x30, 0x8F, 0x01, 0x40, 0x06, 0xE0, 0x2B, 0x95, 0x62, 0x89, 0x2A, 0x34, 0x75, 0x22, 0x68, 0x64, 0x6E, 0x7C, 0x2E, 0x83, 0x50, 0x5A, 0xCE, 0x7B, 0x0B, 0xE8, 0xF8, 0x71, 0xE6, 0xF7, 0x73, 0x8E, 0xEB, 0x84, 0xD2, 0x73, 0x5D, 0x9D, 0xBE, 0x5E, 0xF5, 0x90, 0xF9, 0xAB, 0x0A, 0x10, 0x7E, 0x23, 0x48, 0xF4, 0xAD, 0x70, 0x2E, 0xF7, 0xD4, 0x51, 0xD5, 0x8B, 0x3A, 0xF7, 0xCA, 0x90, 0x4C, 0xDC, 0x80, 0x19, 0x26, 0x65, 0xC9, 0x37, 0xBD, 0x52, 0x81, 0xF1, 0x8B, 0xCD }); var compilationA1 = CreateCompilation( new AssemblyIdentity(assemblyNameA, new Version(1, 1, 1, 1), cultureName: "", publicKeyOrToken: publicKeyA, hasPublicKey: true), new[] { sourceA }, references: new[] { MscorlibRef_v20 }, options: TestOptions.DebugDll.WithDelaySign(true)); var referenceA1 = compilationA1.EmitToImageReference(); var assemblyNameB = "397300B0-B"; var compilationB1 = CreateCompilation( new AssemblyIdentity(assemblyNameB, new Version(1, 2, 2, 2)), new[] { sourceB }, references: new[] { MscorlibRef_v20, referenceA1 }, options: TestOptions.DebugDll); // Use mscorlib v4.0.0.0 and A v2.1.2.1 at runtime. byte[] exeBytes; byte[] pdbBytes; ImmutableArray<MetadataReference> references; compilationB1.EmitAndGetReferences(out exeBytes, out pdbBytes, out references); var compilationA2 = CreateCompilation( new AssemblyIdentity(assemblyNameA, new Version(2, 1, 2, 1), cultureName: "", publicKeyOrToken: publicKeyA, hasPublicKey: true), new[] { sourceA }, references: new[] { MscorlibRef_v20 }, options: TestOptions.DebugDll.WithDelaySign(true)); var referenceA2 = compilationA2.EmitToImageReference(); var runtime = CreateRuntimeInstance( assemblyNameB, ImmutableArray.Create(MscorlibRef, referenceA2).AddIntrinsicAssembly(), exeBytes, new SymReader(pdbBytes)); //// typeof(Exception), typeof(A<B<object>>), typeof(B<A<object>[]>) var context = CreateMethodContext( runtime, "C.M"); var aliases = ImmutableArray.Create( ExceptionAlias("System.Exception, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), ObjectIdAlias(1, "A`1[[B`1[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], 397300B0-B, Version=1.2.2.2, Culture=neutral, PublicKeyToken=null]], 397300B0-A, Version=2.1.2.1, Culture=neutral, PublicKeyToken=1f8a32457d187bf3"), ObjectIdAlias(2, "B`1[[A`1[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]][], 397300B0-A, Version=2.1.2.1, Culture=neutral, PublicKeyToken=1f8a32457d187bf3]], 397300B0-B, Version=1.2.2.2, Culture=neutral, PublicKeyToken=null")); string error; var testData = new CompilationTestData(); context.CompileExpression( "(object)$exception ?? (object)$1 ?? $2", DkmEvaluationFlags.TreatAsExpression, aliases, out error, testData); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 44 (0x2c) .maxstack 2 .locals init (A<object> V_0) //o IL_0000: call ""System.Exception Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetException()"" IL_0005: dup IL_0006: brtrue.s IL_002b IL_0008: pop IL_0009: ldstr ""$1"" IL_000e: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_0013: castclass ""A<B<object>>"" IL_0018: dup IL_0019: brtrue.s IL_002b IL_001b: pop IL_001c: ldstr ""$2"" IL_0021: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_0026: castclass ""B<A<object>[]>"" IL_002b: ret }"); }
public void PassByRef() { var source = @"class C { static T F<T>(ref T t) { t = default(T); return t; } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, "C.F"); var aliases = ImmutableArray.Create( ExceptionAlias(), ReturnValueAlias(), ObjectIdAlias(1), VariableAlias("x", typeof(int))); string error; // $exception context.CompileExpression( "$exception = null", DkmEvaluationFlags.TreatAsExpression, aliases, out error); Assert.Equal(error, "error CS0131: The left-hand side of an assignment must be a variable, property or indexer"); context.CompileExpression( "F(ref $exception)", DkmEvaluationFlags.TreatAsExpression, aliases, out error); Assert.Equal(error, "error CS1510: A ref or out argument must be an assignable variable"); // Object at address context.CompileExpression( "@0x123 = null", DkmEvaluationFlags.TreatAsExpression, aliases, out error); Assert.Equal(error, "error CS0131: The left-hand side of an assignment must be a variable, property or indexer"); context.CompileExpression( "F(ref @0x123)", DkmEvaluationFlags.TreatAsExpression, aliases, out error); Assert.Equal(error, "error CS1510: A ref or out argument must be an assignable variable"); // $ReturnValue context.CompileExpression( "$ReturnValue = null", DkmEvaluationFlags.TreatAsExpression, aliases, out error); Assert.Equal(error, "error CS0131: The left-hand side of an assignment must be a variable, property or indexer"); context.CompileExpression( "F(ref $ReturnValue)", DkmEvaluationFlags.TreatAsExpression, aliases, out error); Assert.Equal(error, "error CS1510: A ref or out argument must be an assignable variable"); // Object id context.CompileExpression( "$1 = null", DkmEvaluationFlags.TreatAsExpression, aliases, out error); Assert.Equal(error, "error CS0131: The left-hand side of an assignment must be a variable, property or indexer"); context.CompileExpression( "F(ref $1)", DkmEvaluationFlags.TreatAsExpression, aliases, out error); Assert.Equal(error, "error CS1510: A ref or out argument must be an assignable variable"); // Declared variable var testData = new CompilationTestData(); context.CompileExpression( "x = 1", DkmEvaluationFlags.TreatAsExpression, aliases, out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0<T>").VerifyIL( @"{ // Code size 16 (0x10) .maxstack 3 .locals init (T V_0, int V_1) IL_0000: ldstr ""x"" IL_0005: call ""int Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress<int>(string)"" IL_000a: ldc.i4.1 IL_000b: dup IL_000c: stloc.1 IL_000d: stind.i4 IL_000e: ldloc.1 IL_000f: ret }"); testData = new CompilationTestData(); var result = context.CompileExpression( "F(ref x)", DkmEvaluationFlags.TreatAsExpression, aliases, out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0<T>").VerifyIL( @"{ // Code size 16 (0x10) .maxstack 1 .locals init (T V_0) IL_0000: ldstr ""x"" IL_0005: call ""int Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress<int>(string)"" IL_000a: call ""int C.F<int>(ref int)"" IL_000f: ret }"); }
private void CompileTimeAndRuntimeAssemblies( ImmutableArray<MetadataReference> compileReferences, ImmutableArray<MetadataReference> runtimeReferences, string storageAssemblyName) { var source = @"class C { static void M(LibraryA.A a, LibraryB.B b, Windows.Data.Text.TextSegment t, Windows.Storage.StorageFolder f) { } }"; var compilation0 = CreateCompilationWithMscorlib(source, compileReferences, TestOptions.DebugDll); WithRuntimeInstance(compilation0, runtimeReferences, runtime => { var context = CreateMethodContext(runtime, "C.M"); string error; var testData = new CompilationTestData(); context.CompileExpression("(object)a ?? (object)b ?? (object)t ?? f", out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 17 (0x11) .maxstack 2 IL_0000: ldarg.0 IL_0001: dup IL_0002: brtrue.s IL_0010 IL_0004: pop IL_0005: ldarg.1 IL_0006: dup IL_0007: brtrue.s IL_0010 IL_0009: pop IL_000a: ldarg.2 IL_000b: dup IL_000c: brtrue.s IL_0010 IL_000e: pop IL_000f: ldarg.3 IL_0010: ret }"); testData = new CompilationTestData(); var result = context.CompileExpression("default(Windows.Storage.StorageFolder)", out error, testData); Assert.Null(error); var methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 2 (0x2) .maxstack 1 IL_0000: ldnull IL_0001: ret }"); // Check return type is from runtime assembly. var assemblyReference = AssemblyMetadata.CreateFromImage(result.Assembly).GetReference(); var compilation = CSharpCompilation.Create( assemblyName: ExpressionCompilerUtilities.GenerateUniqueName(), references: runtimeReferences.Concat(ImmutableArray.Create<MetadataReference>(assemblyReference))); var assembly = ImmutableArray.CreateRange(result.Assembly); using (var metadata = ModuleMetadata.CreateFromImage(ImmutableArray.CreateRange(assembly))) { var reader = metadata.MetadataReader; var typeDef = reader.GetTypeDef("<>x"); var methodHandle = reader.GetMethodDefHandle(typeDef, "<>m0"); var module = (PEModuleSymbol)compilation.GetMember("<>x").ContainingModule; var metadataDecoder = new MetadataDecoder(module); SignatureHeader signatureHeader; BadImageFormatException metadataException; var parameters = metadataDecoder.GetSignatureForMethod(methodHandle, out signatureHeader, out metadataException); Assert.Equal(parameters.Length, 5); var actualReturnType = parameters[0].Type; Assert.Equal(actualReturnType.TypeKind, TypeKind.Class); // not error var expectedReturnType = compilation.GetMember("Windows.Storage.StorageFolder"); Assert.Equal(expectedReturnType, actualReturnType); Assert.Equal(storageAssemblyName, actualReturnType.ContainingAssembly.Name); } }); }
public void BaseMembersInLambda() { var source = @" class Base { protected int x; } class Derived : Base { new protected object x; void F() { System.Action a = () => this.x.ToString(); a(); } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext(runtime, "Derived.<F>b__1_0"); string error; var testData = new CompilationTestData(); context.CompileExpression("this.x", out error, testData); testData.GetMethodData("<>x.<>m0").VerifyIL(@" { // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 IL_0001: ldfld ""object Derived.x"" IL_0006: ret }"); }
public void BaseMembersInAsync() { var source = @" using System; using System.Threading.Tasks; class Base { protected int x; } class Derived : Base { new protected object x; async Task M() { await Console.Out.WriteLineAsync(this.ToString()); } }"; var compilation0 = CreateCompilationWithMscorlib45( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext(runtime, "Derived.<M>d__1.MoveNext"); string error; var testData = new CompilationTestData(); context.CompileExpression("base.x", out error, testData); testData.GetMethodData("<>x.<>m0").VerifyIL(@" { // Code size 12 (0xc) .maxstack 1 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, Derived.<M>d__1 V_2, System.Exception V_3) IL_0000: ldarg.0 IL_0001: ldfld ""Derived Derived.<M>d__1.<>4__this"" IL_0006: ldfld ""int Base.x"" IL_000b: ret }"); }
public void ArrayType() { var source = @"class C { object F; static void M() { } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, "C.M"); var aliases = ImmutableArray.Create( VariableAlias("a", "C[]"), VariableAlias("b", "System.Int32[,], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")); ResultProperties resultProperties; string error; ImmutableArray<AssemblyIdentity> missingAssemblyIdentities; var testData = new CompilationTestData(); context.CompileExpression( "a[b[1, 0]].F", DkmEvaluationFlags.TreatAsExpression, aliases, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 44 (0x2c) .maxstack 4 IL_0000: ldstr ""a"" IL_0005: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_000a: castclass ""C[]"" IL_000f: ldstr ""b"" IL_0014: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_0019: castclass ""int[,]"" IL_001e: ldc.i4.1 IL_001f: ldc.i4.0 IL_0020: call ""int[*,*].Get"" IL_0025: ldelem.ref IL_0026: ldfld ""object C.F"" IL_002b: ret }"); }
public void AssignException() { var source = @"class C { static void M(System.Exception e) { } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, "C.M"); var aliases = ImmutableArray.Create( ExceptionAlias()); ResultProperties resultProperties; string error; ImmutableArray<AssemblyIdentity> missingAssemblyIdentities; var testData = new CompilationTestData(); context.CompileAssignment( target: "e", expr: "$exception.InnerException ?? $exception", aliases: aliases, formatter: DiagnosticFormatter.Instance, resultProperties: out resultProperties, error: out error, missingAssemblyIdentities: out missingAssemblyIdentities, preferredUICulture: EnsureEnglishUICulture.PreferredOrNull, testData: testData); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 22 (0x16) .maxstack 2 IL_0000: call ""System.Exception Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetException()"" IL_0005: callvirt ""System.Exception System.Exception.InnerException.get"" IL_000a: dup IL_000b: brtrue.s IL_0013 IL_000d: pop IL_000e: call ""System.Exception Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetException()"" IL_0013: starg.s V_0 IL_0015: ret }"); }
public void AssemblyQualifiedName() { var source = @"class C { static void M(Windows.Storage.StorageFolder f, Windows.Foundation.Collections.PropertySet p) { } }"; var compilation = CreateCompilationWithMscorlib(source, WinRtRefs, TestOptions.DebugDll); WithRuntimeInstance(compilation, new[] { MscorlibRef }.Concat(ExpressionCompilerTestHelpers.GetRuntimeWinMds("Windows.Storage", "Windows.Foundation.Collections")), runtime => { var context = CreateMethodContext(runtime, "C.M"); var aliases = ImmutableArray.Create( VariableAlias("s", "Windows.Storage.StorageFolder, Windows.Storage, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime"), VariableAlias("d", "Windows.Foundation.DateTime, Windows.Foundation, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime")); string error; var testData = new CompilationTestData(); context.CompileExpression( "(object)s.Attributes ?? d.UniversalTime", DkmEvaluationFlags.TreatAsExpression, aliases, out error, testData); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 55 (0x37) .maxstack 2 IL_0000: ldstr ""s"" IL_0005: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_000a: castclass ""Windows.Storage.StorageFolder"" IL_000f: callvirt ""Windows.Storage.FileAttributes Windows.Storage.StorageFolder.Attributes.get"" IL_0014: box ""Windows.Storage.FileAttributes"" IL_0019: dup IL_001a: brtrue.s IL_0036 IL_001c: pop IL_001d: ldstr ""d"" IL_0022: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_0027: unbox.any ""Windows.Foundation.DateTime"" IL_002c: ldfld ""long Windows.Foundation.DateTime.UniversalTime"" IL_0031: box ""long"" IL_0036: ret }"); }); }
public void CompoundAssignment() { var source = @"struct S { internal int F; } class C { static void M() { } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, "C.M"); var aliases = ImmutableArray.Create( VariableAlias("s", "S")); string error; var testData = new CompilationTestData(); context.CompileExpression( "s.F += 2", DkmEvaluationFlags.TreatAsExpression, aliases, out error, testData); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 24 (0x18) .maxstack 3 .locals init (int V_0) IL_0000: ldstr ""s"" IL_0005: call ""S Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress<S>(string)"" IL_000a: ldflda ""int S.F"" IL_000f: dup IL_0010: ldind.i4 IL_0011: ldc.i4.2 IL_0012: add IL_0013: dup IL_0014: stloc.0 IL_0015: stind.i4 IL_0016: ldloc.0 IL_0017: ret }"); }
public void WinMdAssemblyReferenceRequiresRedirect() { var source = @"class C : Windows.UI.Xaml.Controls.UserControl { static void M(C c) { } }"; var compilation = CreateCompilationWithMscorlib(source, WinRtRefs, TestOptions.DebugDll); WithRuntimeInstance(compilation, new[] { MscorlibRef }.Concat(ExpressionCompilerTestHelpers.GetRuntimeWinMds("Windows.UI", "Windows.UI.Xaml")), runtime => { string errorMessage; var testData = new CompilationTestData(); ExpressionCompilerTestHelpers.CompileExpressionWithRetry( runtime.Modules.SelectAsArray(m => m.MetadataBlock), "c.Dispatcher", ImmutableArray<Alias>.Empty, (metadataBlocks, _) => { return CreateMethodContext(runtime, "C.M"); }, (AssemblyIdentity assembly, out uint size) => { // Compilation should succeed without retry if we redirect assembly refs correctly. // Throwing so that we don't loop forever (as we did before fix)... throw ExceptionUtilities.Unreachable; }, out errorMessage, out testData); Assert.Null(errorMessage); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 IL_0001: callvirt ""Windows.UI.Core.CoreDispatcher Windows.UI.Xaml.DependencyObject.Dispatcher.get"" IL_0006: ret }"); }); }
public void Exception() { var source = @"class C { static void M() { } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, "C.M"); var aliases = ImmutableArray.Create( ExceptionAlias(typeof(System.IO.IOException)), ExceptionAlias(typeof(InvalidOperationException), stowed: true)); string error; var testData = new CompilationTestData(); var result = context.CompileExpression( "(System.Exception)$exception ?? $stowedexception", DkmEvaluationFlags.TreatAsExpression, aliases, out error, testData); Assert.Null(error); Assert.Equal(testData.Methods.Count, 1); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 25 (0x19) .maxstack 2 IL_0000: call ""System.Exception Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetException()"" IL_0005: castclass ""System.IO.IOException"" IL_000a: dup IL_000b: brtrue.s IL_0018 IL_000d: pop IL_000e: call ""System.Exception Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetStowedException()"" IL_0013: castclass ""System.InvalidOperationException"" IL_0018: ret }"); }
public void Win8RuntimeAssemblies_ExternAlias() { var source = @"extern alias X; class C { static void M(X::Windows.Storage.StorageFolder f) { } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName(), references: WinRtRefs.Select(r => r.Display == "Windows" ? r.WithAliases(new[] { "X" }) : r)); var runtimeAssemblies = ExpressionCompilerTestHelpers.GetRuntimeWinMds("Windows.Storage"); Assert.True(runtimeAssemblies.Length >= 1); // no reference to Windows.winmd WithRuntimeInstance(compilation0, new[] { MscorlibRef }.Concat(runtimeAssemblies), runtime => { var context = CreateMethodContext(runtime, "C.M"); string error; var testData = new CompilationTestData(); context.CompileExpression("X::Windows.Storage.FileProperties.PhotoOrientation.Unspecified", out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 2 (0x2) .maxstack 1 IL_0000: ldc.i4.0 IL_0001: ret }"); }); }
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 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, methodName: "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(locals.Count, 3); 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", 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(); }
public void UserVariableOfPointerType() { var source = @"class C { static void M() { } }"; var comp = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll, assemblyName: GetUniqueName()); var runtime = CreateRuntimeInstance(comp); var context = CreateMethodContext(runtime, "C.M"); var aliases = ImmutableArray.Create(VariableAlias("p", typeof(char*))); string error; var testData = new CompilationTestData(); var result = context.CompileExpression( "p", DkmEvaluationFlags.TreatAsExpression, aliases, out error, testData); var methodData = testData.GetMethodData("<>x.<>m0"); Assert.Equal(SpecialType.System_Char, ((PointerTypeSymbol)methodData.Method.ReturnType).PointedAtType.SpecialType); methodData.VerifyIL( @"{ // Code size 21 (0x15) .maxstack 1 IL_0000: ldstr ""p"" IL_0005: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_000a: unbox.any ""System.IntPtr"" IL_000f: call ""void* System.IntPtr.op_Explicit(System.IntPtr)"" IL_0014: ret }"); }
public void AssignmentToLockLocal() { var source = @" class C { void M(object o) { lock(o) { #line 999 int x = 1; } } } "; var comp = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); var runtime = CreateRuntimeInstance(comp); var context = CreateMethodContext( runtime, methodName: "C.M", atLineNumber: 999); ResultProperties resultProperties; string error; var testData = new CompilationTestData(); context.CompileExpression("o = null", out resultProperties, 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 }"); }
public void ReturnValue() { var source = @"class C { static void M() { } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, "C.M"); var aliases = ImmutableArray.Create( ReturnValueAlias(type: typeof(object)), ReturnValueAlias(2, typeof(string))); string error; var testData = new CompilationTestData(); var result = context.CompileExpression( "$ReturnValue ?? $ReturnValue2", DkmEvaluationFlags.TreatAsExpression, aliases, out error, testData); Assert.Equal(testData.Methods.Count, 1); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 22 (0x16) .maxstack 2 IL_0000: ldc.i4.0 IL_0001: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetReturnValue(int)"" IL_0006: dup IL_0007: brtrue.s IL_0015 IL_0009: pop IL_000a: ldc.i4.2 IL_000b: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetReturnValue(int)"" IL_0010: castclass ""string"" IL_0015: ret }"); // Value type $ReturnValue. context = CreateMethodContext( runtime, "C.M"); aliases = ImmutableArray.Create( ReturnValueAlias(type: typeof(int?))); testData = new CompilationTestData(); result = context.CompileExpression( "((int?)$ReturnValue).HasValue", DkmEvaluationFlags.TreatAsExpression, aliases, out error, testData); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 20 (0x14) .maxstack 1 .locals init (int? V_0) IL_0000: ldc.i4.0 IL_0001: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetReturnValue(int)"" IL_0006: unbox.any ""int?"" IL_000b: stloc.0 IL_000c: ldloca.s V_0 IL_000e: call ""bool int?.HasValue.get"" IL_0013: ret }"); }
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 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugExe); byte[] exeBytes; byte[] pdbBytes; ImmutableArray<MetadataReference> references; compilation0.EmitAndGetReferences(out exeBytes, out pdbBytes, out references); var constantSignatures = ImmutableDictionary.CreateRange( new Dictionary<string, byte[]>() { { "y", new byte[] { 0x11, 0x08 } } }); var runtime = CreateRuntimeInstance(ExpressionCompilerUtilities.GenerateUniqueName(), references, exeBytes, new SymReader(pdbBytes, constantSignatures)); var context = CreateMethodContext( runtime, methodName: "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(locals.Count, 2); 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", DkmClrCompilationResultFlags.ReadOnlyResult, expectedILOpt: @"{ // Code size 2 (0x2) .maxstack 1 IL_0000: ldc.i4.1 IL_0001: ret }"); locals.Free(); }
public void ObjectId() { var source = @"class C { static void M() { } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, "C.M"); var aliases = ImmutableArray.Create( ObjectIdAlias(23, typeof(string)), ObjectIdAlias(4, typeof(Type))); string error; var testData = new CompilationTestData(); context.CompileExpression( "(object)$23 ?? $4.BaseType", DkmEvaluationFlags.TreatAsExpression, aliases, out error, testData); Assert.Equal(testData.Methods.Count, 1); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 40 (0x28) .maxstack 2 IL_0000: ldstr ""$23"" IL_0005: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_000a: castclass ""string"" IL_000f: dup IL_0010: brtrue.s IL_0027 IL_0012: pop IL_0013: ldstr ""$4"" IL_0018: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_001d: castclass ""System.Type"" IL_0022: callvirt ""System.Type System.Type.BaseType.get"" IL_0027: ret }"); }
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 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, methodName: "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(locals.Count, 6); 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", 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(); }
public void NestedGenericValueType() { var source = @"class C { internal struct S<T> { internal T F; } static void M() { } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, "C.M"); var aliases = ImmutableArray.Create( VariableAlias("s", "C+S`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]")); ResultProperties resultProperties; string error; ImmutableArray<AssemblyIdentity> missingAssemblyIdentities; var testData = new CompilationTestData(); context.CompileExpression( "s.F + 1", DkmEvaluationFlags.TreatAsExpression, aliases, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, null, // preferredUICulture testData); Assert.Empty(missingAssemblyIdentities); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 23 (0x17) .maxstack 2 IL_0000: ldstr ""s"" IL_0005: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_000a: unbox.any ""C.S<int>"" IL_000f: ldfld ""int C.S<int>.F"" IL_0014: ldc.i4.1 IL_0015: add IL_0016: ret }"); }