private static Imports[] GetImports(params string[] sources) { var trees = sources.Select(source => Parse(source)).ToArray(); var compilationUnits = trees.Select(tree => (CompilationUnitSyntax)tree.GetRoot()); var externAliases = compilationUnits .SelectMany(cu => cu.Externs) .Select(e => e.Identifier.ValueText) .Distinct(); var comp = CreateCompilation( trees, targetFramework: TargetFramework.Mscorlib40, references: new[] { SystemCoreRef.WithAliases(externAliases) } ); comp.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error).Verify(); var factories = trees.Select(tree => comp.GetBinderFactory(tree)); var binders = factories.Select( factory => factory.GetImportsBinder( (CSharpSyntaxNode)factory.SyntaxTree.GetRoot(), inUsing: false ) ); var imports = binders.Select(binder => binder.GetImports(basesBeingResolved: null)); Assert.DoesNotContain(Imports.Empty, imports); return(imports.ToArray()); }
public void ConcatCollidingExternAliases() { var comp = CreateCompilation( "extern alias A; extern alias B;", targetFramework: TargetFramework.Mscorlib40, references: new[] { SystemCoreRef.WithAliases(new[] { "A" }), SystemDataRef.WithAliases(new[] { "B" }), } ); var tree = comp.SyntaxTrees.Single(); var binder = comp.GetBinderFactory(tree) .GetImportsBinder((CSharpSyntaxNode)tree.GetRoot(), inUsing: false); var scratchImports = binder.GetImports(basesBeingResolved: null); var scratchExternAliases = scratchImports.ExternAliases; Assert.Equal(2, scratchExternAliases.Length); var externAlias1 = scratchExternAliases[0]; var externAlias2 = new AliasAndExternAliasDirective( AliasSymbol.CreateCustomDebugInfoAlias( scratchExternAliases[1].Alias.Target, externAlias1.ExternAliasDirective.Identifier, binder ), externAlias1.ExternAliasDirective ); var imports1 = Imports.FromCustomDebugInfo( comp, ImmutableDictionary <string, AliasAndUsingDirective> .Empty, ImmutableArray <NamespaceOrTypeAndUsingDirective> .Empty, ImmutableArray.Create(externAlias1) ); var imports2 = Imports.FromCustomDebugInfo( comp, ImmutableDictionary <string, AliasAndUsingDirective> .Empty, ImmutableArray <NamespaceOrTypeAndUsingDirective> .Empty, ImmutableArray.Create(externAlias2) ); var concat1 = imports1.Concat(imports2); Assert.Equal(externAlias2.Alias.Target, concat1.ExternAliases.Single().Alias.Target); var concat2 = imports2.Concat(imports1); Assert.Equal(externAlias1.Alias.Target, concat2.ExternAliases.Single().Alias.Target); }
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 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 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 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); }