private static void TupleContextNoSystemRuntime(string source, string methodName, string expression, string expectedIL, LanguageVersion languageVersion = LanguageVersion.CSharp7) { var comp = CreateCompilationWithMscorlib40(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), references: new[] { SystemRuntimeFacadeRef, ValueTupleRef }, options: TestOptions.DebugDll); using (var systemRuntime = SystemRuntimeFacadeRef.ToModuleInstance()) { WithRuntimeInstance(comp, new[] { MscorlibRef, ValueTupleRef }, runtime => { ImmutableArray <MetadataBlock> blocks; Guid moduleVersionId; ISymUnmanagedReader symReader; int methodToken; int localSignatureToken; GetContextState(runtime, methodName, out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken); string errorMessage; CompilationTestData testData; int retryCount = 0; var compileResult = ExpressionCompilerTestHelpers.CompileExpressionWithRetry( runtime.Modules.Select(m => m.MetadataBlock).ToImmutableArray(), expression, ImmutableArray <Alias> .Empty, (b, u) => EvaluationContext.CreateMethodContext( b.ToCompilation(default(Guid), MakeAssemblyReferencesKind.AllAssemblies), symReader, moduleVersionId, methodToken, methodVersion: 1, ilOffset: 0, localSignatureToken: localSignatureToken), (AssemblyIdentity assemblyIdentity, out uint uSize) => { retryCount++; Assert.Equal("System.Runtime", assemblyIdentity.Name); var block = systemRuntime.MetadataBlock; uSize = (uint)block.Size; return(block.Pointer); }, errorMessage: out errorMessage, testData: out testData); Assert.Equal(1, retryCount); testData.GetMethodData("<>x.<>m0").VerifyIL(expectedIL); }); } }
public void SucceedOnRetry() { var source = @" class C { void M() { } }"; var comp = CreateCompilationWithMscorlib(source); var runtime = CreateRuntimeInstance(comp); var context = CreateMethodContext(runtime, "C.M"); var missingModule = runtime.Modules.First(); var missingIdentity = missingModule.MetadataReader.ReadAssemblyIdentityOrThrow(); var shouldSucceed = false; string errorMessage; var compileResult = ExpressionCompilerTestHelpers.CompileExpressionWithRetry( runtime.Modules.Select(m => m.MetadataBlock).ToImmutableArray(), context, (_, diagnostics) => { if (shouldSucceed) { return(TestCompileResult.Instance); } else { shouldSucceed = true; diagnostics.Add(new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_NoTypeDef, "MissingType", missingIdentity), Location.None)); return(null); } }, (AssemblyIdentity assemblyIdentity, out uint uSize) => { uSize = (uint)missingModule.MetadataLength; return(missingModule.MetadataAddress); }, out errorMessage); Assert.Same(TestCompileResult.Instance, compileResult); Assert.Null(errorMessage); }
public void WinMdAssemblyReferenceRequiresRedirect() { var source = @"class C : Windows.UI.Xaml.Controls.UserControl { static void M(C c) { } }"; var compilation = CreateEmptyCompilation(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 CompileWithRetrySameErrorReported() { var source = @" class C { void M() { } }"; var comp = CreateStandardCompilation(source); WithRuntimeInstance(comp, runtime => { var context = CreateMethodContext(runtime, "C.M"); var missingModule = runtime.Modules.First(); var missingIdentity = missingModule.GetMetadataReader().ReadAssemblyIdentityOrThrow(); var numRetries = 0; string errorMessage; ExpressionCompilerTestHelpers.CompileExpressionWithRetry( runtime.Modules.Select(m => m.MetadataBlock).ToImmutableArray(), context, (_, diagnostics) => { numRetries++; Assert.InRange(numRetries, 0, 2); // We don't want to loop forever... diagnostics.Add(new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_NoTypeDef, "MissingType", missingIdentity), Location.None)); return(null); }, (AssemblyIdentity assemblyIdentity, out uint uSize) => { uSize = (uint)missingModule.MetadataLength; return(missingModule.MetadataAddress); }, out errorMessage); Assert.Equal(2, numRetries); // Ensure that we actually retried and that we bailed out on the second retry if the same identity was seen in the diagnostics. Assert.Equal($"error CS0012: The type 'MissingType' is defined in an assembly that is not referenced. You must add a reference to assembly '{missingIdentity}'.", errorMessage); }); }
public void TryDifferentLinqLibraryOnRetry() { var source = @" using System.Linq; class C { void M(string[] args) { } } class UseLinq { bool b = Enumerable.Any<int>(null); }"; var compilation = CreateCompilation(source, new[] { MscorlibRef, SystemCoreRef }); WithRuntimeInstance(compilation, new[] { MscorlibRef }, runtime => { var context = CreateMethodContext(runtime, "C.M"); var systemCore = SystemCoreRef.ToModuleInstance(); var fakeSystemLinq = CreateCompilationWithMscorlib45("", assemblyName: "System.Linq"). EmitToImageReference().ToModuleInstance(); string errorMessage; CompilationTestData testData; int retryCount = 0; var compileResult = ExpressionCompilerTestHelpers.CompileExpressionWithRetry( runtime.Modules.Select(m => m.MetadataBlock).ToImmutableArray(), "args.Where(a => a.Length > 0)", ImmutableArray <Alias> .Empty, (_1, _2) => context, // ignore new blocks and just keep using the same failed context... (AssemblyIdentity assemblyIdentity, out uint uSize) => { retryCount++; MetadataBlock block; switch (retryCount) { case 1: Assert.Equal(EvaluationContextBase.SystemLinqIdentity, assemblyIdentity); block = fakeSystemLinq.MetadataBlock; break; case 2: Assert.Equal(EvaluationContextBase.SystemCoreIdentity, assemblyIdentity); block = systemCore.MetadataBlock; break; default: throw ExceptionUtilities.Unreachable; } uSize = (uint)block.Size; return(block.Pointer); }, errorMessage: out errorMessage, testData: out testData); Assert.Equal(2, retryCount); }); }
public void MissingMscorlib() { var sourceA = @"public class A { } class B { } class C { }"; var sourceB = @"public class B : A { }"; var assemblyNameA = ExpressionCompilerUtilities.GenerateUniqueName(); var compilationA = CreateCompilation( sourceA, references: new MetadataReference[] { SystemRuntimePP7Ref }, options: TestOptions.DebugDll, assemblyName: assemblyNameA); byte[] exeBytesA; byte[] pdbBytesA; ImmutableArray <MetadataReference> referencesA; compilationA.EmitAndGetReferences(out exeBytesA, out pdbBytesA, out referencesA); var referenceA = AssemblyMetadata.CreateFromImage(exeBytesA).GetReference(display: assemblyNameA); var identityA = referenceA.GetAssemblyIdentity(); var moduleA = referenceA.ToModuleInstance(exeBytesA, new SymReader(pdbBytesA)); var assemblyNameB = ExpressionCompilerUtilities.GenerateUniqueName(); var compilationB = CreateCompilation( sourceB, references: new MetadataReference[] { SystemRuntimePP7Ref, referenceA }, options: TestOptions.DebugDll, assemblyName: assemblyNameB); byte[] exeBytesB; byte[] pdbBytesB; ImmutableArray <MetadataReference> referencesB; compilationB.EmitAndGetReferences(out exeBytesB, out pdbBytesB, out referencesB); var referenceB = AssemblyMetadata.CreateFromImage(exeBytesB).GetReference(display: assemblyNameB); var moduleB = referenceB.ToModuleInstance(exeBytesB, new SymReader(pdbBytesB)); // At runtime System.Runtime.dll contract assembly is replaced // by mscorlib.dll and System.Runtime.dll facade assemblies. var moduleBuilder = ArrayBuilder <ModuleInstance> .GetInstance(); moduleBuilder.Add(MscorlibFacadeRef.ToModuleInstance(null, null)); moduleBuilder.Add(SystemRuntimeFacadeRef.ToModuleInstance(null, null)); moduleBuilder.Add(moduleA); moduleBuilder.Add(moduleB); var modules = moduleBuilder.ToImmutableAndFree(); using (var runtime = new RuntimeInstance(modules)) { ImmutableArray <MetadataBlock> blocks; Guid moduleVersionId; ISymUnmanagedReader symReader; int typeToken; int localSignatureToken; GetContextState(runtime, "C", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken); string errorMessage; CompilationTestData testData; int attempts = 0; ExpressionCompiler.CreateContextDelegate contextFactory = (b, u) => { attempts++; return(EvaluationContext.CreateTypeContext( ToCompilation(b, u, moduleVersionId), moduleVersionId, typeToken)); }; // Compile: [DebuggerDisplay("{new B()}")] const string expr = "new B()"; ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, expr, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.Null(errorMessage); Assert.Equal(2, attempts); var methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""B..ctor()"" IL_0005: ret }"); } }
public void DuplicateTypesAndMethodsDifferentAssemblies() { var sourceA = @"using N; namespace N { class C1 { } public static class E { public static A F(this A o) { return o; } } } class C2 { } public class A { public static void M() { var x = new A(); var y = x.F(); } }"; var sourceB = @"using N; namespace N { class C1 { } public static class E { public static int F(this A o) { return 2; } } } class C2 { } public class B { static void M() { var x = new A(); } }"; var assemblyNameA = ExpressionCompilerUtilities.GenerateUniqueName(); var compilationA = CreateCompilationWithMscorlibAndSystemCore(sourceA, options: TestOptions.DebugDll, assemblyName: assemblyNameA); byte[] exeBytesA; byte[] pdbBytesA; ImmutableArray <MetadataReference> referencesA; compilationA.EmitAndGetReferences(out exeBytesA, out pdbBytesA, out referencesA); var referenceA = AssemblyMetadata.CreateFromImage(exeBytesA).GetReference(display: assemblyNameA); var identityA = referenceA.GetAssemblyIdentity(); var moduleA = referenceA.ToModuleInstance(exeBytesA, new SymReader(pdbBytesA)); var assemblyNameB = ExpressionCompilerUtilities.GenerateUniqueName(); var compilationB = CreateCompilationWithMscorlibAndSystemCore(sourceB, options: TestOptions.DebugDll, assemblyName: assemblyNameB, references: new[] { referenceA }); byte[] exeBytesB; byte[] pdbBytesB; ImmutableArray <MetadataReference> referencesB; compilationB.EmitAndGetReferences(out exeBytesB, out pdbBytesB, out referencesB); var referenceB = AssemblyMetadata.CreateFromImage(exeBytesB).GetReference(display: assemblyNameB); var moduleB = referenceB.ToModuleInstance(exeBytesB, new SymReader(pdbBytesB)); var moduleBuilder = ArrayBuilder <ModuleInstance> .GetInstance(); moduleBuilder.AddRange(referencesA.Select(r => r.ToModuleInstance(null, null))); moduleBuilder.Add(moduleA); moduleBuilder.Add(moduleB); var modules = moduleBuilder.ToImmutableAndFree(); using (var runtime = new RuntimeInstance(modules)) { ImmutableArray <MetadataBlock> blocks; Guid moduleVersionId; ISymUnmanagedReader symReader; int typeToken; int methodToken; int localSignatureToken; GetContextState(runtime, "B", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken); string errorMessage; CompilationTestData testData; var contextFactory = CreateTypeContextFactory(moduleVersionId, typeToken); // Duplicate type in namespace, at type scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new N.C1()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.True(errorMessage.StartsWith("error CS0433: The type 'C1' exists in both ")); GetContextState(runtime, "B.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken); contextFactory = CreateMethodContextFactory(moduleVersionId, symReader, methodToken, localSignatureToken); // Duplicate type in namespace, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C1()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.True(errorMessage.StartsWith("error CS0433: The type 'C1' exists in both ")); // Duplicate type in global namespace, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C2()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.True(errorMessage.StartsWith("error CS0433: The type 'C2' exists in both ")); // Duplicate extension method, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "x.F()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.Equal(errorMessage, "(1,3): error CS0121: The call is ambiguous between the following methods or properties: 'N.E.F(A)' and 'N.E.F(A)'"); // Same tests as above but in library that does not directly reference duplicates. GetContextState(runtime, "A", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken); contextFactory = CreateTypeContextFactory(moduleVersionId, typeToken); // Duplicate type in namespace, at type scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new N.C1()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.Null(errorMessage); var methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""N.C1..ctor()"" IL_0005: ret }"); Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName()); GetContextState(runtime, "A.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken); contextFactory = CreateMethodContextFactory(moduleVersionId, symReader, methodToken, localSignatureToken); // Duplicate type in global namespace, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C2()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.Null(errorMessage); methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 6 (0x6) .maxstack 1 .locals init (A V_0, //x A V_1) //y IL_0000: newobj ""C2..ctor()"" IL_0005: ret }"); Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName()); // Duplicate extension method, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "x.F()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.Null(errorMessage); methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 7 (0x7) .maxstack 1 .locals init (A V_0, //x A V_1) //y IL_0000: ldloc.0 IL_0001: call ""A N.E.F(A)"" IL_0006: ret }"); Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName()); } }
public void IntrinsicMethods() { var sourceA = @"public class A { }"; var sourceB = @"public class A { } public class B { static void M(A a) { } }"; var compilationA = CreateCompilationWithMscorlibAndSystemCore(sourceA, options: TestOptions.DebugDll); var moduleA = compilationA.ToModuleInstance(); var compilationB = CreateCompilationWithMscorlibAndSystemCore(sourceB, options: TestOptions.DebugDll, references: new[] { moduleA.GetReference() }); var moduleB = compilationB.ToModuleInstance(); var runtime = CreateRuntimeInstance(new[] { MscorlibRef.ToModuleInstance(), SystemCoreRef.ToModuleInstance(), moduleA, moduleB, ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance() }); ImmutableArray <MetadataBlock> blocks; Guid moduleVersionId; ISymUnmanagedReader symReader; int methodToken; int localSignatureToken; GetContextState(runtime, "B.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken); var aliases = ImmutableArray.Create( ExceptionAlias(typeof(ArgumentException)), ReturnValueAlias(2, typeof(string)), ObjectIdAlias(1, typeof(object))); int attempts = 0; EvaluationContextBase contextFactory(ImmutableArray <MetadataBlock> b, bool u) { attempts++; return(EvaluationContext.CreateMethodContext( ToCompilation(b, u, moduleVersionId), symReader, moduleVersionId, methodToken, methodVersion: 1, ilOffset: 0, localSignatureToken: localSignatureToken)); } string errorMessage; CompilationTestData testData; ExpressionCompilerTestHelpers.CompileExpressionWithRetry( blocks, "(object)new A() ?? $exception ?? $1 ?? $ReturnValue2", aliases, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.Null(errorMessage); Assert.Equal(2, attempts); var methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 49 (0x31) .maxstack 2 IL_0000: newobj ""A..ctor()"" IL_0005: dup IL_0006: brtrue.s IL_0030 IL_0008: pop IL_0009: call ""System.Exception Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetException()"" IL_000e: castclass ""System.ArgumentException"" IL_0013: dup IL_0014: brtrue.s IL_0030 IL_0016: pop IL_0017: ldstr ""$1"" IL_001c: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_0021: dup IL_0022: brtrue.s IL_0030 IL_0024: pop IL_0025: ldc.i4.2 IL_0026: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetReturnValue(int)"" IL_002b: castclass ""string"" IL_0030: ret }"); }
public void MissingMscorlib() { var sourceA = @"public class A { } class B { } class C { }"; var sourceB = @"public class B : A { }"; var moduleA = CreateCompilation( sourceA, references: new[] { SystemRuntimePP7Ref }, options: TestOptions.DebugDll).ToModuleInstance(); var moduleB = CreateCompilation( sourceB, references: new[] { SystemRuntimePP7Ref, moduleA.GetReference() }, options: TestOptions.DebugDll).ToModuleInstance(); // Include an empty assembly to verify that not all assemblies // with no references are treated as mscorlib. var referenceC = AssemblyMetadata.CreateFromImage(CommonResources.Empty).GetReference(); // At runtime System.Runtime.dll contract assembly is replaced // by mscorlib.dll and System.Runtime.dll facade assemblies. var runtime = CreateRuntimeInstance(new[] { MscorlibFacadeRef.ToModuleInstance(), SystemRuntimeFacadeRef.ToModuleInstance(), moduleA, moduleB, referenceC.ToModuleInstance() }); ImmutableArray <MetadataBlock> blocks; Guid moduleVersionId; ISymUnmanagedReader symReader; int typeToken; int localSignatureToken; GetContextState(runtime, "C", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken); string errorMessage; CompilationTestData testData; int attempts = 0; EvaluationContextBase contextFactory(ImmutableArray <MetadataBlock> b, bool u) { attempts++; return(EvaluationContext.CreateTypeContext( ToCompilation(b, u, moduleVersionId), moduleVersionId, typeToken)); } // Compile: [DebuggerDisplay("{new B()}")] const string expr = "new B()"; ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, expr, ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.Null(errorMessage); Assert.Equal(2, attempts); var methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""B..ctor()"" IL_0005: ret }"); }
public void DuplicateTypesAndMethodsDifferentAssemblies() { var sourceA = @"using N; namespace N { class C1 { } public static class E { public static A F(this A o) { return o; } } } class C2 { } public class A { public static void M() { var x = new A(); var y = x.F(); } }"; var sourceB = @"using N; namespace N { class C1 { } public static class E { public static int F(this A o) { return 2; } } } class C2 { } public class B { static void M() { var x = new A(); } }"; var compilationA = CreateCompilationWithMscorlibAndSystemCore(sourceA, options: TestOptions.DebugDll); var identityA = compilationA.Assembly.Identity; var moduleA = compilationA.ToModuleInstance(); var compilationB = CreateCompilationWithMscorlibAndSystemCore(sourceB, options: TestOptions.DebugDll, references: new[] { moduleA.GetReference() }); var moduleB = compilationB.ToModuleInstance(); var runtime = CreateRuntimeInstance(new[] { MscorlibRef.ToModuleInstance(), SystemCoreRef.ToModuleInstance(), moduleA, moduleB }); ImmutableArray <MetadataBlock> blocks; Guid moduleVersionId; ISymUnmanagedReader symReader; int typeToken; int methodToken; int localSignatureToken; GetContextState(runtime, "B", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken); string errorMessage; CompilationTestData testData; var contextFactory = CreateTypeContextFactory(moduleVersionId, typeToken); // Duplicate type in namespace, at type scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new N.C1()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.True(errorMessage.StartsWith("error CS0433: The type 'C1' exists in both ")); GetContextState(runtime, "B.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken); contextFactory = CreateMethodContextFactory(moduleVersionId, symReader, methodToken, localSignatureToken); // Duplicate type in namespace, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C1()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.True(errorMessage.StartsWith("error CS0433: The type 'C1' exists in both ")); // Duplicate type in global namespace, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C2()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.True(errorMessage.StartsWith("error CS0433: The type 'C2' exists in both ")); // Duplicate extension method, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "x.F()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.Equal(errorMessage, "error CS0121: The call is ambiguous between the following methods or properties: 'N.E.F(A)' and 'N.E.F(A)'"); // Same tests as above but in library that does not directly reference duplicates. GetContextState(runtime, "A", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken); contextFactory = CreateTypeContextFactory(moduleVersionId, typeToken); // Duplicate type in namespace, at type scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new N.C1()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.Null(errorMessage); var methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""N.C1..ctor()"" IL_0005: ret }"); Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName()); GetContextState(runtime, "A.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken); contextFactory = CreateMethodContextFactory(moduleVersionId, symReader, methodToken, localSignatureToken); // Duplicate type in global namespace, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C2()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.Null(errorMessage); methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 6 (0x6) .maxstack 1 .locals init (A V_0, //x A V_1) //y IL_0000: newobj ""C2..ctor()"" IL_0005: ret }"); Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName()); // Duplicate extension method, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "x.F()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.Null(errorMessage); methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 7 (0x7) .maxstack 1 .locals init (A V_0, //x A V_1) //y IL_0000: ldloc.0 IL_0001: call ""A N.E.F(A)"" IL_0006: ret }"); Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName()); }
public void IntrinsicMethods() { var sourceA = @"public class A { }"; var sourceB = @"public class A { } public class B { static void M(A a) { } }"; var assemblyNameA = ExpressionCompilerUtilities.GenerateUniqueName(); var compilationA = CreateCompilationWithMscorlibAndSystemCore(sourceA, options: TestOptions.DebugDll, assemblyName: assemblyNameA); byte[] exeBytesA; byte[] pdbBytesA; ImmutableArray <MetadataReference> referencesA; compilationA.EmitAndGetReferences(out exeBytesA, out pdbBytesA, out referencesA); var referenceA = AssemblyMetadata.CreateFromImage(exeBytesA).GetReference(display: assemblyNameA); var identityA = referenceA.GetAssemblyIdentity(); var moduleA = referenceA.ToModuleInstance(exeBytesA, new SymReader(pdbBytesA)); var assemblyNameB = ExpressionCompilerUtilities.GenerateUniqueName(); var compilationB = CreateCompilationWithMscorlibAndSystemCore(sourceB, options: TestOptions.DebugDll, assemblyName: assemblyNameB, references: new[] { referenceA }); byte[] exeBytesB; byte[] pdbBytesB; ImmutableArray <MetadataReference> referencesB; compilationB.EmitAndGetReferences(out exeBytesB, out pdbBytesB, out referencesB); var referenceB = AssemblyMetadata.CreateFromImage(exeBytesB).GetReference(display: assemblyNameB); var moduleB = referenceB.ToModuleInstance(exeBytesB, new SymReader(pdbBytesB)); var moduleBuilder = ArrayBuilder <ModuleInstance> .GetInstance(); moduleBuilder.AddRange(referencesA.Select(r => r.ToModuleInstance(null, null))); moduleBuilder.Add(moduleA); moduleBuilder.Add(moduleB); moduleBuilder.Add(ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance(fullImage: null, symReader: null)); var modules = moduleBuilder.ToImmutableAndFree(); using (var runtime = new RuntimeInstance(modules)) { ImmutableArray <MetadataBlock> blocks; Guid moduleVersionId; ISymUnmanagedReader symReader; int methodToken; int localSignatureToken; GetContextState(runtime, "B.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken); var aliases = ImmutableArray.Create( ExceptionAlias(typeof(ArgumentException)), ReturnValueAlias(2, typeof(string)), ObjectIdAlias(1, typeof(object))); int attempts = 0; ExpressionCompiler.CreateContextDelegate contextFactory = (b, u) => { attempts++; return(EvaluationContext.CreateMethodContext( ToCompilation(b, u, moduleVersionId), symReader, moduleVersionId, methodToken, methodVersion: 1, ilOffset: 0, localSignatureToken: localSignatureToken)); }; string errorMessage; CompilationTestData testData; ExpressionCompilerTestHelpers.CompileExpressionWithRetry( blocks, "(object)new A() ?? $exception ?? $1 ?? $ReturnValue2", aliases, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData); Assert.Null(errorMessage); Assert.Equal(2, attempts); var methodData = testData.GetMethodData("<>x.<>m0"); methodData.VerifyIL( @"{ // Code size 49 (0x31) .maxstack 2 IL_0000: newobj ""A..ctor()"" IL_0005: dup IL_0006: brtrue.s IL_0030 IL_0008: pop IL_0009: call ""System.Exception Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetException()"" IL_000e: castclass ""System.ArgumentException"" IL_0013: dup IL_0014: brtrue.s IL_0030 IL_0016: pop IL_0017: ldstr ""$1"" IL_001c: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" IL_0021: dup IL_0022: brtrue.s IL_0030 IL_0024: pop IL_0025: ldc.i4.2 IL_0026: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetReturnValue(int)"" IL_002b: castclass ""string"" IL_0030: ret }"); } }
public void TryDifferentLinqLibraryOnRetry() { var source = @" using System.Linq; class C { void M(string[] args) { } } class UseLinq { bool b = Enumerable.Any<int>(null); }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(source); byte[] exeBytes, pdbBytes; ImmutableArray <MetadataReference> references; compilation.EmitAndGetReferences(out exeBytes, out pdbBytes, out references); var systemCore = SystemCoreRef.ToModuleInstance(fullImage: null, symReader: null); var referencesWithoutSystemCore = references.Where(r => r != SystemCoreRef).ToImmutableArray(); var runtime = CreateRuntimeInstance(ExpressionCompilerUtilities.GenerateUniqueName(), referencesWithoutSystemCore.AddIntrinsicAssembly(), exeBytes, symReader: null); var context = CreateMethodContext(runtime, "C.M"); var fakeSystemLinq = CreateCompilationWithMscorlib45("", assemblyName: "System.Linq").EmitToImageReference().ToModuleInstance(fullImage: null, symReader: null); string errorMessage; CompilationTestData testData; int retryCount = 0; var compileResult = ExpressionCompilerTestHelpers.CompileExpressionWithRetry( runtime.Modules.Select(m => m.MetadataBlock).ToImmutableArray(), "args.Where(a => a.Length > 0)", (_1, _2) => context, // ignore new blocks and just keep using the same failed context... (AssemblyIdentity assemblyIdentity, out uint uSize) => { retryCount++; MetadataBlock block; switch (retryCount) { case 1: Assert.Equal(EvaluationContextBase.SystemLinqIdentity, assemblyIdentity); block = fakeSystemLinq.MetadataBlock; break; case 2: Assert.Equal(EvaluationContextBase.SystemCoreIdentity, assemblyIdentity); block = systemCore.MetadataBlock; break; default: throw ExceptionUtilities.Unreachable; } uSize = (uint)block.Size; return(block.Pointer); }, errorMessage: out errorMessage, testData: out testData); Assert.Equal(2, retryCount); }