|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection.PortableExecutable;
using Microsoft.Cci;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.CSharp.Emit;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.CSharp.UnitTests;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Symbols;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.DiaSymReader;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Roslyn.Test.PdbUtilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.UnitTests
{
public class ReferencedModulesTests : ExpressionCompilerTestBase
{
/// <summary>
/// MakeAssemblyReferences should drop unreferenced assemblies.
/// </summary>
[Fact]
public void UnreferencedAssemblies()
{
var (identityMscorlib, moduleMscorlib) = (MscorlibRef.GetAssemblyIdentity(), MscorlibRef.ToModuleInstance());
var (identityIntrinsic, moduleIntrinsic) = (ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.GetAssemblyIdentity(), ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance());
var (identityA1, moduleA1, refA1) = Compile("A1", "public class A1 { static void M() { } }");
var (identityA2, moduleA2, refA2) = Compile("A2", "public class A2 { static void M() { } }");
var (identityB1, moduleB1, refB1) = Compile("B1", "public class B1 : A1 { static void M() { } }", refA1);
var (identityB2, moduleB2, refB2) = Compile("B2", "public class B2 : A1 { static void M() { } }", refA1);
var (identityC, moduleC, refC) = Compile("C", "public class C1 : B2 { static void M() { } } public class C2 : A2 { }", refA1, refA2, refB2);
using (var runtime = CreateRuntimeInstance(new[] { moduleMscorlib, moduleA1, moduleA2, moduleB1, moduleB2, moduleC }))
{
var stateB2 = GetContextState(runtime, "B2.M");
// B2.M with missing A1.
var context = CreateMethodContext(
new AppDomain(),
ImmutableArray.Create(moduleMscorlib, moduleA2, moduleB1, moduleB2, moduleC).SelectAsArray(m => m.MetadataBlock),
stateB2);
ResultProperties resultProperties;
string error;
ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
context.CompileExpression("new B2()", DkmEvaluationFlags.TreatAsExpression,
NoAliases,
DebuggerDiagnosticFormatter.Instance,
out resultProperties,
out error,
out missingAssemblyIdentities,
EnsureEnglishUICulture.PreferredOrNull,
testData: null);
Assert.Equal("error CS0012: The type 'A1' is defined in an assembly that is not referenced. You must add a reference to assembly 'A1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.", error);
AssertEx.Equal(new[] { identityA1 }, missingAssemblyIdentities);
VerifyResolutionRequests(context, (identityA1, null, 1));
// B2.M with all assemblies.
context = CreateMethodContext(
new AppDomain(),
ImmutableArray.Create(moduleMscorlib, moduleA1, moduleA2, moduleB1, moduleB2, moduleC).SelectAsArray(m => m.MetadataBlock),
stateB2);
var testData = new CompilationTestData();
context.CompileExpression("new B2()", out error, testData);
var methodData = testData.GetMethodData("<>x.<>m0");
methodData.VerifyIL(
@"{
// Code size 6 (0x6)
.maxstack 1
IL_0000: newobj ""B2..ctor()""
IL_0005: ret
}");
VerifyResolutionRequests(context, (identityA1, identityA1, 1));
// B2.M with all assemblies in reverse order.
context = CreateMethodContext(
new AppDomain(),
ImmutableArray.Create(moduleC, moduleB2, moduleB1, moduleA2, moduleA1, moduleMscorlib, moduleIntrinsic).SelectAsArray(m => m.MetadataBlock),
stateB2);
testData = new CompilationTestData();
context.CompileExpression("new B2()", out error, testData);
methodData = testData.GetMethodData("<>x.<>m0");
methodData.VerifyIL(
@"{
// Code size 6 (0x6)
.maxstack 1
IL_0000: newobj ""B2..ctor()""
IL_0005: ret
}");
VerifyResolutionRequests(context, (identityA1, identityA1, 1));
// A1.M with all assemblies.
var stateA1 = GetContextState(runtime, "A1.M");
context = CreateMethodContext(
new AppDomain(),
ImmutableArray.Create(moduleMscorlib, moduleA1, moduleA2, moduleB1, moduleB2, moduleC).SelectAsArray(m => m.MetadataBlock),
stateA1);
testData = new CompilationTestData();
context.CompileExpression("new A1()", out error, testData);
methodData = testData.GetMethodData("<>x.<>m0");
methodData.VerifyIL(
@"{
// Code size 6 (0x6)
.maxstack 1
IL_0000: newobj ""A1..ctor()""
IL_0005: ret
}");
VerifyResolutionRequests(context);
// B1.M with all assemblies.
var stateB1 = GetContextState(runtime, "B1.M");
context = CreateMethodContext(
new AppDomain(),
ImmutableArray.Create(moduleMscorlib, moduleA1, moduleA2, moduleB1, moduleB2, moduleC).SelectAsArray(m => m.MetadataBlock),
stateB1);
testData = new CompilationTestData();
context.CompileExpression("new B1()", out error, testData);
methodData = testData.GetMethodData("<>x.<>m0");
methodData.VerifyIL(
@"{
// Code size 6 (0x6)
.maxstack 1
IL_0000: newobj ""B1..ctor()""
IL_0005: ret
}");
VerifyResolutionRequests(context, (identityA1, identityA1, 1));
// C1.M with all assemblies.
var stateC = GetContextState(runtime, "C1.M");
context = CreateMethodContext(
new AppDomain(),
ImmutableArray.Create(moduleMscorlib, moduleA1, moduleA2, moduleB1, moduleB2, moduleC).SelectAsArray(m => m.MetadataBlock),
stateC);
testData = new CompilationTestData();
context.CompileExpression("new C1()", out error, testData);
methodData = testData.GetMethodData("<>x.<>m0");
methodData.VerifyIL(
@"{
// Code size 6 (0x6)
.maxstack 1
IL_0000: newobj ""C1..ctor()""
IL_0005: ret
}");
VerifyResolutionRequests(context, (identityB2, identityB2, 1), (identityA1, identityA1, 1), (identityA2, identityA2, 1));
// Other EvaluationContext.CreateMethodContext overload.
// A1.M with all assemblies.
var allBlocks = ImmutableArray.Create(moduleMscorlib, moduleA1, moduleA2, moduleB1, moduleB2, moduleC).SelectAsArray(m => m.MetadataBlock);
context = EvaluationContext.CreateMethodContext(
allBlocks,
stateA1.SymReader,
stateA1.ModuleVersionId,
stateA1.MethodToken,
methodVersion: 1,
stateA1.ILOffset,
stateA1.LocalSignatureToken);
testData = new CompilationTestData();
context.CompileExpression("new B1()", out error, testData);
methodData = testData.GetMethodData("<>x.<>m0");
methodData.VerifyIL(
@"{
// Code size 6 (0x6)
.maxstack 1
IL_0000: newobj ""B1..ctor()""
IL_0005: ret
}");
// Other EvaluationContext.CreateMethodContext overload.
// A1.M with all assemblies, offset outside of IL.
context = EvaluationContext.CreateMethodContext(
allBlocks,
stateA1.SymReader,
stateA1.ModuleVersionId,
stateA1.MethodToken,
methodVersion: 1,
uint.MaxValue,
stateA1.LocalSignatureToken);
testData = new CompilationTestData();
context.CompileExpression("new C1()", out error, testData);
methodData = testData.GetMethodData("<>x.<>m0");
methodData.VerifyIL(
@"{
// Code size 6 (0x6)
.maxstack 1
IL_0000: newobj ""C1..ctor()""
IL_0005: ret
}");
}
}
[Fact]
public void DifferentAssemblyVersions()
{
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 options = TestOptions.DebugDll.WithDelaySign(true);
var (identityMscorlib, moduleMscorlib) = (MscorlibRef.GetAssemblyIdentity(), MscorlibRef.ToModuleInstance());
var (identityA1, moduleA1, refA1) = Compile(new AssemblyIdentity("A", new Version(1, 1, 1, 1), publicKeyOrToken: publicKeyA, hasPublicKey: true), "public class A { }", options, MscorlibRef);
var (identityA2, moduleA2, refA2) = Compile(new AssemblyIdentity("A", new Version(2, 2, 2, 2), publicKeyOrToken: publicKeyA, hasPublicKey: true), "public class A { }", options, MscorlibRef);
var (identityA3, moduleA3, refA3) = Compile(new AssemblyIdentity("a", new Version(3, 3, 3, 3), publicKeyOrToken: publicKeyA, hasPublicKey: true), "public class A { }", options, MscorlibRef);
var (identityB1, moduleB1, refB1) = Compile(new AssemblyIdentity("B", new Version(1, 1, 1, 1)), "public class B : A { static void M() { } }", TestOptions.DebugDll, refA2, MscorlibRef);
using (var runtime = CreateRuntimeInstance(new[] { moduleMscorlib, moduleA1, moduleA2, moduleA3, moduleB1 }))
{
var stateB = GetContextState(runtime, "B.M");
// Expected version of A.
var context = CreateMethodContext(
new AppDomain(),
ImmutableArray.Create(moduleMscorlib, moduleA2, moduleB1).SelectAsArray(m => m.MetadataBlock),
stateB);
string error;
var testData = new CompilationTestData();
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
}");
VerifyResolutionRequests(context, (identityA2, identityA2, 1));
// Higher version of A.
context = CreateMethodContext(
new AppDomain(),
ImmutableArray.Create(moduleMscorlib, moduleA3, moduleB1).SelectAsArray(m => m.MetadataBlock),
stateB);
testData = new CompilationTestData();
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
}");
VerifyResolutionRequests(context, (identityA2, identityA3, 1));
// Lower version of A.
context = CreateMethodContext(
new AppDomain(),
ImmutableArray.Create(moduleMscorlib, moduleA1, moduleB1).SelectAsArray(m => m.MetadataBlock),
stateB);
testData = new CompilationTestData();
context.CompileExpression("new B()", out error, testData);
Assert.Equal("error CS1705: Assembly 'B' with identity 'B, Version=1.1.1.1, Culture=neutral, PublicKeyToken=null' uses 'A, Version=2.2.2.2, Culture=neutral, PublicKeyToken=1f8a32457d187bf3' which has a higher version than referenced assembly 'A' with identity 'A, Version=1.1.1.1, Culture=neutral, PublicKeyToken=1f8a32457d187bf3'", error);
VerifyResolutionRequests(context, (identityA2, identityA1, 1));
// Multiple versions of A.
context = CreateMethodContext(
new AppDomain(),
ImmutableArray.Create(moduleMscorlib, moduleA1, moduleA3, moduleA2, moduleB1).SelectAsArray(m => m.MetadataBlock),
stateB);
testData = new CompilationTestData();
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
}");
VerifyResolutionRequests(context, (identityA2, identityA2, 1));
// Duplicate versions of A.
context = CreateMethodContext(
new AppDomain(),
ImmutableArray.Create(moduleMscorlib, moduleA3, moduleA1, moduleA3, moduleA1, moduleB1).SelectAsArray(m => m.MetadataBlock),
stateB);
testData = new CompilationTestData();
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
}");
VerifyResolutionRequests(context, (identityA2, identityA3, 1));
}
}
// Not handling duplicate corlib when using referenced assemblies
// only (bug #...).
[Fact(Skip = "TODO")]
public void DuplicateNamedCorLib()
{
var publicKeyOther = 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 options = TestOptions.DebugDll.WithDelaySign(true);
var (identityMscorlib, moduleMscorlib) = (MscorlibRef.GetAssemblyIdentity(), MscorlibRef.ToModuleInstance());
var (identityOther, moduleOther, refOther) = Compile(new AssemblyIdentity(identityMscorlib.Name, new Version(1, 1, 1, 1), publicKeyOrToken: publicKeyOther, hasPublicKey: true), "class Other { }", options, MscorlibRef);
var (identityA, moduleA, refA) = Compile(new AssemblyIdentity("A", new Version(1, 1, 1, 1)), "public class A { }", TestOptions.DebugDll, refOther, MscorlibRef);
var (identityB, moduleB, refB) = Compile(new AssemblyIdentity("B", new Version(1, 1, 1, 1)), "public class B : A { static void M() { } }", TestOptions.DebugDll, refA, refOther, MscorlibRef);
using (var runtime = CreateRuntimeInstance(new[] { moduleMscorlib, moduleA, moduleB }))
{
var stateB = GetContextState(runtime, "B.M");
var (moduleVersionId, symReader, methodToken, localSignatureToken, ilOffset) = GetContextState(runtime, "B.M");
var context = CreateMethodContext(
new AppDomain(),
ImmutableArray.Create(moduleMscorlib, moduleOther, moduleA, moduleB).SelectAsArray(m => m.MetadataBlock),
stateB);
string error;
var testData = new CompilationTestData();
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
}");
VerifyResolutionRequests(context, (identityA, identityA, 1));
context = CreateMethodContext(
new AppDomain(),
ImmutableArray.Create(moduleB, moduleA, moduleOther, moduleMscorlib).SelectAsArray(m => m.MetadataBlock),
stateB);
testData = new CompilationTestData();
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
}");
VerifyResolutionRequests(context, (identityA, identityA, 1));
}
}
/// <summary>
/// Reuse compilation across evaluations unless current assembly changes.
/// </summary>
[Fact]
public void ReuseCompilation()
{
var (identityMscorlib, moduleMscorlib) = (MscorlibRef.GetAssemblyIdentity(), MscorlibRef.ToModuleInstance());
var (identityA1, moduleA1, refA1) = Compile("A1", "public class A1 { static void M() { } }");
var (identityA2, moduleA2, refA2) = Compile("A2", "public class A2 { static void M() { } } public class A3 { static void M() { } }");
var (identityB1, moduleB1, refB1) = Compile("B1", "public class B1 : A1 { static void M() { } } public class B2 { static void M() { } }", refA1);
using (var runtime = CreateRuntimeInstance(new[] { moduleMscorlib, moduleA1, moduleA2, moduleB1 }))
{
var blocks = runtime.Modules.SelectAsArray(m => m.MetadataBlock);
var stateA1 = GetContextState(runtime, "A1.M");
var stateA2 = GetContextState(runtime, "A2.M");
var stateA3 = GetContextState(runtime, "A3.M");
var stateB1 = GetContextState(runtime, "B1.M");
var stateB2 = GetContextState(runtime, "B2.M");
var mvidA1 = stateA1.ModuleVersionId;
var mvidA2 = stateA2.ModuleVersionId;
var mvidB1 = stateB1.ModuleVersionId;
Assert.Equal(mvidB1, stateB2.ModuleVersionId);
EvaluationContext context;
MetadataContext<CSharpMetadataContext> previous;
// B1 -> B2 -> A1 -> A2 -> A3
// B1.M:
var appDomain = new AppDomain();
previous = appDomain.GetMetadataContext();
context = CreateMethodContext(appDomain, blocks, stateB1);
VerifyResolutionRequests(context, (identityA1, identityA1, 1));
VerifyAppDomainMetadataContext(appDomain, mvidB1);
// B2.M:
previous = appDomain.GetMetadataContext();
context = CreateMethodContext(appDomain, blocks, stateB2);
Assert.NotSame(context, GetMetadataContext(previous, mvidB1).EvaluationContext);
Assert.Same(context.Compilation, GetMetadataContext(previous, mvidB1).Compilation);
VerifyResolutionRequests(context, (identityA1, identityA1, 1));
VerifyAppDomainMetadataContext(appDomain, mvidB1);
// A1.M:
previous = appDomain.GetMetadataContext();
context = CreateMethodContext(appDomain, blocks, stateA1);
Assert.NotSame(context, GetMetadataContext(previous, mvidB1).EvaluationContext);
Assert.NotSame(context.Compilation, GetMetadataContext(previous, mvidB1).Compilation);
VerifyResolutionRequests(context);
VerifyAppDomainMetadataContext(appDomain, mvidB1, mvidA1);
// A2.M:
previous = appDomain.GetMetadataContext();
context = CreateMethodContext(appDomain, blocks, stateA2);
Assert.NotSame(context, GetMetadataContext(previous, mvidA1).EvaluationContext);
Assert.NotSame(context.Compilation, GetMetadataContext(previous, mvidA1).Compilation);
VerifyResolutionRequests(context);
VerifyAppDomainMetadataContext(appDomain, mvidB1, mvidA1, mvidA2);
// A3.M:
previous = appDomain.GetMetadataContext();
context = CreateMethodContext(appDomain, blocks, stateA3);
Assert.NotSame(context, GetMetadataContext(previous, mvidA2).EvaluationContext);
Assert.Same(context.Compilation, GetMetadataContext(previous, mvidA2).Compilation);
VerifyResolutionRequests(context);
VerifyAppDomainMetadataContext(appDomain, mvidB1, mvidA1, mvidA2);
// A1 -> A2 -> A3 -> B1 -> B2
// A1.M:
appDomain = new AppDomain();
context = CreateMethodContext(appDomain, blocks, stateA1);
VerifyResolutionRequests(context);
VerifyAppDomainMetadataContext(appDomain, mvidA1);
// A2.M:
previous = appDomain.GetMetadataContext();
context = CreateMethodContext(appDomain, blocks, stateA2);
Assert.NotSame(context, GetMetadataContext(previous, mvidA1).EvaluationContext);
Assert.NotSame(context.Compilation, GetMetadataContext(previous, mvidA1).Compilation);
VerifyResolutionRequests(context);
VerifyAppDomainMetadataContext(appDomain, mvidA1, mvidA2);
// A3.M:
previous = appDomain.GetMetadataContext();
context = CreateMethodContext(appDomain, blocks, stateA3);
Assert.NotSame(context, GetMetadataContext(previous, mvidA2).EvaluationContext);
Assert.Same(context.Compilation, GetMetadataContext(previous, mvidA2).Compilation);
VerifyResolutionRequests(context);
VerifyAppDomainMetadataContext(appDomain, mvidA1, mvidA2);
// B1.M:
previous = appDomain.GetMetadataContext();
context = CreateMethodContext(appDomain, blocks, stateB1);
Assert.NotSame(context, GetMetadataContext(previous, mvidA2).EvaluationContext);
Assert.NotSame(context.Compilation, GetMetadataContext(previous, mvidA2).Compilation);
VerifyResolutionRequests(context, (identityA1, identityA1, 1));
VerifyAppDomainMetadataContext(appDomain, mvidA1, mvidA2, mvidB1);
// B2.M:
previous = appDomain.GetMetadataContext();
context = CreateMethodContext(appDomain, blocks, stateB2);
Assert.NotSame(context, GetMetadataContext(previous, mvidB1).EvaluationContext);
Assert.Same(context.Compilation, GetMetadataContext(previous, mvidB1).Compilation);
VerifyResolutionRequests(context, (identityA1, identityA1, 1));
VerifyAppDomainMetadataContext(appDomain, mvidA1, mvidA2, mvidB1);
}
}
private static void VerifyAppDomainMetadataContext(AppDomain appDomain, params Guid[] moduleVersionIds)
{
ExpressionCompilerTestHelpers.VerifyAppDomainMetadataContext(appDomain.GetMetadataContext(), moduleVersionIds);
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26159")]
public void TypeOutsideAssemblyReferences()
{
var sourceA =
@"public class A
{
void M()
{
}
}";
var sourceB =
@"#pragma warning disable 169
class B : A
{
object F;
}";
var (identityMscorlib, moduleMscorlib) = (MscorlibRef.GetAssemblyIdentity(), MscorlibRef.ToModuleInstance());
var (identityA, moduleA, refA) = Compile("A", sourceA);
var (identityB, moduleB, refB) = Compile("B", sourceB, refA);
using (var runtime = CreateRuntimeInstance(new[] { moduleMscorlib, moduleA, moduleB }))
{
var blocks = runtime.Modules.SelectAsArray(m => m.MetadataBlock);
var stateA = GetContextState(runtime, "A.M");
const string expr = "((B)this).F";
// A.M, all assemblies
var context = CreateMethodContext(new AppDomain(), blocks, stateA, MakeAssemblyReferencesKind.AllAssemblies);
string error;
var testData = new CompilationTestData();
context.CompileExpression(expr, out error, testData);
var methodData = testData.GetMethodData("<>x.<>m0");
methodData.VerifyIL(
@"{
// Code size 12 (0xc)
.maxstack 1
IL_0000: ldarg.0
IL_0001: castclass ""B""
IL_0006: ldfld ""object B.F""
IL_000b: ret
}");
// A.M, all referenced assemblies
context = CreateMethodContext(new AppDomain(), blocks, stateA, MakeAssemblyReferencesKind.AllReferences);
testData = new CompilationTestData();
context.CompileExpression(expr, out error, testData);
Assert.Equal("error CS0246: The type or namespace name 'B' could not be found (are you missing a using directive or an assembly reference?)", error);
}
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1141029")]
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 appDomain = new AppDomain();
var context = CreateTypeContext(
appDomain,
typeBlocks,
moduleVersionId,
typeToken,
MakeAssemblyReferencesKind.AllAssemblies);
Assert.Equal(identityAS2, context.Compilation.GlobalNamespace.GetMembers("A").OfType<NamedTypeSymbol>().Single().ContainingAssembly.Identity);
Assert.Equal(identityBS2, context.Compilation.GlobalNamespace.GetMembers("B").OfType<NamedTypeSymbol>().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);
appDomain.SetMetadataContext(
SetMetadataContext(
new MetadataContext<CSharpMetadataContext>(typeBlocks, ImmutableDictionary<MetadataContextId, CSharpMetadataContext>.Empty),
default(Guid),
new CSharpMetadataContext(context.Compilation)));
// Compile expression with type context with referenced modules only.
context = CreateTypeContext(
appDomain,
typeBlocks,
moduleVersionId,
typeToken,
MakeAssemblyReferencesKind.DirectReferencesOnly);
// 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 CS0246: The type or namespace name 'A' could not be found (are you missing a using directive or an assembly reference?)", error);
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(((MethodSymbol)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.
var previous = appDomain.GetMetadataContext();
context = CreateMethodContext(
appDomain,
methodBlocks,
symReader,
moduleVersionId,
methodToken: methodToken,
methodVersion: 1,
ilOffset: ilOffset,
localSignatureToken: localSignatureToken,
MakeAssemblyReferencesKind.AllAssemblies);
Assert.NotSame(GetMetadataContext(previous).EvaluationContext, context);
Assert.Same(GetMetadataContext(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 = CreateMethodContext(
appDomain,
methodBlocks,
symReader,
moduleVersionId,
methodToken: methodToken,
methodVersion: 1,
ilOffset: ilOffset,
localSignatureToken: localSignatureToken,
MakeAssemblyReferencesKind.DirectReferencesOnly);
// 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 CS0246: The type or namespace name 'A' could not be found (are you missing a using directive or an assembly reference?)", error);
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(((MethodSymbol)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));
});
}
private static (AssemblyIdentity Identity, ModuleInstance Module, MetadataReference Reference) Compile(string assemblyName, string source, params MetadataReference[] references)
{
var compilation = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll, references: references, assemblyName: assemblyName);
compilation.VerifyDiagnostics();
var module = compilation.ToModuleInstance();
return (compilation.Assembly.Identity, module, module.GetReference());
}
private static (AssemblyIdentity Identity, ModuleInstance Module, MetadataReference Reference) Compile(AssemblyIdentity identity, string source, CSharpCompilationOptions options, params MetadataReference[] references)
{
var compilation = CreateCompilation(identity, new[] { source }, references: references, options: options);
compilation.VerifyDiagnostics();
var module = compilation.ToModuleInstance();
return (compilation.Assembly.Identity, module, module.GetReference());
}
private static void VerifyAssemblyReferences(
MetadataReference target,
ImmutableArray<MetadataReference> references,
ImmutableArray<AssemblyIdentity> expectedIdentities)
{
Assert.True(references.Contains(target));
var modules = references.SelectAsArray(r => r.ToModuleInstance());
using (var runtime = new RuntimeInstance(modules, DebugInformationFormat.Pdb))
{
var moduleVersionId = target.GetModuleVersionId();
var blocks = runtime.Modules.SelectAsArray(m => m.MetadataBlock);
IReadOnlyDictionary<string, ImmutableArray<(AssemblyIdentity, MetadataReference)>> referencesBySimpleName;
var actualReferences = blocks.MakeAssemblyReferences(moduleVersionId, CompilationExtensions.IdentityComparer, MakeAssemblyReferencesKind.DirectReferencesOnly, out referencesBySimpleName);
Assert.Null(referencesBySimpleName);
// Verify identities.
var actualIdentities = actualReferences.SelectAsArray(r => r.GetAssemblyIdentity());
AssertEx.Equal(expectedIdentities, actualIdentities);
// Verify identities are unique.
var uniqueIdentities = actualIdentities.Distinct();
Assert.Equal(actualIdentities.Length, uniqueIdentities.Length);
actualReferences = blocks.MakeAssemblyReferences(moduleVersionId, CompilationExtensions.IdentityComparer, MakeAssemblyReferencesKind.AllReferences, out referencesBySimpleName);
Assert.Equal(2, actualReferences.Length);
Assert.Equal(moduleVersionId, actualReferences[1].GetModuleVersionId());
foreach (var reference in references)
{
var identity = reference.GetAssemblyIdentity();
var pairs = referencesBySimpleName[identity.Name];
var other = pairs.FirstOrDefault(p => identity.Equals(p.Item1));
Assert.Equal(identity, other.Item1);
}
}
}
private static void VerifyResolutionRequests(EvaluationContext context, params (AssemblyIdentity, AssemblyIdentity, int)[] expectedRequests)
{
ExpressionCompilerTestHelpers.VerifyResolutionRequests(
(EEMetadataReferenceResolver)context.Compilation.Options.MetadataReferenceResolver,
expectedRequests);
}
[Fact]
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 = CreateCompilationWithMscorlib40AndSystemCore(sourceA, options: TestOptions.DebugDll);
var identityA = compilationA.Assembly.Identity;
var moduleA = compilationA.ToModuleInstance();
var compilationB = CreateCompilationWithMscorlib40AndSystemCore(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);
IEnumerable<string> CS0433Messages(string type)
{
yield return "error CS0433: " + string.Format(CSharpResources.ERR_SameFullNameAggAgg, compilationA.Assembly.Identity, type, compilationB.Assembly.Identity);
yield return "error CS0433: " + string.Format(CSharpResources.ERR_SameFullNameAggAgg, compilationB.Assembly.Identity, type, compilationA.Assembly.Identity);
}
Assert.Contains(errorMessage, CS0433Messages("C1"));
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.Contains(errorMessage, CS0433Messages("C1"));
// 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.Contains(errorMessage, CS0433Messages("C2"));
// 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($"error CS0121: {string.Format(CSharpResources.ERR_AmbigCall, "N.E.F(A)", "N.E.F(A)")}", errorMessage);
// 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(((MethodSymbol)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(((MethodSymbol)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(((MethodSymbol)methodData.Method).ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName());
}
/// <summary>
/// mscorlib.dll is not directly referenced from an assembly
/// compiled against portable framework assemblies.
/// </summary>
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1150981")]
public void MissingMscorlib()
{
var sourceA =
@"public class A
{
}
class B
{
}
class C
{
}";
var sourceB =
@"public class B : A
{
}";
var moduleA = CreateEmptyCompilation(
sourceA,
references: new[] { SystemRuntimePP7Ref },
options: TestOptions.DebugDll).ToModuleInstance();
var moduleB = CreateEmptyCompilation(
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(TestResources.ExpressionCompiler.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
}");
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1170032")]
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 = CreateCompilation(sourceConsole, options: TestOptions.DebugDll, assemblyName: "System.Console");
var systemConsoleRef = systemConsoleComp.EmitToImageReference();
var systemObjectModelComp = CreateCompilation(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 = CreateEmptyCompilation(
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 = CreateEmptyCompilation(
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(((MethodSymbol)methodData.Method).ReturnType.ContainingAssembly.ToDisplayString(), identityObjectModel.GetDisplayName());
});
}
/// <summary>
/// Intrinsic methods assembly should not be dropped.
/// </summary>
[WorkItem("https://github.com/dotnet/roslyn/issues/4140")]
[ConditionalFact(typeof(IsRelease), Reason = "https://github.com/dotnet/roslyn/issues/25702")]
public void IntrinsicMethods()
{
var sourceA =
@"public class A { }";
var sourceB =
@"public class A { }
public class B
{
static void M(A a)
{
}
}";
var compilationA = CreateCompilationWithMscorlib40AndSystemCore(sourceA, options: TestOptions.DebugDll);
var moduleA = compilationA.ToModuleInstance();
var compilationB = CreateCompilationWithMscorlib40AndSystemCore(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
}");
}
private const string CorLibAssemblyName = "System.Private.CoreLib";
// An assembly with the expected corlib name and with System.Object should
// be considered the corlib, even with references to external assemblies.
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30030")]
[WorkItem("https://github.com/dotnet/roslyn/issues/13275")]
public void CorLibWithAssemblyReferences()
{
string sourceLib =
@"public class Private1
{
}
public class Private2
{
}";
var parseOptions = TestOptions.Regular.WithNoRefSafetyRulesAttribute();
var compLib = CreateCompilation(sourceLib, assemblyName: "System.Private.Library", parseOptions: parseOptions);
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 = CreateEmptyCompilation(sourceCorLib, assemblyName: CorLibAssemblyName, references: new[] { MscorlibRef, refLib }, parseOptions: parseOptions);
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.GetCciAdapter()),
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 = CreateEmptyCompilation(source, options: TestOptions.DebugDll, references: new[] { refLib, AssemblyMetadata.Create(module).GetReference() }, parseOptions: parseOptions);
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);
}
}
}
// References to missing assembly from PDB custom debug info.
[Theory, WorkItem("https://github.com/dotnet/roslyn/issues/13275")]
[MemberData(nameof(NonNullTypesTrueAndFalseReleaseDll))]
public void CorLibWithAssemblyReferences_Pdb(CSharpCompilationOptions options)
{
string sourceLib =
@"namespace Namespace
{
public class Private { }
}";
var compLib = CreateCompilation(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 = CreateEmptyCompilation(sourceCorLib, assemblyName: CorLibAssemblyName, references: new[] { MscorlibRef, refLib }, options: options);
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.GetCciAdapter()),
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);
}
}
}
// An assembly with the expected corlib name but without
// System.Object should not be considered the corlib.
[Fact]
public void CorLibWithAssemblyReferencesNoSystemObject()
{
// Assembly with expected corlib name but without System.Object declared.
string sourceLib =
@"class Private
{
}";
var compLib = CreateCompilation(sourceLib, assemblyName: CorLibAssemblyName);
compLib.VerifyDiagnostics();
var refLib = compLib.EmitToImageReference();
var source =
@"class C
{
static void M()
{
}
}";
var comp = CreateCompilation(source, options: TestOptions.DebugDll);
comp.VerifyDiagnostics();
using (var runtime = RuntimeInstance.Create(new[] { comp.ToModuleInstance(), refLib.ToModuleInstance(), MscorlibRef.ToModuleInstance() }))
{
string error;
var context = CreateMethodContext(runtime, "C.M");
var testData = new CompilationTestData();
context.CompileExpression(
"1.GetType()",
out error,
testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
// Code size 12 (0xc)
.maxstack 1
IL_0000: ldc.i4.1
IL_0001: box ""int""
IL_0006: call ""System.Type object.GetType()""
IL_000b: ret
}");
}
}
private static ExpressionCompiler.CreateContextDelegate CreateTypeContextFactory(
Guid moduleVersionId,
int typeToken)
{
return (blocks, useReferencedModulesOnly) => EvaluationContext.CreateTypeContext(
ToCompilation(blocks, useReferencedModulesOnly, moduleVersionId),
moduleVersionId,
typeToken);
}
private static ExpressionCompiler.CreateContextDelegate CreateMethodContextFactory(
Guid moduleVersionId,
ISymUnmanagedReader symReader,
int methodToken,
int localSignatureToken)
{
return (blocks, useReferencedModulesOnly) => EvaluationContext.CreateMethodContext(
ToCompilation(blocks, useReferencedModulesOnly, moduleVersionId),
symReader,
moduleVersionId,
methodToken,
methodVersion: 1,
ilOffset: 0,
localSignatureToken: localSignatureToken);
}
private static CSharpCompilation ToCompilation(
ImmutableArray<MetadataBlock> blocks,
bool useReferencedModulesOnly,
Guid moduleVersionId)
{
return blocks.ToCompilation(moduleVersionId, useReferencedModulesOnly ? MakeAssemblyReferencesKind.DirectReferencesOnly : MakeAssemblyReferencesKind.AllAssemblies);
}
private sealed class PEAssemblyBuilderWithAdditionalReferences : PEModuleBuilder, IAssemblyReference
{
private readonly CommonPEModuleBuilder _builder;
private readonly NamespaceTypeDefinitionNoBase _objectType;
internal PEAssemblyBuilderWithAdditionalReferences(CommonPEModuleBuilder builder, EmitOptions emitOptions, INamespaceTypeDefinition objectType) :
base((SourceModuleSymbol)builder.CommonSourceModule, emitOptions, builder.OutputKind, builder.SerializationProperties, builder.ManifestResources)
{
_builder = builder;
_objectType = new NamespaceTypeDefinitionNoBase(objectType);
}
public override IEnumerable<INamespaceTypeDefinition> GetTopLevelSourceTypeDefinitions(EmitContext context)
{
foreach (var type in base.GetTopLevelSourceTypeDefinitions(context))
{
yield return (type == _objectType.UnderlyingType) ? _objectType : type;
}
}
public override SymbolChanges EncSymbolChanges => _builder.EncSymbolChanges;
public override EmitBaseline PreviousGeneration => _builder.PreviousGeneration;
public override ISourceAssemblySymbolInternal SourceAssemblyOpt => _builder.SourceAssemblyOpt;
public override IEnumerable<IFileReference> GetFiles(EmitContext context) => _builder.GetFiles(context);
protected override void AddEmbeddedResourcesFromAddedModules(ArrayBuilder<ManagedResource> builder, DiagnosticBag diagnostics)
{
}
internal override SynthesizedAttributeData SynthesizeEmbeddedAttribute()
{
throw new NotImplementedException();
}
AssemblyIdentity IAssemblyReference.Identity => ((IAssemblyReference)_builder).Identity;
Version IAssemblyReference.AssemblyVersionPattern => ((IAssemblyReference)_builder).AssemblyVersionPattern;
}
}
}
|