internal abstract ReadOnlyCollection <byte> CompileGetLocals( ArrayBuilder <LocalAndMethod> locals, bool argumentsOnly, out string typeName, CompilationTestData testData);
public void CorLibWithAssemblyReferences_Pdb() { string sourceLib = @"namespace Namespace { public class Private { } }"; var compLib = CreateStandardCompilation(sourceLib, assemblyName: "System.Private.Library"); compLib.VerifyDiagnostics(); var refLib = compLib.EmitToImageReference(aliases: ImmutableArray.Create("A")); string sourceCorLib = @"extern alias A; #pragma warning disable 8019 using N = A::Namespace; namespace System { public class Object { public void F() { } } #pragma warning disable 0436 public class Void : Object { } #pragma warning restore 0436 }"; // Create a custom corlib with a reference to compilation // above and a reference to the actual mscorlib. var compCorLib = CreateCompilation(sourceCorLib, assemblyName: CorLibAssemblyName, references: new[] { MscorlibRef, refLib }); compCorLib.VerifyDiagnostics(); var objectType = compCorLib.SourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("System.Object"); Assert.NotNull(objectType.BaseType); var pdbPath = Temp.CreateDirectory().Path; ImmutableArray <byte> peBytes; ImmutableArray <byte> pdbBytes; ExpressionCompilerTestHelpers.EmitCorLibWithAssemblyReferences( compCorLib, pdbPath, (moduleBuilder, emitOptions) => new PEAssemblyBuilderWithAdditionalReferences(moduleBuilder, emitOptions, objectType), out peBytes, out pdbBytes); var symReader = SymReaderFactory.CreateReader(pdbBytes); using (var reader = new PEReader(peBytes)) { var metadata = reader.GetMetadata(); var module = metadata.ToModuleMetadata(ignoreAssemblyRefs: true); var metadataReader = metadata.ToMetadataReader(); var moduleInstance = ModuleInstance.Create(metadata, metadataReader.GetModuleVersionIdOrThrow(), symReader); // Verify the module declares System.Object. Assert.True(metadataReader.DeclaresTheObjectClass()); // Verify the PEModule has no assembly references. Assert.Equal(0, module.Module.ReferencedAssemblies.Length); // Verify the underlying metadata has the expected assembly references. var actualReferences = metadataReader.AssemblyReferences.Select(r => metadataReader.GetString(metadataReader.GetAssemblyReference(r).Name)).ToImmutableArray(); AssertEx.Equal(new[] { "mscorlib", "System.Private.Library" }, actualReferences); using (var runtime = RuntimeInstance.Create(new[] { moduleInstance })) { string error; var context = CreateMethodContext(runtime, "System.Object.F"); var testData = new CompilationTestData(); // Invalid import: "using N = A::Namespace;". context.CompileExpression( "new N.Private()", out error, testData); Assert.Equal("error CS0246: The type or namespace name 'N' could not be found (are you missing a using directive or an assembly reference?)", error); } } }
public void Alias() { var source = @"class C { static (int, int) F; static void M() { } }"; var comp = CreateCompilationWithMscorlib40(source, new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugDll); WithRuntimeInstance(comp, new[] { ValueTupleRef, SystemRuntimeFacadeRef, MscorlibRef }, runtime => { var context = CreateMethodContext( runtime, "C.M"); // (int A, (int, int D) B)[] t; var aliasElementNames = new ReadOnlyCollection <string>(new[] { "A", "B", null, "D" }); var alias = new Alias( DkmClrAliasKind.Variable, "t", "t", "System.ValueTuple`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.ValueTuple`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51]][], System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51", CustomTypeInfo.PayloadTypeId, CustomTypeInfo.Encode(null, aliasElementNames)); var locals = ArrayBuilder <LocalAndMethod> .GetInstance(); string typeName; var diagnostics = DiagnosticBag.GetInstance(); var testData = new CompilationTestData(); var assembly = context.CompileGetLocals( locals, argumentsOnly: false, aliases: ImmutableArray.Create(alias), diagnostics: diagnostics, typeName: out typeName, testData: testData); diagnostics.Verify(); diagnostics.Free(); Assert.Equal(locals.Count, 1); ReadOnlyCollection <byte> customTypeInfo; var customTypeInfoId = locals[0].GetCustomTypeInfo(out customTypeInfo); ReadOnlyCollection <byte> dynamicFlags; ReadOnlyCollection <string> tupleElementNames; CustomTypeInfo.Decode(customTypeInfoId, customTypeInfo, out dynamicFlags, out tupleElementNames); Assert.Equal(aliasElementNames, tupleElementNames); var method = testData.Methods.Single().Value.Method; CheckAttribute(assembly, method, AttributeDescription.TupleElementNamesAttribute, expected: true); var returnType = (TypeSymbol)method.ReturnType; Assert.False(returnType.IsTupleType); Assert.True(((ArrayTypeSymbol)returnType).ElementType.IsTupleType); VerifyLocal(testData, typeName, locals[0], "<>m0", "t", expectedILOpt: @"{ // Code size 16 (0x10) .maxstack 1 IL_0000: ldstr ""t"" IL_0005: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_000a: castclass ""(int A, (int, int D) B)[]"" IL_000f: ret }"); locals.Free(); }); }
public void PIATypeAndEmbeddedType() { var sourcePIA = @"using System.Runtime.InteropServices; [assembly: PrimaryInteropAssembly(0, 0)] [assembly: Guid(""863D5BC0-46A1-49AC-97AA-A5F0D441A9DC"")] [ComImport] [Guid(""863D5BC0-46A1-49AD-97AA-A5F0D441A9DC"")] public interface I { object F(); }"; var sourceA = @"public class A { public static void M(I x) { } }"; var sourceB = @"class B { static void Main() { I y = null; A.M(y); } }"; var compilationPIA = CreateCompilationWithMscorlib(sourcePIA, options: TestOptions.DebugDll); byte[] exePIA; byte[] pdbPIA; ImmutableArray <MetadataReference> referencesPIA; compilationPIA.EmitAndGetReferences(out exePIA, out pdbPIA, out referencesPIA); var metadataPIA = AssemblyMetadata.CreateFromImage(exePIA); var referencePIA = metadataPIA.GetReference(); // csc /t:library /l:PIA.dll A.cs var compilationA = CreateCompilationWithMscorlib( sourceA, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName(), references: new MetadataReference[] { metadataPIA.GetReference(embedInteropTypes: true) }); byte[] exeA; byte[] pdbA; ImmutableArray <MetadataReference> referencesA; compilationA.EmitAndGetReferences(out exeA, out pdbA, out referencesA); var metadataA = AssemblyMetadata.CreateFromImage(exeA); var referenceA = metadataA.GetReference(); // csc /r:A.dll /r:PIA.dll B.cs var compilationB = CreateCompilationWithMscorlib( sourceB, options: TestOptions.DebugExe, assemblyName: Guid.NewGuid().ToString("D"), references: new MetadataReference[] { metadataA.GetReference(), metadataPIA.GetReference() }); byte[] exeB; byte[] pdbB; ImmutableArray <MetadataReference> referencesB; compilationB.EmitAndGetReferences(out exeB, out pdbB, out referencesB); var metadataB = AssemblyMetadata.CreateFromImage(exeB); var referenceB = metadataB.GetReference(); // Create runtime from modules { mscorlib, PIA, A, B }. 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(referencePIA.ToModuleInstance(fullImage: null, symReader: null)); modulesBuilder.Add(referenceB.ToModuleInstance(fullImage: exeB, symReader: new SymReader(pdbB))); using (var runtime = new RuntimeInstance(modulesBuilder.ToImmutableAndFree())) { var context = CreateMethodContext(runtime, "A.M"); ResultProperties resultProperties; string error; // Bind to local of embedded PIA type. var testData = new CompilationTestData(); context.CompileExpression("x", out resultProperties, out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 2 (0x2) .maxstack 1 IL_0000: ldarg.0 IL_0001: ret }"); // Binding to method on original PIA should fail // since it was not included in embedded type. testData = new CompilationTestData(); context.CompileExpression("x.F()", out resultProperties, out error, testData); Assert.Equal(error, "error CS1061: 'I' does not contain a definition for 'F' and no extension method 'F' accepting a first argument of type 'I' could be found (are you missing a using directive or an assembly reference?)"); // Binding to method on original PIA should succeed // in assembly referencing PIA.dll. context = CreateMethodContext(runtime, "B.Main"); testData = new CompilationTestData(); context.CompileExpression("y.F()", out resultProperties, out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 7 (0x7) .maxstack 1 .locals init (I V_0) //y IL_0000: ldloc.0 IL_0001: callvirt ""object I.F()"" IL_0006: ret }"); } }
public void DuplicateTypesInMscorlib() { var sourceConsole = @"namespace System { public class Console { } }"; var sourceObjectModel = @"namespace System.Collections.ObjectModel { public class ReadOnlyDictionary<K, V> { } }"; var source = @"class C { static void Main() { var t = typeof(System.Console); var o = (System.Collections.ObjectModel.ReadOnlyDictionary<object, object>)null; } }"; var systemConsoleComp = CreateStandardCompilation(sourceConsole, options: TestOptions.DebugDll, assemblyName: "System.Console"); var systemConsoleRef = systemConsoleComp.EmitToImageReference(); var systemObjectModelComp = CreateStandardCompilation(sourceObjectModel, options: TestOptions.DebugDll, assemblyName: "System.ObjectModel"); var systemObjectModelRef = systemObjectModelComp.EmitToImageReference(); var identityObjectModel = systemObjectModelRef.GetAssemblyIdentity(); // At runtime System.Runtime.dll contract assembly is replaced // by mscorlib.dll and System.Runtime.dll facade assemblies; // System.Console.dll and System.ObjectModel.dll are not replaced. // Test different ordering of modules containing duplicates: // { System.Console, mscorlib } and { mscorlib, System.ObjectModel }. var contractReferences = ImmutableArray.Create(systemConsoleRef, SystemRuntimePP7Ref, systemObjectModelRef); var runtimeReferences = ImmutableArray.Create(systemConsoleRef, MscorlibFacadeRef, SystemRuntimeFacadeRef, systemObjectModelRef); // Verify the compiler reports duplicate types with facade assemblies. var compilation = CreateCompilation( source, references: runtimeReferences, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); compilation.VerifyDiagnostics( // error CS0433: The type 'Console' exists in both 'System.Console, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' // var t = typeof(System.Console); Diagnostic(ErrorCode.ERR_SameFullNameAggAgg, "Console").WithArguments("System.Console, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "System.Console", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089").WithLocation(5, 31), // error CS0433: The type 'ReadOnlyDictionary<K, V>' exists in both 'System.ObjectModel, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' // var o = (System.Collections.ObjectModel.ReadOnlyDictionary<object, object>)null; Diagnostic(ErrorCode.ERR_SameFullNameAggAgg, "ReadOnlyDictionary<object, object>").WithArguments("System.ObjectModel, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "System.Collections.ObjectModel.ReadOnlyDictionary<K, V>", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089").WithLocation(6, 49)); // EE should not report duplicate type when the original source // is compiled with contract assemblies and the EE expression // is compiled with facade assemblies. compilation = CreateCompilation( source, references: contractReferences, options: TestOptions.DebugDll); WithRuntimeInstance(compilation, runtimeReferences, runtime => { var context = CreateMethodContext(runtime, "C.Main"); string errorMessage; // { System.Console, mscorlib } var testData = new CompilationTestData(); context.CompileExpression("typeof(System.Console)", out errorMessage, testData); var methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL(@" { // Code size 11 (0xb) .maxstack 1 .locals init (System.Type V_0, //t System.Collections.ObjectModel.ReadOnlyDictionary<object, object> V_1) //o IL_0000: ldtoken ""System.Console"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ret }"); // { mscorlib, System.ObjectModel } testData = new CompilationTestData(); context.CompileExpression("(System.Collections.ObjectModel.ReadOnlyDictionary<object, object>)null", out errorMessage, testData); methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL(@" { // Code size 2 (0x2) .maxstack 1 .locals init (System.Type V_0, //t System.Collections.ObjectModel.ReadOnlyDictionary<object, object> V_1) //o IL_0000: ldnull IL_0001: ret }"); Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityObjectModel.GetDisplayName()); }); }
public void ReferenceInSameDeclaration() { 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, methodName: "C.M"); ResultProperties resultProperties; string error; ImmutableArray <AssemblyIdentity> missingAssemblyIdentities; var testData = new CompilationTestData(); context.CompileExpression( InspectionContextFactory.Empty, "object o = o ?? null;", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); // The compiler reports "CS0165: Use of unassigned local variable 'o'" // in flow analysis. But since flow analysis is skipped in the EE, // compilation succeeds and references to the local in the initializer // are treated as default(T). That matches the legacy EE. Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 47 (0x2f) .maxstack 3 IL_0000: ldtoken ""object"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""o"" IL_000f: call ""void <>x.<>CreateVariable(System.Type, string)"" IL_0014: ldstr ""o"" IL_0019: call ""object <>x.<>GetVariableAddress<object>(string)"" IL_001e: ldstr ""o"" IL_0023: call ""object <>x.<>GetObjectByAlias(string)"" IL_0028: dup IL_0029: brtrue.s IL_002d IL_002b: pop IL_002c: ldnull IL_002d: stind.ref IL_002e: ret }"); testData = new CompilationTestData(); context.CompileExpression( InspectionContextFactory.Empty, "string s = s.Substring(0);", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 53 (0x35) .maxstack 3 IL_0000: ldtoken ""string"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""s"" IL_000f: call ""void <>x.<>CreateVariable(System.Type, string)"" IL_0014: ldstr ""s"" IL_0019: call ""string <>x.<>GetVariableAddress<string>(string)"" IL_001e: ldstr ""s"" IL_0023: call ""object <>x.<>GetObjectByAlias(string)"" IL_0028: castclass ""string"" IL_002d: ldc.i4.0 IL_002e: callvirt ""string string.Substring(int)"" IL_0033: stind.ref IL_0034: ret }"); }
internal override CommonPEModuleBuilder CreateModuleBuilder(EmitOptions emitOptions, IMethodSymbol debugEntryPoint, Stream sourceLinkStream, IEnumerable <EmbeddedText> embeddedTexts, IEnumerable <ResourceDescription> manifestResources, CompilationTestData testData, DiagnosticBag diagnostics, CancellationToken cancellationToken) { Debug.Assert(!IsSubmission || HasCodeToEmit()); var runtimeMDVersion = GetRuntimeMetadataVersion(emitOptions, diagnostics); if (runtimeMDVersion == null) { Debug.Assert(runtimeMDVersion != null, "Set PhpCommandLineArguments.EmitOptions"); return(null); } var moduleProps = ConstructModuleSerializationProperties(emitOptions, runtimeMDVersion); if (manifestResources == null) { manifestResources = SpecializedCollections.EmptyEnumerable <ResourceDescription>(); } if (SynthesizedResources != null) { manifestResources = manifestResources.Concat(SynthesizedResources); } if (Options.EmbedSourceMetadata) { manifestResources = manifestResources.Concat(new[] { SourceMetadataResource() }); } PEModuleBuilder moduleBeingBuilt; if (_options.OutputKind.IsNetModule()) { moduleBeingBuilt = new PENetModuleBuilder( this, SourceModule, emitOptions, moduleProps, manifestResources); } else { var kind = _options.OutputKind.IsValid() ? _options.OutputKind : OutputKind.DynamicallyLinkedLibrary; moduleBeingBuilt = new PEAssemblyBuilder( SourceAssembly, moduleProps, manifestResources, kind, emitOptions); } if (debugEntryPoint != null) { moduleBeingBuilt.SetDebugEntryPoint(debugEntryPoint, diagnostics); } moduleBeingBuilt.SourceLinkStreamOpt = sourceLinkStream; if (embeddedTexts != null) { moduleBeingBuilt.EmbeddedTexts = embeddedTexts; } // testData is only passed when running tests. if (testData != null) { //moduleBeingBuilt.SetMethodTestData(testData.Methods); //testData.Module = moduleBeingBuilt; throw new NotImplementedException(); } return(moduleBeingBuilt); }
private static void CompileDeclaration(EvaluationContext context, string declaration, out DkmClrCompilationResultFlags flags, out CompilationTestData testData) { testData = new CompilationTestData(); ResultProperties resultProperties; string error; ImmutableArray <AssemblyIdentity> missingAssemblyIdentities; var result = context.CompileExpression( declaration, DkmEvaluationFlags.None, NoAliases, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Null(error); Assert.Empty(missingAssemblyIdentities); flags = resultProperties.Flags; }
public void ReferenceInNextDeclaration() { var source = @"class C { static void M<T>() { } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, methodName: "C.M"); string error; var testData = new CompilationTestData(); context.CompileExpression( "T x = default(T), y = x;", DkmEvaluationFlags.None, NoAliases, out error, testData); testData.GetMethodData("<>x.<>m0<T>").VerifyIL( @"{ // Code size 115 (0x73) .maxstack 4 .locals init (System.Guid V_0, T V_1) IL_0000: ldtoken ""T"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""x"" IL_000f: ldloca.s V_0 IL_0011: initobj ""System.Guid"" IL_0017: ldloc.0 IL_0018: ldnull IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" IL_001e: ldstr ""x"" IL_0023: call ""T Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress<T>(string)"" IL_0028: ldloca.s V_1 IL_002a: initobj ""T"" IL_0030: ldloc.1 IL_0031: stobj ""T"" IL_0036: ldtoken ""T"" IL_003b: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_0040: ldstr ""y"" IL_0045: ldloca.s V_0 IL_0047: initobj ""System.Guid"" IL_004d: ldloc.0 IL_004e: ldnull IL_004f: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" IL_0054: ldstr ""y"" IL_0059: call ""T Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress<T>(string)"" IL_005e: ldstr ""x"" IL_0063: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_0068: unbox.any ""T"" IL_006d: stobj ""T"" IL_0072: ret }"); }
public void PassByRef() { var source = @"class C { static T F<T>(ref T t) { t = default(T); return t; } }"; var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll); WithRuntimeInstance(compilation0, runtime => { 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 value 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 value 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 value 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 value 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 }"); }); }
public void DifferentAssemblyVersion() { var sourceA = @"public class A<T> { }"; var sourceB = @"class B<T> { } class C { static void M() { var o = new A<object>(); } }"; const string assemblyNameA = "397300B0-A"; const string assemblyNameB = "397300B0-B"; 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 compilationB1 = CreateCompilation( new AssemblyIdentity(assemblyNameB, new Version(1, 2, 2, 2)), new[] { sourceB }, references: new[] { MscorlibRef_v20, compilationA1.EmitToImageReference() }, options: TestOptions.DebugDll); // Use mscorlib v4.0.0.0 and A v2.1.2.1 at runtime. 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)); WithRuntimeInstance(compilationB1, new[] { MscorlibRef, compilationA2.EmitToImageReference() }, runtime => { // 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 ReturnValue() { var source = @"class C { static void M() { } }"; var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll); WithRuntimeInstance(compilation0, runtime => { 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 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 = CreateCompilation(sourceA, options: TestOptions.DebugDll, assemblyName: assemblyNameA); var moduleA = compilationA.ToModuleInstance(); var assemblyNameB = "9BAC6622-86EB-4EC5-94A1-9A1E6D0C24B9"; var compilationB = CreateCompilation(sourceB, options: TestOptions.DebugExe, references: new[] { moduleA.GetReference() }, assemblyName: assemblyNameB); var moduleB = compilationB.ToModuleInstance(); var runtime = CreateRuntimeInstance(new[] { MscorlibRef.ToModuleInstance(), moduleA, moduleB, ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance() }); 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, DebuggerDiagnosticFormatter.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 HoistedAnonymousTypes_Complex() { var source0 = @" using System; class C { static void F() { var x1 = new[] { new { A = new { X = 1 } } }; var x2 = new[] { new { A = new { Y = 1 } } }; var y = new Func<int>(() => x1[0].A.X + x2[0].A.Y); } } "; var source1 = @" using System; class C { static void F() { var x1 = new[] { new { A = new { X = 1 } } }; var x2 = new[] { new { A = new { Z = 1 } } }; var y = new Func<int>(() => x1[0].A.X + x2[0].A.Z); } }"; var compilation0 = CreateStandardCompilation(source0, options: TestOptions.DebugDll); var peRef0 = compilation0.EmitToImageReference(); var peAssemblySymbol0 = (PEAssemblySymbol)CreateStandardCompilation("", new[] { peRef0 }).GetReferencedAssemblySymbol(peRef0); var peModule0 = (PEModuleSymbol)peAssemblySymbol0.Modules[0]; var reader0 = peModule0.Module.MetadataReader; var decoder0 = new MetadataDecoder(peModule0); var anonymousTypeMap0 = PEDeltaAssemblyBuilder.GetAnonymousTypeMapFromMetadata(reader0, decoder0); Assert.Equal("<>f__AnonymousType0", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("A", isKey: false, ignoreCase: false)))].Name); Assert.Equal("<>f__AnonymousType1", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("X", isKey: false, ignoreCase: false)))].Name); Assert.Equal("<>f__AnonymousType2", anonymousTypeMap0[new AnonymousTypeKey(ImmutableArray.Create(new AnonymousTypeKeyField("Y", isKey: false, ignoreCase: false)))].Name); Assert.Equal(3, anonymousTypeMap0.Count); var compilation1 = CreateStandardCompilation(source1, options: TestOptions.DebugDll); var testData = new CompilationTestData(); compilation1.EmitToArray(testData: testData); var peAssemblyBuilder = (PEAssemblyBuilder)testData.Module; var c = compilation1.GetMember <NamedTypeSymbol>("C"); var displayClass = peAssemblyBuilder.GetSynthesizedTypes(c).Single(); Assert.Equal("<>c__DisplayClass0_0", displayClass.Name); var emitContext = new EmitContext(peAssemblyBuilder, null, new DiagnosticBag()); var fields = displayClass.GetFields(emitContext).ToArray(); AssertEx.SetEqual(fields.Select(f => f.Name), new[] { "x1", "x2" }); var x1 = fields.Where(f => f.Name == "x1").Single(); var x2 = fields.Where(f => f.Name == "x2").Single(); var matcher = new CSharpSymbolMatcher(anonymousTypeMap0, compilation1.SourceAssembly, emitContext, peAssemblySymbol0); var mappedX1 = (Cci.IFieldDefinition)matcher.MapDefinition(x1); var mappedX2 = (Cci.IFieldDefinition)matcher.MapDefinition(x2); Assert.Equal("x1", mappedX1.Name); Assert.Null(mappedX2); }
public void TreatAsExpression() { var source = @"class C { static void M(object x) { } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, methodName: "C.M"); ResultProperties resultProperties; string error; ImmutableArray <AssemblyIdentity> missingAssemblyIdentities; // Expression without ';' as statement. var testData = new CompilationTestData(); var result = context.CompileExpression(InspectionContextFactory.Empty, "3", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Null(error); // Expression with ';' as statement. testData = new CompilationTestData(); result = context.CompileExpression(InspectionContextFactory.Empty, "3;", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Null(error); // Expression with format specifiers but without ';' as statement. testData = new CompilationTestData(); result = context.CompileExpression(InspectionContextFactory.Empty, "string.Empty, nq", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Null(error); AssertEx.SetEqual(result.FormatSpecifiers, new[] { "nq" }); // Expression with format specifiers with ';' as statement. testData = new CompilationTestData(); result = context.CompileExpression(InspectionContextFactory.Empty, "string.Empty, nq;", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Equal(error, "(1,13): error CS1002: ; expected"); Assert.Equal(result.FormatSpecifiers, null); // Assignment without ';' as statement. testData = new CompilationTestData(); result = context.CompileExpression(InspectionContextFactory.Empty, "x = 2", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Null(error); // Assignment with ';' as statement. testData = new CompilationTestData(); result = context.CompileExpression(InspectionContextFactory.Empty, "x = 2;", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Null(error); // Statement without ';' as statement. testData = new CompilationTestData(); result = context.CompileExpression(InspectionContextFactory.Empty, "int o", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Equal(error, "(1,6): error CS1002: ; expected"); // Neither statement nor expression as statement. testData = new CompilationTestData(); result = context.CompileExpression(InspectionContextFactory.Empty, "M(;", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Equal(error, "(1,3): error CS1026: ) expected"); // Statement without ';' as expression. testData = new CompilationTestData(); result = context.CompileExpression(InspectionContextFactory.Empty, "int o", DkmEvaluationFlags.TreatAsExpression, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Equal(error, "(1,1): error CS1525: Invalid expression term 'int'"); // Statement with ';' as expression. testData = new CompilationTestData(); result = context.CompileExpression(InspectionContextFactory.Empty, "int o;", DkmEvaluationFlags.TreatAsExpression, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Equal(error, "(1,1): error CS1525: Invalid expression term 'int'"); // Neither statement nor expression as expression. testData = new CompilationTestData(); result = context.CompileExpression(InspectionContextFactory.Empty, "M(;", DkmEvaluationFlags.TreatAsExpression, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Equal(error, "(1,3): error CS1026: ) expected"); }
public void ReferenceInSameDeclaration() { 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, methodName: "C.M"); string error; var testData = new CompilationTestData(); context.CompileExpression( "object o = o ?? null;", DkmEvaluationFlags.None, NoAliases, out error, testData); // The compiler reports "CS0165: Use of unassigned local variable 'o'" // in flow analysis. But since flow analysis is skipped in the EE, // compilation succeeds and references to the local in the initializer // are treated as default(T). That matches the legacy EE. Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 57 (0x39) .maxstack 4 .locals init (System.Guid V_0) IL_0000: ldtoken ""object"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""o"" IL_000f: ldloca.s V_0 IL_0011: initobj ""System.Guid"" IL_0017: ldloc.0 IL_0018: ldnull IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" IL_001e: ldstr ""o"" IL_0023: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress<object>(string)"" IL_0028: ldstr ""o"" IL_002d: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_0032: dup IL_0033: brtrue.s IL_0037 IL_0035: pop IL_0036: ldnull IL_0037: stind.ref IL_0038: ret }"); testData = new CompilationTestData(); context.CompileExpression( "string s = s.Substring(0);", DkmEvaluationFlags.None, NoAliases, out error, testData); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 63 (0x3f) .maxstack 4 .locals init (System.Guid V_0) IL_0000: ldtoken ""string"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""s"" IL_000f: ldloca.s V_0 IL_0011: initobj ""System.Guid"" IL_0017: ldloc.0 IL_0018: ldnull IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" IL_001e: ldstr ""s"" IL_0023: call ""string Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress<string>(string)"" IL_0028: ldstr ""s"" IL_002d: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_0032: castclass ""string"" IL_0037: ldc.i4.0 IL_0038: callvirt ""string string.Substring(int)"" IL_003d: stind.ref IL_003e: ret }"); }
public void ReferenceInNextDeclaration() { var source = @"class C { static void M<T>() { } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, methodName: "C.M"); ResultProperties resultProperties; string error; ImmutableArray <AssemblyIdentity> missingAssemblyIdentities; var testData = new CompilationTestData(); context.CompileExpression( InspectionContextFactory.Empty, "T x = default(T), y = x;", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); testData.GetMethodData("<>x.<>m0<T>").VerifyIL( @"{ // Code size 95 (0x5f) .maxstack 2 .locals init (T V_0) IL_0000: ldtoken ""T"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""x"" IL_000f: call ""void <>x.<>CreateVariable(System.Type, string)"" IL_0014: ldstr ""x"" IL_0019: call ""T <>x.<>GetVariableAddress<T>(string)"" IL_001e: ldloca.s V_0 IL_0020: initobj ""T"" IL_0026: ldloc.0 IL_0027: stobj ""T"" IL_002c: ldtoken ""T"" IL_0031: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_0036: ldstr ""y"" IL_003b: call ""void <>x.<>CreateVariable(System.Type, string)"" IL_0040: ldstr ""y"" IL_0045: call ""T <>x.<>GetVariableAddress<T>(string)"" IL_004a: ldstr ""x"" IL_004f: call ""object <>x.<>GetObjectByAlias(string)"" IL_0054: unbox.any ""T"" IL_0059: stobj ""T"" IL_005e: ret }"); }
public void References() { var source = @"class C { delegate void D(); internal object F; static object G; static void M<T>(object x) { object y; } }"; 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("x", typeof(string)), VariableAlias("y", typeof(int)), VariableAlias("T", typeof(object)), VariableAlias("D", "C"), VariableAlias("F", typeof(int))); string error; var testData = new CompilationTestData(); context.CompileExpression( "(object)x ?? (object)y ?? (object)T ?? (object)F ?? ((C)D).F ?? C.G", DkmEvaluationFlags.TreatAsExpression, aliases, out error, testData); Assert.Equal(testData.Methods.Count, 1); testData.GetMethodData("<>x.<>m0<T>").VerifyIL( @"{ // Code size 78 (0x4e) .maxstack 2 .locals init (object V_0) //y IL_0000: ldarg.0 IL_0001: dup IL_0002: brtrue.s IL_004d IL_0004: pop IL_0005: ldloc.0 IL_0006: dup IL_0007: brtrue.s IL_004d IL_0009: pop IL_000a: ldstr ""T"" IL_000f: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_0014: dup IL_0015: brtrue.s IL_004d IL_0017: pop IL_0018: ldstr ""F"" IL_001d: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_0022: unbox.any ""int"" IL_0027: box ""int"" IL_002c: dup IL_002d: brtrue.s IL_004d IL_002f: pop IL_0030: ldstr ""D"" IL_0035: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_003a: castclass ""C"" IL_003f: ldfld ""object C.F"" IL_0044: dup IL_0045: brtrue.s IL_004d IL_0047: pop IL_0048: ldsfld ""object C.G"" IL_004d: ret }"); }
public void PIATypeAndEmbeddedType() { var sourcePIA = @"using System.Runtime.InteropServices; [assembly: PrimaryInteropAssembly(0, 0)] [assembly: Guid(""863D5BC0-46A1-49AC-97AA-A5F0D441A9DC"")] [ComImport] [Guid(""863D5BC0-46A1-49AD-97AA-A5F0D441A9DC"")] public interface I { object F(); }"; var sourceA = @"public class A { public static void M(I x) { } }"; var sourceB = @"class B { static void Main() { I y = null; A.M(y); } }"; var modulePIA = CreateCompilation(sourcePIA, options: TestOptions.DebugDll).ToModuleInstance(); // csc /t:library /l:PIA.dll A.cs var moduleA = CreateCompilation( sourceA, options: TestOptions.DebugDll, references: new[] { modulePIA.GetReference().WithEmbedInteropTypes(true) }).ToModuleInstance(); // csc /r:A.dll /r:PIA.dll B.cs var moduleB = CreateCompilation( sourceB, options: TestOptions.DebugExe, references: new[] { moduleA.GetReference(), modulePIA.GetReference() }).ToModuleInstance(); var runtime = CreateRuntimeInstance(new[] { MscorlibRef.ToModuleInstance(), moduleA, modulePIA, moduleB }); var context = CreateMethodContext(runtime, "A.M"); ResultProperties resultProperties; string error; // Bind to local of embedded PIA type. var testData = new CompilationTestData(); context.CompileExpression("x", out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 2 (0x2) .maxstack 1 IL_0000: ldarg.0 IL_0001: ret }"); // Binding to method on original PIA should fail // since it was not included in embedded type. ImmutableArray <AssemblyIdentity> missingAssemblyIdentities; context.CompileExpression( "x.F()", DkmEvaluationFlags.TreatAsExpression, NoAliases, DebuggerDiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData: null); AssertEx.SetEqual(missingAssemblyIdentities, EvaluationContextBase.SystemCoreIdentity); Assert.Equal(error, "error CS1061: 'I' does not contain a definition for 'F' and no extension method 'F' accepting a first argument of type 'I' could be found (are you missing a using directive or an assembly reference?)"); // Binding to method on original PIA should succeed // in assembly referencing PIA.dll. context = CreateMethodContext(runtime, "B.Main"); testData = new CompilationTestData(); context.CompileExpression("y.F()", out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 7 (0x7) .maxstack 1 .locals init (I V_0) //y IL_0000: ldloc.0 IL_0001: callvirt ""object I.F()"" IL_0006: ret }"); }
public void CapturedVariable() { var source = @"class C { int x; void F(int y) { int G() { return x + y; }; int z = G(); } }"; var compilation0 = CreateCompilation(source, options: TestOptions.DebugDll); WithRuntimeInstance(compilation0, runtime => { var context = CreateMethodContext(runtime, "C.<F>g__G|1_0"); 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 7 (0x7) .maxstack 1 .locals init (int V_0) IL_0000: ldarg.1 IL_0001: ldfld ""C C.<>c__DisplayClass1_0.<>4__this"" IL_0006: ret }"); VerifyLocal(testData, typeName, locals[1], "<>m1", "y", expectedILOpt: @"{ // Code size 7 (0x7) .maxstack 1 .locals init (int V_0) IL_0000: ldarg.1 IL_0001: ldfld ""int C.<>c__DisplayClass1_0.y"" IL_0006: ret }"); locals.Free(); testData = new CompilationTestData(); string error; context.CompileExpression("this.F(1)", out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 13 (0xd) .maxstack 2 .locals init (int V_0) IL_0000: ldarg.1 IL_0001: ldfld ""C C.<>c__DisplayClass1_0.<>4__this"" IL_0006: ldc.i4.1 IL_0007: callvirt ""void C.F(int)"" IL_000c: ret }"); }); }
internal override EmitDifferenceResult EmitDifference(EmitBaseline baseline, IEnumerable <SemanticEdit> edits, Func <ISymbol, bool> isAddedSymbol, Stream metadataStream, Stream ilStream, Stream pdbStream, ICollection <MethodDefinitionHandle> updatedMethodHandles, CompilationTestData testData, CancellationToken cancellationToken) { throw new NotImplementedException(); }
public void DisallowSizeof() { var source = @" class C { void M<T>() { } } delegate void D(); interface I { } enum E { A } "; var comp = CreateCompilation(source, options: TestOptions.DebugDll); WithRuntimeInstance( comp, runtime => { var context = CreateMethodContext(runtime, "C.M"); var types = new[] { "C", // class "D", // delegate "I", // interface "T", // type parameter "int[]", "dynamic", }; foreach (var type in types) { string error; CompilationTestData testData = new CompilationTestData(); context.CompileExpression( string.Format("sizeof({0})", type), out error, testData ); // CONSIDER: change error code to make text less confusing? Assert.Equal( string.Format( "error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('{0}')", type ), error ); } } ); }
public void AssemblyDuplicateReferences() { var sourceA = @"public class A { }"; var sourceB = @"public class B { public A F = new A(); }"; var sourceC = @"class C { private B F = new B(); static void M() { } }"; // Assembly A, multiple versions, strong name. var assemblyNameA = ExpressionCompilerUtilities.GenerateUniqueName(); 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 compilationAS1 = CreateCompilation( new AssemblyIdentity(assemblyNameA, new Version(1, 1, 1, 1), cultureName: "", publicKeyOrToken: publicKeyA, hasPublicKey: true), new[] { sourceA }, references: new[] { MscorlibRef }, options: TestOptions.DebugDll.WithDelaySign(true)); var referenceAS1 = compilationAS1.EmitToImageReference(); var identityAS1 = referenceAS1.GetAssemblyIdentity(); var compilationAS2 = CreateCompilation( new AssemblyIdentity(assemblyNameA, new Version(2, 1, 1, 1), cultureName: "", publicKeyOrToken: publicKeyA, hasPublicKey: true), new[] { sourceA }, references: new[] { MscorlibRef }, options: TestOptions.DebugDll.WithDelaySign(true)); var referenceAS2 = compilationAS2.EmitToImageReference(); var identityAS2 = referenceAS2.GetAssemblyIdentity(); // Assembly B, multiple versions, not strong name. var assemblyNameB = ExpressionCompilerUtilities.GenerateUniqueName(); var compilationBN1 = CreateCompilation( new AssemblyIdentity(assemblyNameB, new Version(1, 1, 1, 1)), new[] { sourceB }, references: new[] { MscorlibRef, referenceAS1 }, options: TestOptions.DebugDll); var referenceBN1 = compilationBN1.EmitToImageReference(); var identityBN1 = referenceBN1.GetAssemblyIdentity(); var compilationBN2 = CreateCompilation( new AssemblyIdentity(assemblyNameB, new Version(2, 2, 2, 1)), new[] { sourceB }, references: new[] { MscorlibRef, referenceAS1 }, options: TestOptions.DebugDll); var referenceBN2 = compilationBN2.EmitToImageReference(); var identityBN2 = referenceBN2.GetAssemblyIdentity(); // Assembly B, multiple versions, strong name. var publicKeyB = ImmutableArray.CreateRange(new byte[] { 0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x53, 0x52, 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 compilationBS1 = CreateCompilation( new AssemblyIdentity(assemblyNameB, new Version(1, 1, 1, 1), cultureName: "", publicKeyOrToken: publicKeyB, hasPublicKey: true), new[] { sourceB }, references: new[] { MscorlibRef, referenceAS1 }, options: TestOptions.DebugDll.WithDelaySign(true)); var referenceBS1 = compilationBS1.EmitToImageReference(); var identityBS1 = referenceBS1.GetAssemblyIdentity(); var compilationBS2 = CreateCompilation( new AssemblyIdentity(assemblyNameB, new Version(2, 2, 2, 1), cultureName: "", publicKeyOrToken: publicKeyB, hasPublicKey: true), new[] { sourceB }, references: new[] { MscorlibRef, referenceAS2 }, options: TestOptions.DebugDll.WithDelaySign(true)); var referenceBS2 = compilationBS2.EmitToImageReference(); var identityBS2 = referenceBS2.GetAssemblyIdentity(); var mscorlibIdentity = MscorlibRef.GetAssemblyIdentity(); var mscorlib20Identity = MscorlibRef_v20.GetAssemblyIdentity(); var systemRefIdentity = SystemRef.GetAssemblyIdentity(); var systemRef20Identity = SystemRef_v20.GetAssemblyIdentity(); // No duplicates. VerifyAssemblyReferences( referenceBN1, ImmutableArray.Create(MscorlibRef, referenceAS1, referenceBN1), ImmutableArray.Create(mscorlibIdentity, identityAS1, identityBN1)); // No duplicates, extra references. VerifyAssemblyReferences( referenceAS1, ImmutableArray.Create(MscorlibRef, referenceBN1, referenceAS1, referenceBS2), ImmutableArray.Create(mscorlibIdentity, identityAS1)); // Strong-named, non-strong-named, and framework duplicates, same version (no aliases). VerifyAssemblyReferences( referenceBN2, ImmutableArray.Create(MscorlibRef, referenceAS1, MscorlibRef, referenceBN2, referenceBN2, referenceAS1, referenceAS1), ImmutableArray.Create(mscorlibIdentity, identityAS1, identityBN2)); // Strong-named, non-strong-named, and framework duplicates, different versions. VerifyAssemblyReferences( referenceBN1, ImmutableArray.Create(MscorlibRef, referenceAS1, MscorlibRef_v20, referenceAS2, referenceBN2, referenceBN1, referenceAS2, referenceAS1, referenceBN1), ImmutableArray.Create(mscorlibIdentity, identityAS2, identityBN2)); VerifyAssemblyReferences( referenceBN2, ImmutableArray.Create(MscorlibRef, referenceAS1, MscorlibRef_v20, referenceAS2, referenceBN2, referenceBN1, referenceAS2, referenceAS1, referenceBN1), ImmutableArray.Create(mscorlibIdentity, identityAS2, identityBN2)); // Strong-named, different versions. VerifyAssemblyReferences( referenceBS1, ImmutableArray.Create(MscorlibRef, referenceAS1, referenceAS2, referenceBS2, referenceBS1, referenceAS2, referenceAS1, referenceBS1), ImmutableArray.Create(mscorlibIdentity, identityAS2, identityBS2)); VerifyAssemblyReferences( referenceBS2, ImmutableArray.Create(MscorlibRef, referenceAS1, referenceAS2, referenceBS2, referenceBS1, referenceAS2, referenceAS1, referenceBS1), ImmutableArray.Create(mscorlibIdentity, identityAS2, identityBS2)); // Assembly C, multiple versions, not strong name. var compilationCN1 = CreateCompilation( new AssemblyIdentity("C", new Version(1, 1, 1, 1)), new[] { sourceC }, references: new[] { MscorlibRef, referenceBS1 }, options: TestOptions.DebugDll); // Duplicate assemblies, target module referencing BS1. WithRuntimeInstance(compilationCN1, new[] { MscorlibRef, referenceAS1, referenceAS2, referenceBS2, referenceBS1, referenceBS2 }, runtime => { ImmutableArray <MetadataBlock> typeBlocks; ImmutableArray <MetadataBlock> methodBlocks; Guid moduleVersionId; ISymUnmanagedReader symReader; int typeToken; int methodToken; int localSignatureToken; GetContextState(runtime, "C", out typeBlocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken); GetContextState(runtime, "C.M", out methodBlocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken); uint ilOffset = ExpressionCompilerTestHelpers.GetOffset(methodToken, symReader); // Compile expression with type context with all modules. var context = EvaluationContext.CreateTypeContext( default(CSharpMetadataContext), typeBlocks, moduleVersionId, typeToken); Assert.Equal(identityAS2, context.Compilation.GlobalNamespace.GetMembers("A").OfType <INamedTypeSymbol>().Single().ContainingAssembly.Identity); Assert.Equal(identityBS2, context.Compilation.GlobalNamespace.GetMembers("B").OfType <INamedTypeSymbol>().Single().ContainingAssembly.Identity); string error; // A could be ambiguous, but the ambiguity is resolved in favor of the newer assembly. var testData = new CompilationTestData(); context.CompileExpression("new A()", out error, testData); Assert.Null(error); // B could be ambiguous, but the ambiguity is resolved in favor of the newer assembly. testData = new CompilationTestData(); context.CompileExpression("new B()", out error, testData); Assert.Null(error); var previous = new CSharpMetadataContext(typeBlocks, context); // Compile expression with type context with referenced modules only. context = EvaluationContext.CreateTypeContext( typeBlocks.ToCompilationReferencedModulesOnly(moduleVersionId), moduleVersionId, typeToken); // A is unrecognized since there were no direct references to AS1 or AS2. testData = new CompilationTestData(); context.CompileExpression("new A()", out error, testData); Assert.Equal(error, "error CS0246: The type or namespace name 'A' could not be found (are you missing a using directive or an assembly reference?)"); testData = new CompilationTestData(); // B should be resolved to BS2. context.CompileExpression("new B()", out error, testData); var methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""B..ctor()"" IL_0005: ret }"); Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityBS2.GetDisplayName()); // B.F should result in missing assembly AS2 since there were no direct references to AS2. ResultProperties resultProperties; ImmutableArray <AssemblyIdentity> missingAssemblyIdentities; testData = new CompilationTestData(); context.CompileExpression( "(new B()).F", DkmEvaluationFlags.None, NoAliases, DebuggerDiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); AssertEx.Equal(missingAssemblyIdentities, ImmutableArray.Create(identityAS2)); // Compile expression with method context with all modules. context = EvaluationContext.CreateMethodContext( previous, methodBlocks, symReader, moduleVersionId, methodToken: methodToken, methodVersion: 1, ilOffset: ilOffset, localSignatureToken: localSignatureToken); Assert.Equal(previous.Compilation, context.Compilation); // re-use type context compilation testData = new CompilationTestData(); // A could be ambiguous, but the ambiguity is resolved in favor of the newer assembly. testData = new CompilationTestData(); context.CompileExpression("new A()", out error, testData); Assert.Null(error); // B could be ambiguous, but the ambiguity is resolved in favor of the newer assembly. testData = new CompilationTestData(); context.CompileExpression("new B()", out error, testData); Assert.Null(error); // Compile expression with method context with referenced modules only. context = EvaluationContext.CreateMethodContext( methodBlocks.ToCompilationReferencedModulesOnly(moduleVersionId), symReader, moduleVersionId, methodToken: methodToken, methodVersion: 1, ilOffset: ilOffset, localSignatureToken: localSignatureToken); // A is unrecognized since there were no direct references to AS1 or AS2. testData = new CompilationTestData(); context.CompileExpression("new A()", out error, testData); Assert.Equal(error, "error CS0246: The type or namespace name 'A' could not be found (are you missing a using directive or an assembly reference?)"); testData = new CompilationTestData(); // B should be resolved to BS2. context.CompileExpression("new B()", out error, testData); methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""B..ctor()"" IL_0005: ret }"); Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityBS2.GetDisplayName()); // B.F should result in missing assembly AS2 since there were no direct references to AS2. testData = new CompilationTestData(); context.CompileExpression( "(new B()).F", DkmEvaluationFlags.None, NoAliases, DebuggerDiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); AssertEx.Equal(missingAssemblyIdentities, ImmutableArray.Create(identityAS2)); }); }
public void NoPrefix() { 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, methodName: "C.M"); ResultProperties resultProperties; string error; ImmutableArray <AssemblyIdentity> missingAssemblyIdentities; // $1 var testData = new CompilationTestData(); context.CompileExpression( InspectionContextFactory.Empty, "var $1 = 1;", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Equal(error, "(1,5): error CS1056: Unexpected character '$'"); // $exception testData = new CompilationTestData(); context.CompileExpression( InspectionContextFactory.Empty, "var $exception = 2;", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Equal(error, "(1,5): error CS1056: Unexpected character '$'"); // $ReturnValue testData = new CompilationTestData(); context.CompileExpression( InspectionContextFactory.Empty, "var $ReturnValue = 3;", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Equal(error, "(1,5): error CS1056: Unexpected character '$'"); // $x testData = new CompilationTestData(); context.CompileExpression( InspectionContextFactory.Empty, "var $x = 4;", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Equal(error, "(1,5): error CS1056: Unexpected character '$'"); }
public void CorLibWithAssemblyReferences() { string sourceLib = @"public class Private1 { } public class Private2 { }"; var compLib = CreateStandardCompilation(sourceLib, assemblyName: "System.Private.Library"); compLib.VerifyDiagnostics(); var refLib = compLib.EmitToImageReference(); string sourceCorLib = @"using System.Runtime.CompilerServices; [assembly: TypeForwardedTo(typeof(Private2))] namespace System { public class Object { public Private1 F() => null; } #pragma warning disable 0436 public class Void : Object { } #pragma warning restore 0436 }"; // Create a custom corlib with a reference to compilation // above and a reference to the actual mscorlib. var compCorLib = CreateCompilation(sourceCorLib, assemblyName: CorLibAssemblyName, references: new[] { MscorlibRef, refLib }); compCorLib.VerifyDiagnostics(); var objectType = compCorLib.SourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("System.Object"); Assert.NotNull(objectType.BaseType); ImmutableArray <byte> peBytes; ImmutableArray <byte> pdbBytes; ExpressionCompilerTestHelpers.EmitCorLibWithAssemblyReferences( compCorLib, null, (moduleBuilder, emitOptions) => new PEAssemblyBuilderWithAdditionalReferences(moduleBuilder, emitOptions, objectType), out peBytes, out pdbBytes); using (var reader = new PEReader(peBytes)) { var metadata = reader.GetMetadata(); var module = metadata.ToModuleMetadata(ignoreAssemblyRefs: true); var metadataReader = metadata.ToMetadataReader(); var moduleInstance = ModuleInstance.Create(metadata, metadataReader.GetModuleVersionIdOrThrow()); // Verify the module declares System.Object. Assert.True(metadataReader.DeclaresTheObjectClass()); // Verify the PEModule has no assembly references. Assert.Equal(0, module.Module.ReferencedAssemblies.Length); // Verify the underlying metadata has the expected assembly references. var actualReferences = metadataReader.AssemblyReferences.Select(r => metadataReader.GetString(metadataReader.GetAssemblyReference(r).Name)).ToImmutableArray(); AssertEx.Equal(new[] { "mscorlib", "System.Private.Library" }, actualReferences); var source = @"class C { static void M() { } }"; var comp = CreateCompilation(source, options: TestOptions.DebugDll, references: new[] { refLib, AssemblyMetadata.Create(module).GetReference() }); comp.VerifyDiagnostics(); using (var runtime = RuntimeInstance.Create(new[] { comp.ToModuleInstance(), moduleInstance })) { string error; var context = CreateMethodContext(runtime, "C.M"); // Valid expression. var testData = new CompilationTestData(); context.CompileExpression( "new object()", out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""object..ctor()"" IL_0005: ret }"); // Invalid expression: System.Int32 is not defined in corlib above. testData = new CompilationTestData(); context.CompileExpression( "1", out error, testData); Assert.Equal("error CS0518: Predefined type 'System.Int32' is not defined or imported", error); // Invalid expression: type in method signature from missing referenced assembly. testData = new CompilationTestData(); context.CompileExpression( "(new object()).F()", out error, testData); Assert.Equal("error CS0570: 'object.F()' is not supported by the language", error); // Invalid expression: type forwarded to missing referenced assembly. testData = new CompilationTestData(); context.CompileExpression( "new Private2()", out error, testData); Assert.Equal("error CS0246: The type or namespace name 'Private2' could not be found (are you missing a using directive or an assembly reference?)", error); } } }
public void References() { var source = @"class C { delegate void D(); internal object F; static object G; static void M<T>(object x) { object y; } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, methodName: "C.M"); ResultProperties resultProperties; string error; ImmutableArray <AssemblyIdentity> missingAssemblyIdentities; var testData = new CompilationTestData(); context.CompileExpression( InspectionContextFactory.Empty.Add("x", typeof(string)). Add("y", typeof(int)). Add("T", typeof(object)). Add("D", "C"). Add("F", typeof(int)), "(object)x ?? (object)y ?? (object)T ?? (object)F ?? ((C)D).F ?? C.G", DkmEvaluationFlags.TreatAsExpression, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Equal(testData.Methods.Count, 3); testData.GetMethodData("<>x.<>m0<T>").VerifyIL( @"{ // Code size 78 (0x4e) .maxstack 2 .locals init (object V_0) //y IL_0000: ldarg.0 IL_0001: dup IL_0002: brtrue.s IL_004d IL_0004: pop IL_0005: ldloc.0 IL_0006: dup IL_0007: brtrue.s IL_004d IL_0009: pop IL_000a: ldstr ""T"" IL_000f: call ""object <>x.<>GetObjectByAlias(string)"" IL_0014: dup IL_0015: brtrue.s IL_004d IL_0017: pop IL_0018: ldstr ""F"" IL_001d: call ""object <>x.<>GetObjectByAlias(string)"" IL_0022: unbox.any ""int"" IL_0027: box ""int"" IL_002c: dup IL_002d: brtrue.s IL_004d IL_002f: pop IL_0030: ldstr ""D"" IL_0035: call ""object <>x.<>GetObjectByAlias(string)"" IL_003a: castclass ""C"" IL_003f: ldfld ""object C.F"" IL_0044: dup IL_0045: brtrue.s IL_004d IL_0047: pop IL_0048: ldsfld ""object C.G"" IL_004d: ret }"); }
public void DeclareLocal() { var source = @"class C { static void M() { var x = (1, 2); } }"; var comp = CreateCompilationWithMscorlib40(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; ResultProperties resultProperties; ImmutableArray <AssemblyIdentity> missingAssemblyIdentities; var result = context.CompileExpression( "(int A, int B) y = x;", DkmEvaluationFlags.None, NoAliases, DebuggerDiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Null(error); Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.PotentialSideEffect | DkmClrCompilationResultFlags.ReadOnlyResult); ReadOnlyCollection <byte> customTypeInfo; var customTypeInfoId = result.GetCustomTypeInfo(out customTypeInfo); ReadOnlyCollection <byte> dynamicFlags; ReadOnlyCollection <string> tupleElementNames; CustomTypeInfo.Decode(customTypeInfoId, customTypeInfo, out dynamicFlags, out tupleElementNames); Assert.Null(tupleElementNames); var methodData = testData.GetMethodData("<>x.<>m0"); var method = methodData.Method; CheckAttribute(result.Assembly, method, AttributeDescription.TupleElementNamesAttribute, expected: false); methodData.VerifyIL( @"{ // Code size 64 (0x40) .maxstack 6 .locals init ((int, int) V_0) //x IL_0000: ldtoken ""System.ValueTuple<int, int>"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""y"" IL_000f: ldstr ""108766ce-df68-46ee-b761-0dcb7ac805f1"" IL_0014: newobj ""System.Guid..ctor(string)"" IL_0019: ldc.i4.5 IL_001a: newarr ""byte"" IL_001f: dup IL_0020: ldtoken ""<PrivateImplementationDetails>.__StaticArrayInitTypeSize=5 <PrivateImplementationDetails>.362A905A18EA2A18A9EB2574618C490DE8A1F5C3"" IL_0025: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" IL_002a: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" IL_002f: ldstr ""y"" IL_0034: call ""(int A, int B) Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress<(int A, int B)>(string)"" IL_0039: ldloc.0 IL_003a: stobj ""System.ValueTuple<int, int>"" IL_003f: ret }"); }); }
public void Declarations() { var source = @"class C { static object F; static void M<T>(object x) { object y; if (x == null) { object z; } } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, methodName: "C.M"); ResultProperties resultProperties; string error; ImmutableArray <AssemblyIdentity> missingAssemblyIdentities; var testData = new CompilationTestData(); var result = context.CompileExpression( InspectionContextFactory.Empty, "int z = 1, F = 2;", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.PotentialSideEffect | DkmClrCompilationResultFlags.ReadOnlyResult); testData.GetMethodData("<>x.<>m0<T>").VerifyIL( @"{ // Code size 65 (0x41) .maxstack 2 .locals init (object V_0, //y bool V_1, object V_2) IL_0000: ldtoken ""int"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""z"" IL_000f: call ""void <>x.<>CreateVariable(System.Type, string)"" IL_0014: ldstr ""z"" IL_0019: call ""int <>x.<>GetVariableAddress<int>(string)"" IL_001e: ldc.i4.1 IL_001f: stind.i4 IL_0020: ldtoken ""int"" IL_0025: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_002a: ldstr ""F"" IL_002f: call ""void <>x.<>CreateVariable(System.Type, string)"" IL_0034: ldstr ""F"" IL_0039: call ""int <>x.<>GetVariableAddress<int>(string)"" IL_003e: ldc.i4.2 IL_003f: stind.i4 IL_0040: ret }"); var assembly = ImmutableArray.CreateRange(result.Assembly); assembly.VerifyIL("<>x.<>CreateVariable", @"{ // Code size 2 (0x2) .maxstack 8 IL_0000: ldnull IL_0001: throw }"); assembly.VerifyIL("<>x.<>GetVariableAddress", @"{ // Code size 2 (0x2) .maxstack 8 IL_0000: ldnull IL_0001: throw }"); // Verify <>CreateVariable is not generic and <>GetVariableAddress is. using (var metadata = ModuleMetadata.CreateFromImage(ImmutableArray.CreateRange(assembly))) { var reader = metadata.MetadataReader; var typeDef = reader.GetTypeDef("<>x"); reader.CheckTypeParameters(typeDef.GetGenericParameters()); var methodDef = reader.GetMethodDef(typeDef, "<>CreateVariable"); reader.CheckTypeParameters(methodDef.GetGenericParameters()); var method = (MethodSymbol)testData.GetMethodData("<>x.<>CreateVariable").Method; Assert.Equal(method.CallingConvention, Cci.CallingConvention.Default); methodDef = reader.GetMethodDef(typeDef, "<>GetVariableAddress"); reader.CheckTypeParameters(methodDef.GetGenericParameters(), "<>T"); method = (MethodSymbol)testData.GetMethodData("<>x.<>GetVariableAddress<<>T>").Method; Assert.Equal(method.CallingConvention, Cci.CallingConvention.Generic); } }
public void AliasElement_NoNames() { var source = @"class C { static (int, int) F; static void M() { } }"; var comp = CreateCompilationWithMscorlib40(source, new[] { SystemRuntimeFacadeRef, ValueTupleRef }, options: TestOptions.DebugDll); WithRuntimeInstance(comp, new[] { MscorlibRef, SystemCoreRef, SystemRuntimeFacadeRef, ValueTupleRef }, runtime => { var context = CreateMethodContext(runtime, "C.M"); var alias = new Alias( DkmClrAliasKind.Variable, "x", "x", "System.ValueTuple`8[" + "[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]," + "[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]," + "[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]," + "[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]," + "[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]," + "[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]," + "[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]," + "[System.ValueTuple`2[" + "[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]," + "[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], " + "System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51]], " + "System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51", Guid.Empty, null); ResultProperties resultProperties; string error; ImmutableArray <AssemblyIdentity> missingAssemblyIdentities; var testData = new CompilationTestData(); context.CompileExpression( "x.Item4 + x.Item8", DkmEvaluationFlags.TreatAsExpression, ImmutableArray.Create(alias), DebuggerDiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, null, testData); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 47 (0x2f) .maxstack 2 IL_0000: ldstr ""x"" IL_0005: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_000a: unbox.any ""System.ValueTuple<int, int, int, int, int, int, int, (int, int)>"" IL_000f: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, (int, int)>.Item4"" IL_0014: ldstr ""x"" IL_0019: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_001e: unbox.any ""System.ValueTuple<int, int, int, int, int, int, int, (int, int)>"" IL_0023: ldfld ""(int, int) System.ValueTuple<int, int, int, int, int, int, int, (int, int)>.Rest"" IL_0028: ldfld ""int System.ValueTuple<int, int>.Item1"" IL_002d: add IL_002e: 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 runtime = CreateRuntime(source, compileReferences, runtimeReferences); 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); } }