/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/ReferencedModulesTests.vb
1 033 строки
51 KB
Tomáš Matoušek
EnC: Block additions to MethodImpl table when targeting .NET Framework (#81304)
03 дек 2025, 23:18
Не верифицирован
03 дек 2025, 23:18
264f04f
Код
Авторство
О чём код?
' 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. Imports System.Collections.Immutable Imports System.Reflection.Metadata Imports System.Reflection.PortableExecutable Imports Microsoft.Cci Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.CodeGen Imports Microsoft.CodeAnalysis.Emit Imports Microsoft.CodeAnalysis.ExpressionEvaluator Imports Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.Symbols Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Emit Imports Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.UnitTests Imports Microsoft.DiaSymReader Imports Microsoft.VisualStudio.Debugger.Evaluation Imports Roslyn.Test.Utilities Imports Xunit Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator.UnitTests Public Class ReferencedModulesTests Inherits ExpressionCompilerTestBase ''' <summary> ''' MakeAssemblyReferences should drop unreferenced assemblies. ''' </summary> <Fact> Public Sub UnreferencedAssemblies() Const sourceA1 = "Public Class A1 Private Shared Sub M() End Sub End Class" Const sourceA2 = "Public Class A2 Private Shared Sub M() End Sub End Class" Const sourceB1 = "Public Class B1 Inherits A1 Private Shared Sub M() End Sub End Class" Const sourceB2 = "Public Class B2 Inherits A1 Private Shared Sub M() End Sub End Class" Const sourceC = "Class C1 Inherits B2 Private Shared Sub M() End Sub End Class Class C2 Inherits A2 End Class" Dim moduleMscorlib = (Identity:=MscorlibRef.GetAssemblyIdentity(), [Module]:=MscorlibRef.ToModuleInstance()) Dim moduleIntrinsic = (Identity:=ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.GetAssemblyIdentity(), [Module]:=ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance()) Dim moduleA1 = Compile("A1", sourceA1) Dim moduleA2 = Compile("A2", sourceA2) Dim moduleB1 = Compile("B1", sourceB1, moduleA1.Reference) Dim moduleB2 = Compile("B2", sourceB2, moduleA1.Reference) Dim moduleC = Compile("C", sourceC, moduleA1.Reference, moduleA2.Reference, moduleB2.Reference) Using runtime = CreateRuntimeInstance({moduleMscorlib.Module, moduleA1.Module, moduleA2.Module, moduleB1.Module, moduleB2.Module, moduleC.Module}) Dim stateB2 = GetContextState(runtime, "B2.M") ' B2.M with missing A1. Dim context = CreateMethodContext( New AppDomain(), ImmutableArray.Create(moduleMscorlib.Module, moduleA2.Module, moduleB1.Module, moduleB2.Module, moduleC.Module).SelectAsArray(Function(m) m.MetadataBlock), stateB2) Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() Dim missingAssemblyIdentities As ImmutableArray(Of AssemblyIdentity) = Nothing context.CompileExpression( "New B2()", DkmEvaluationFlags.TreatAsExpression, NoAliases, DebuggerDiagnosticFormatter.Instance, resultProperties, errorMessage, missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData) Assert.Equal("error BC30652: Reference required to assembly 'A1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' containing the type 'A1'. Add one to your project.", errorMessage) AssertEx.Equal({moduleA1.Identity}, missingAssemblyIdentities) VerifyResolutionRequests(context, (moduleA1.Identity, Nothing, 1)) ' B2.M with all assemblies. context = CreateMethodContext( New AppDomain(), ImmutableArray.Create(moduleMscorlib.Module, moduleA1.Module, moduleA2.Module, moduleB1.Module, moduleB2.Module, moduleC.Module).SelectAsArray(Function(m) m.MetadataBlock), stateB2) testData = New CompilationTestData() context.CompileExpression("New B2()", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""Sub B2..ctor()"" IL_0005: ret }") VerifyResolutionRequests(context, (moduleA1.Identity, moduleA1.Identity, 1)) ' B2.M with all assemblies in reverse order. context = CreateMethodContext( New AppDomain(), ImmutableArray.Create(moduleC.Module, moduleB2.Module, moduleB1.Module, moduleA2.Module, moduleA1.Module, moduleMscorlib.Module, moduleIntrinsic.Module).SelectAsArray(Function(m) m.MetadataBlock), stateB2) testData = New CompilationTestData() context.CompileExpression("New B2()", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""Sub B2..ctor()"" IL_0005: ret }") VerifyResolutionRequests(context, (moduleA1.Identity, moduleA1.Identity, 1)) ' A1.M with all assemblies. Dim stateA1 = GetContextState(runtime, "A1.M") context = CreateMethodContext( New AppDomain(), ImmutableArray.Create(moduleMscorlib.Module, moduleA1.Module, moduleA2.Module, moduleB1.Module, moduleB2.Module, moduleC.Module).SelectAsArray(Function(m) m.MetadataBlock), stateA1) testData = New CompilationTestData() context.CompileExpression("New A1()", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""Sub A1..ctor()"" IL_0005: ret }") VerifyResolutionRequests(context) ' B1.M with all assemblies. Dim stateB1 = GetContextState(runtime, "B1.M") context = CreateMethodContext( New AppDomain(), ImmutableArray.Create(moduleMscorlib.Module, moduleA1.Module, moduleA2.Module, moduleB1.Module, moduleB2.Module, moduleC.Module).SelectAsArray(Function(m) m.MetadataBlock), stateB1) testData = New CompilationTestData() context.CompileExpression("New B1()", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""Sub B1..ctor()"" IL_0005: ret }") VerifyResolutionRequests(context, (moduleA1.Identity, moduleA1.Identity, 1)) ' C1.M with all assemblies. Dim stateC = GetContextState(runtime, "C1.M") context = CreateMethodContext( New AppDomain(), ImmutableArray.Create(moduleMscorlib.Module, moduleA1.Module, moduleA2.Module, moduleB1.Module, moduleB2.Module, moduleC.Module).SelectAsArray(Function(m) m.MetadataBlock), stateC) testData = New CompilationTestData() context.CompileExpression("New C1()", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""Sub C1..ctor()"" IL_0005: ret }") VerifyResolutionRequests(context, (moduleB2.Identity, moduleB2.Identity, 1), (moduleA1.Identity, moduleA1.Identity, 1), (moduleA2.Identity, moduleA2.Identity, 1)) ' Other EvaluationContext.CreateMethodContext overload. ' A1.M with all assemblies. Dim allBlocks = ImmutableArray.Create(moduleMscorlib.Module, moduleA1.Module, moduleA2.Module, moduleB1.Module, moduleB2.Module, moduleC.Module).SelectAsArray(Function(m) m.MetadataBlock) context = EvaluationContext.CreateMethodContext( New VisualBasicMetadataContext(), allBlocks, MakeDummyLazyAssemblyReaders(), stateA1.SymReader, stateA1.ModuleId, stateA1.MethodToken, methodVersion:=1, stateA1.ILOffset, stateA1.LocalSignatureToken) testData = New CompilationTestData() context.CompileExpression("New B1()", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""Sub B1..ctor()"" IL_0005: ret }") ' Other EvaluationContext.CreateMethodContext overload. ' A1.M with all assemblies, offset outside of IL. context = EvaluationContext.CreateMethodContext( New VisualBasicMetadataContext(), allBlocks, MakeDummyLazyAssemblyReaders(), stateA1.SymReader, stateA1.ModuleId, stateA1.MethodToken, methodVersion:=1, UInteger.MaxValue, stateA1.LocalSignatureToken) testData = New CompilationTestData() context.CompileExpression("New C1()", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""Sub C1..ctor()"" IL_0005: ret }") End Using End Sub ''' <summary> ''' Reuse compilation across evaluations unless current assembly changes. ''' </summary> <Fact> Public Sub ReuseCompilation() Const sourceA1 = "Public Class A1 Private Shared Sub M() End Sub End Class" Const sourceA2 = "Public Class A2 Private Shared Sub M() End Sub End Class Public Class A3 Private Shared Sub M() End Sub End Class" Const sourceB1 = "Public Class B1 Inherits A1 Private Shared Sub M() End Sub End Class Public Class B2 Private Shared Sub M() End Sub End Class" Dim moduleMscorlib = (Identity:=MscorlibRef.GetAssemblyIdentity(), [Module]:=MscorlibRef.ToModuleInstance()) Dim moduleIntrinsic = (Identity:=ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.GetAssemblyIdentity(), [Module]:=ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance()) Dim moduleA1 = Compile("A1", sourceA1) Dim moduleA2 = Compile("A2", sourceA2) Dim moduleB1 = Compile("B1", sourceB1, moduleA1.Reference) Using runtime = CreateRuntimeInstance({moduleMscorlib.Module, moduleA1.Module, moduleA2.Module, moduleB1.Module}) Dim blocks = runtime.Modules.SelectAsArray(Function(m) m.MetadataBlock) Dim stateA1 = GetContextState(runtime, "A1.M") Dim stateA2 = GetContextState(runtime, "A2.M") Dim stateA3 = GetContextState(runtime, "A3.M") Dim stateB1 = GetContextState(runtime, "B1.M") Dim stateB2 = GetContextState(runtime, "B2.M") Dim mvidA1 = stateA1.ModuleId Dim mvidA2 = stateA2.ModuleId Dim mvidB1 = stateB1.ModuleId Dim context As EvaluationContext Dim previous As MetadataContext(Of VisualBasicMetadataContext) ' B1 -> B2 -> A1 -> A2 -> A3 ' B1.M: Dim appDomain = New AppDomain() previous = appDomain.GetMetadataContext() context = CreateMethodContext(appDomain, blocks, stateB1) VerifyResolutionRequests(context, (moduleA1.Identity, moduleA1.Identity, 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, (moduleA1.Identity, moduleA1.Identity, 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() previous = appDomain.GetMetadataContext() 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, (moduleA1.Identity, moduleA1.Identity, 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, (moduleA1.Identity, moduleA1.Identity, 1)) VerifyAppDomainMetadataContext(appDomain, mvidA1, mvidA2, mvidB1) End Using End Sub Private Shared Sub VerifyAppDomainMetadataContext(appDomain As AppDomain, ParamArray moduleIds As ModuleId()) ExpressionCompilerTestHelpers.VerifyAppDomainMetadataContext(appDomain.GetMetadataContext(), moduleIds) End Sub <Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1141029")> Public Sub AssemblyDuplicateReferences() Const sourceA = "Public Class A End Class" Const sourceB = "Public Class B Public F As New A() End Class" Const sourceC = "Class C Public F As New B() Shared Sub M() End Sub End Class" ' Assembly A, multiple versions, strong name. Dim assemblyNameA = ExpressionCompilerUtilities.GenerateUniqueName() Dim publicKeyA = ImmutableArray.CreateRange(Of Byte)({&H0, &H24, &H0, &H0, &H4, &H80, &H0, &H0, &H94, &H0, &H0, &H0, &H6, &H2, &H0, &H0, &H0, &H24, &H0, &H0, &H52, &H53, &H41, &H31, &H0, &H4, &H0, &H0, &H1, &H0, &H1, &H0, &HED, &HD3, &H22, &HCB, &H6B, &HF8, &HD4, &HA2, &HFC, &HCC, &H87, &H37, &H4, &H6, &H4, &HCE, &HE7, &HB2, &HA6, &HF8, &H4A, &HEE, &HF3, &H19, &HDF, &H5B, &H95, &HE3, &H7A, &H6A, &H28, &H24, &HA4, &HA, &H83, &H83, &HBD, &HBA, &HF2, &HF2, &H52, &H20, &HE9, &HAA, &H3B, &HD1, &HDD, &HE4, &H9A, &H9A, &H9C, &HC0, &H30, &H8F, &H1, &H40, &H6, &HE0, &H2B, &H95, &H62, &H89, &H2A, &H34, &H75, &H22, &H68, &H64, &H6E, &H7C, &H2E, &H83, &H50, &H5A, &HCE, &H7B, &HB, &HE8, &HF8, &H71, &HE6, &HF7, &H73, &H8E, &HEB, &H84, &HD2, &H73, &H5D, &H9D, &HBE, &H5E, &HF5, &H90, &HF9, &HAB, &HA, &H10, &H7E, &H23, &H48, &HF4, &HAD, &H70, &H2E, &HF7, &HD4, &H51, &HD5, &H8B, &H3A, &HF7, &HCA, &H90, &H4C, &HDC, &H80, &H19, &H26, &H65, &HC9, &H37, &HBD, &H52, &H81, &HF1, &H8B, &HCD}) Dim compilationAS1 = CreateEmptyCompilation( New AssemblyIdentity(assemblyNameA, New Version(1, 1, 1, 1), cultureName:="", publicKeyOrToken:=publicKeyA, hasPublicKey:=True), {sourceA}, references:={MscorlibRef}, options:=TestOptions.DebugDll.WithDelaySign(True)) Dim referenceAS1 = compilationAS1.EmitToImageReference() Dim identityAS1 = referenceAS1.GetAssemblyIdentity() Dim compilationAS2 = CreateEmptyCompilation( New AssemblyIdentity(assemblyNameA, New Version(2, 1, 1, 1), cultureName:="", publicKeyOrToken:=publicKeyA, hasPublicKey:=True), {sourceA}, references:={MscorlibRef}, options:=TestOptions.DebugDll.WithDelaySign(True)) Dim referenceAS2 = compilationAS2.EmitToImageReference() Dim identityAS2 = referenceAS2.GetAssemblyIdentity() ' Assembly B, multiple versions, strong name. Dim assemblyNameB = ExpressionCompilerUtilities.GenerateUniqueName() Dim publicKeyB = ImmutableArray.CreateRange(Of Byte)({&H0, &H24, &H0, &H0, &H4, &H80, &H0, &H0, &H94, &H0, &H0, &H0, &H6, &H2, &H0, &H0, &H0, &H24, &H0, &H0, &H53, &H52, &H41, &H31, &H0, &H4, &H0, &H0, &H1, &H0, &H1, &H0, &HED, &HD3, &H22, &HCB, &H6B, &HF8, &HD4, &HA2, &HFC, &HCC, &H87, &H37, &H4, &H6, &H4, &HCE, &HE7, &HB2, &HA6, &HF8, &H4A, &HEE, &HF3, &H19, &HDF, &H5B, &H95, &HE3, &H7A, &H6A, &H28, &H24, &HA4, &HA, &H83, &H83, &HBD, &HBA, &HF2, &HF2, &H52, &H20, &HE9, &HAA, &H3B, &HD1, &HDD, &HE4, &H9A, &H9A, &H9C, &HC0, &H30, &H8F, &H1, &H40, &H6, &HE0, &H2B, &H95, &H62, &H89, &H2A, &H34, &H75, &H22, &H68, &H64, &H6E, &H7C, &H2E, &H83, &H50, &H5A, &HCE, &H7B, &HB, &HE8, &HF8, &H71, &HE6, &HF7, &H73, &H8E, &HEB, &H84, &HD2, &H73, &H5D, &H9D, &HBE, &H5E, &HF5, &H90, &HF9, &HAB, &HA, &H10, &H7E, &H23, &H48, &HF4, &HAD, &H70, &H2E, &HF7, &HD4, &H51, &HD5, &H8B, &H3A, &HF7, &HCA, &H90, &H4C, &HDC, &H80, &H19, &H26, &H65, &HC9, &H37, &HBD, &H52, &H81, &HF1, &H8B, &HCD}) Dim compilationBS1 = CreateEmptyCompilation( New AssemblyIdentity(assemblyNameB, New Version(1, 1, 1, 1), cultureName:="", publicKeyOrToken:=publicKeyB, hasPublicKey:=True), {sourceB}, references:={MscorlibRef, referenceAS1}, options:=TestOptions.DebugDll.WithDelaySign(True)) Dim referenceBS1 = compilationBS1.EmitToImageReference() Dim identityBS1 = referenceBS1.GetAssemblyIdentity() Dim compilationBS2 = CreateEmptyCompilation( New AssemblyIdentity(assemblyNameB, New Version(2, 2, 2, 1), cultureName:="", publicKeyOrToken:=publicKeyB, hasPublicKey:=True), {sourceB}, references:={MscorlibRef, referenceAS2}, options:=TestOptions.DebugDll.WithDelaySign(True)) Dim referenceBS2 = compilationBS2.EmitToImageReference() Dim identityBS2 = referenceBS2.GetAssemblyIdentity() ' Assembly C, multiple versions, not strong name. Dim compilationCN1 = CreateEmptyCompilation( New AssemblyIdentity("C", New Version(1, 1, 1, 1)), {sourceC}, references:={MscorlibRef, referenceBS1}, options:=TestOptions.DebugDll) ' Duplicate assemblies, target module referencing BS1. WithRuntimeInstance(compilationCN1, {MscorlibRef, referenceAS1, referenceAS2, referenceBS2, referenceBS1, referenceBS2}, Sub(runtime) Dim typeBlocks As ImmutableArray(Of MetadataBlock) = Nothing Dim methodBlocks As ImmutableArray(Of MetadataBlock) = Nothing Dim moduleId As ModuleId = Nothing Dim symReader As ISymUnmanagedReader = Nothing Dim typeToken = 0 Dim methodToken = 0 Dim localSignatureToken = 0 GetContextState(runtime, "C", typeBlocks, moduleId, symReader, typeToken, localSignatureToken) GetContextState(runtime, "C.M", methodBlocks, moduleId, symReader, methodToken, localSignatureToken) ' Compile expression with type context. Dim appDomain = New AppDomain() Dim context = CreateTypeContext( appDomain, typeBlocks, moduleId, typeToken, MakeAssemblyReferencesKind.AllAssemblies) ' If VB supported extern aliases, the following would be true: ' Assert.Equal(identityAS2, context.Compilation.GlobalNamespace.GetMembers("A").OfType(Of INamedTypeSymbol)().Single().ContainingAssembly.Identity) ' Assert.Equal(identityBS2, context.Compilation.GlobalNamespace.GetMembers("B").OfType(Of INamedTypeSymbol)().Single().ContainingAssembly.Identity) Dim errorMessage As String = Nothing ' A is ambiguous since there were no explicit references to AS1 or AS2. context.CompileExpression("New A()", errorMessage) Assert.Equal(errorMessage, "error BC30554: 'A' is ambiguous.") ' Ideally, B should be resolved to BS1. context.CompileExpression("New B()", errorMessage) Assert.Equal(errorMessage, "error BC30554: 'B' is ambiguous.") ' Compile expression with method context. appDomain.SetMetadataContext( SetMetadataContext( New MetadataContext(Of VisualBasicMetadataContext)(typeBlocks, ImmutableDictionary(Of MetadataContextId, VisualBasicMetadataContext).Empty), New VisualBasicMetadataContext(context.Compilation))) Dim previous = appDomain.GetMetadataContext() context = CreateMethodContext( appDomain, methodBlocks, MakeDummyLazyAssemblyReaders(), symReader, moduleId, methodToken, methodVersion:=1, ilOffset:=0, localSignatureToken:=localSignatureToken, kind:=MakeAssemblyReferencesKind.AllAssemblies) Assert.NotSame(GetMetadataContext(previous).EvaluationContext, context) Assert.Same(GetMetadataContext(previous).Compilation, context.Compilation) ' re-use type context compilation ' Ideally, B should be resolved to BS1. context.CompileExpression("New B()", errorMessage) Assert.Equal(errorMessage, "error BC30554: 'B' is ambiguous.") End Sub) End Sub Private Shared Function Compile(assemblyName As String, source As String, ParamArray references As MetadataReference()) As (Identity As AssemblyIdentity, [Module] As ModuleInstance, Reference As MetadataReference) Dim comp = CreateCompilationWithMscorlib40(source, references, options:=TestOptions.DebugDll, assemblyName:=assemblyName) comp.AssertNoDiagnostics() Dim [module] = comp.ToModuleInstance() Return (comp.Assembly.Identity, [module], [module].GetReference()) End Function Private Shared Sub VerifyResolutionRequests(context As EvaluationContext, ParamArray expectedResults As (AssemblyIdentity, AssemblyIdentity, Integer)()) ExpressionCompilerTestHelpers.VerifyResolutionRequests( DirectCast(context.Compilation.Options.MetadataReferenceResolver, EEMetadataReferenceResolver), expectedResults) End Sub <Fact> Public Sub DuplicateTypesAndMethodsDifferentAssemblies() Const sourceA = "Option Strict On Imports System.Runtime.CompilerServices Imports N Namespace N Class C1 End Class Public Module E <Extension> Public Function F(o As A) As A Return o End Function End Module End Namespace Class C2 End Class Public Class A Public Shared Sub M() Dim x As New A() Dim y As Object = x.F() End Sub End Class" Const sourceB = "Option Strict On Imports System.Runtime.CompilerServices Imports N Namespace N Class C1 End Class Public Module E <Extension> Public Function F(o As A) As Integer Return 2 End Function End Module End Namespace Class C2 End Class Class B Shared Sub Main() Dim x As New A() End Sub End Class" Dim compilationA = CreateEmptyCompilationWithReferences( MakeSources(sourceA), options:=TestOptions.DebugDll, references:={MscorlibRef, SystemRef, MsvbRef, SystemCoreRef}) Dim moduleA = compilationA.ToModuleInstance() Dim identityA = compilationA.Assembly.Identity Dim moduleB = CreateEmptyCompilationWithReferences( MakeSources(sourceB), options:=TestOptions.DebugDll, references:={MscorlibRef, SystemRef, MsvbRef, SystemCoreRef, moduleA.GetReference()}).ToModuleInstance() Dim runtime = CreateRuntimeInstance( { MscorlibRef.ToModuleInstance(), SystemRef.ToModuleInstance(), MsvbRef.ToModuleInstance(), SystemCoreRef.ToModuleInstance(), moduleA, moduleB }) Dim blocks As ImmutableArray(Of MetadataBlock) = Nothing Dim moduleId As ModuleId = Nothing Dim symReader As ISymUnmanagedReader = Nothing Dim typeToken = 0 Dim methodToken = 0 Dim localSignatureToken = 0 GetContextState(runtime, "B", blocks, moduleId, symReader, typeToken, localSignatureToken) Dim contextFactory = CreateTypeContextFactory(moduleId, typeToken) ' Duplicate type in namespace, at type scope. Dim testData As CompilationTestData = Nothing Dim errorMessage As String = Nothing ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "New N.C1()", ImmutableArray(Of [Alias]).Empty, contextFactory, getMetaDataBytesPtr:=Nothing, errorMessage:=errorMessage, testData:=testData) Assert.Equal($"error BC30560: { String.Format(VBResources.ERR_AmbiguousInNamespace2, "C1", "N") }", errorMessage) GetContextState(runtime, "B.Main", blocks, moduleId, symReader, methodToken, localSignatureToken) contextFactory = CreateMethodContextFactory(moduleId, symReader, methodToken, localSignatureToken) ' Duplicate type in namespace, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "New C1()", ImmutableArray(Of [Alias]).Empty, contextFactory, getMetaDataBytesPtr:=Nothing, errorMessage:=errorMessage, testData:=testData) Assert.Equal($"error BC30560: { String.Format(VBResources.ERR_AmbiguousInNamespace2, "C1", "N") }", errorMessage) ' Duplicate type in global namespace, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "New C2()", ImmutableArray(Of [Alias]).Empty, contextFactory, getMetaDataBytesPtr:=Nothing, errorMessage:=errorMessage, testData:=testData) Assert.Equal($"error BC30554: { String.Format(VBResources.ERR_AmbiguousInUnnamedNamespace1, "C2") }", errorMessage) ' Duplicate extension method, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "x.F()", ImmutableArray(Of [Alias]).Empty, contextFactory, getMetaDataBytesPtr:=Nothing, errorMessage:=errorMessage, testData:=testData) Assert.True(errorMessage.StartsWith($"error BC30521: { String.Format(VBResources.ERR_NoMostSpecificOverload2, "F", "") }")) ' Same tests as above but in library that does not directly reference duplicates. GetContextState(runtime, "A", blocks, moduleId, symReader, typeToken, localSignatureToken) contextFactory = CreateTypeContextFactory(moduleId, typeToken) ' Duplicate type in namespace, at type scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "New N.C1()", ImmutableArray(Of [Alias]).Empty, contextFactory, getMetaDataBytesPtr:=Nothing, errorMessage:=errorMessage, testData:=testData) Assert.Null(errorMessage) Dim methodData = testData.GetMethodData("<>x.<>m0") methodData.VerifyIL( "{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""Sub N.C1..ctor()"" IL_0005: ret }") Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName()) GetContextState(runtime, "A.M", blocks, moduleId, symReader, methodToken, localSignatureToken) contextFactory = CreateMethodContextFactory(moduleId, symReader, methodToken, localSignatureToken) ' Duplicate type in global namespace, at method scope. ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "New C2()", ImmutableArray(Of [Alias]).Empty, contextFactory, getMetaDataBytesPtr:=Nothing, errorMessage:=errorMessage, testData:=testData) Assert.Null(errorMessage) methodData = testData.GetMethodData("<>x.<>m0") methodData.VerifyIL( "{ // Code size 6 (0x6) .maxstack 1 .locals init (A V_0, //x Object V_1) //y IL_0000: newobj ""Sub 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(Of [Alias]).Empty, contextFactory, getMetaDataBytesPtr:=Nothing, errorMessage:=errorMessage, testData:=testData) Assert.Null(errorMessage) methodData = testData.GetMethodData("<>x.<>m0") methodData.VerifyIL( "{ // Code size 7 (0x7) .maxstack 1 .locals init (A V_0, //x Object V_1) //y IL_0000: ldloc.0 IL_0001: call ""Function N.E.F(A) As A"" IL_0006: ret }") Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName()) End Sub <Fact> Public Sub DuplicateTypesAndMethodsDifferentAssemblies_2() Const sourceA = "Namespace N Public Module M Public Function F() Return 1 End Function End Module End Namespace" Const sourceB = "Imports N Class C Shared Sub M() F() End Sub End Class" Dim referenceA1 = CreateEmptyCompilation( New AssemblyIdentity("A", New Version(1, 1, 1, 1)), {sourceA}, options:=TestOptions.DebugDll, references:={MscorlibRef, SystemRef, MsvbRef}).EmitToImageReference() Dim referenceA2 = CreateEmptyCompilation( New AssemblyIdentity("A", New Version(2, 1, 1, 2)), {sourceA}, options:=TestOptions.DebugDll, references:={MscorlibRef, SystemRef, MsvbRef}).EmitToImageReference() Dim compilationB = CreateEmptyCompilation( New AssemblyIdentity("B", New Version(1, 1, 1, 1)), {sourceB}, options:=TestOptions.DebugDll, references:={MscorlibRef, referenceA1}) WithRuntimeInstance(compilationB, {MscorlibRef, SystemRef, MsvbRef, referenceA1, referenceA2}, Sub(runtime) Dim blocks As ImmutableArray(Of MetadataBlock) = Nothing Dim moduleId As ModuleId = Nothing Dim symReader As ISymUnmanagedReader = Nothing Dim typeToken = 0 Dim methodToken = 0 Dim localSignatureToken = 0 GetContextState(runtime, "C.M", blocks, moduleId, symReader, methodToken, localSignatureToken) Dim context = CreateMethodContext( New AppDomain(), blocks, MakeDummyLazyAssemblyReaders(), symReader, moduleId, methodToken, methodVersion:=1, ilOffset:=0, localSignatureToken:=localSignatureToken, kind:=MakeAssemblyReferencesKind.AllAssemblies) Dim errorMessage As String = Nothing context.CompileExpression("F()", errorMessage) Assert.Equal(errorMessage, "error BC30562: 'F' is ambiguous between declarations in Modules 'N.M, N.M'.") Dim testData As New CompilationTestData() Dim contextFactory = CreateMethodContextFactory(moduleId, symReader, methodToken, localSignatureToken) ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "F()", ImmutableArray(Of [Alias]).Empty, contextFactory, getMetaDataBytesPtr:=Nothing, errorMessage:=errorMessage, testData:=testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 6 (0x6) .maxstack 1 IL_0000: call ""Function N.M.F() As Object"" IL_0005: ret }") End Sub) End Sub <Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1170032")> Public Sub DuplicateTypesInMscorlib() Const sourceConsole = "Namespace System Public Class Console End Class End Namespace" Const sourceObjectModel = "Namespace System.Collections.ObjectModel Public Class ReadOnlyDictionary(Of K, V) End Class End Namespace" Const source = "Class C Shared Sub Main() Dim t = GetType(System.Console) Dim o = DirectCast(Nothing, System.Collections.ObjectModel.ReadOnlyDictionary(Of Object, Object)) End Sub End Class" Dim systemConsoleComp = CreateCompilationWithMscorlib40({sourceConsole}, options:=TestOptions.DebugDll, assemblyName:="System.Console") Dim systemConsoleRef = systemConsoleComp.EmitToImageReference() Dim systemObjectModelComp = CreateCompilationWithMscorlib40({sourceObjectModel}, options:=TestOptions.DebugDll, assemblyName:="System.ObjectModel") Dim systemObjectModelRef = systemObjectModelComp.EmitToImageReference() Dim 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 }. Dim contractReferences = ImmutableArray.Create(systemConsoleRef, SystemRuntimePP7Ref, systemObjectModelRef) Dim runtimeReferences = ImmutableArray.Create(systemConsoleRef, MscorlibFacadeRef, SystemRuntimeFacadeRef, systemObjectModelRef) ' Verify the compiler reports duplicate types with facade assemblies. Dim compilation = CreateEmptyCompilationWithReferences(MakeSources(source), references:=runtimeReferences, options:=TestOptions.DebugDll) compilation.VerifyDiagnostics( Diagnostic(ERRID.ERR_AmbiguousInNamespace2, "System.Console").WithArguments("Console", "System").WithLocation(3, 25), Diagnostic(ERRID.ERR_AmbiguousInNamespace2, "System.Collections.ObjectModel.ReadOnlyDictionary(Of Object, Object)").WithArguments("ReadOnlyDictionary", "System.Collections.ObjectModel").WithLocation(4, 37)) ' 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 = CreateEmptyCompilationWithReferences(MakeSources(source), references:=contractReferences, options:=TestOptions.DebugDll) WithRuntimeInstance(compilation, runtimeReferences, Sub(runtime) Dim context = CreateMethodContext(runtime, "C.Main") Dim errorMessage As String = Nothing ' { System.Console, mscorlib } Dim testData = New CompilationTestData() context.CompileExpression("GetType(System.Console)", errorMessage, testData) Dim methodData = testData.GetMethodData("<>x.<>m0") methodData.VerifyIL( "{ // Code size 11 (0xb) .maxstack 1 .locals init (System.Type V_0, //t System.Collections.ObjectModel.ReadOnlyDictionary(Of Object, Object) V_1) //o IL_0000: ldtoken ""System.Console"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ret }") ' { mscorlib, System.ObjectModel } testData = New CompilationTestData() context.CompileExpression("DirectCast(Nothing, System.Collections.ObjectModel.ReadOnlyDictionary(Of Object, Object))", 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(Of Object, Object) V_1) //o IL_0000: ldnull IL_0001: ret }") Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityObjectModel.GetDisplayName()) End Sub) End Sub Private Const 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/13275")> Public Sub CorLibWithAssemblyReferences() Const sourceLib = "Public Class Private1 End Class Public Class Private2 End Class" Dim compLib = CreateCompilationWithMscorlib40( {sourceLib}, options:=TestOptions.ReleaseDll, assemblyName:="System.Private.Library") compLib.VerifyDiagnostics() Dim refLib = compLib.EmitToImageReference() Const sourceCorLib = "Imports System.Runtime.CompilerServices <Assembly: TypeForwardedTo(GetType(Private2))> Namespace System Public Class [Object] Public Function F() As Private1 Return Nothing End Function End Class Public Class Void Inherits [Object] End Class End Namespace" ' Create a custom corlib with a reference to compilation ' above and a reference to the actual mscorlib. Dim compCorLib = CreateEmptyCompilation( {Parse(sourceCorLib)}, options:=TestOptions.ReleaseDll, references:={MscorlibRef, refLib}, assemblyName:=CorLibAssemblyName) compCorLib.VerifyDiagnostics() Dim objectType = compCorLib.SourceAssembly.GlobalNamespace.GetMember(Of NamedTypeSymbol)("System.Object") Assert.NotNull(objectType.BaseType) Dim peBytes As ImmutableArray(Of Byte) = Nothing Dim pdbBytes As ImmutableArray(Of Byte) = Nothing ExpressionCompilerTestHelpers.EmitCorLibWithAssemblyReferences( compCorLib, Nothing, Function(moduleBuilder, emitOptions) New PEAssemblyBuilderWithAdditionalReferences(moduleBuilder, emitOptions, objectType.GetCciAdapter()), peBytes, pdbBytes) Using reader As New PEReader(peBytes) Dim metadata = reader.GetMetadata() Dim [module] = metadata.ToModuleMetadata(ignoreAssemblyRefs:=True) Dim metadataReader = metadata.ToMetadataReader() Dim moduleInstance = Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests.ModuleInstance.Create(metadata, New ModuleId(metadataReader.GetModuleVersionIdOrThrow(), [module].Name)) ' 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. Dim actualReferences = metadataReader.AssemblyReferences.Select(Function(r) metadataReader.GetString(metadataReader.GetAssemblyReference(r).Name)).ToImmutableArray() AssertEx.Equal({"mscorlib", "System.Private.Library"}, actualReferences) Const source = "Class C Shared Sub M() End Sub End Class" Dim comp = CreateEmptyCompilation( {Parse(source)}, options:=TestOptions.ReleaseDll, references:={refLib, AssemblyMetadata.Create([module]).GetReference()}) comp.VerifyDiagnostics() Using runtime = RuntimeInstance.Create({comp.ToModuleInstance(), moduleInstance}) Dim errorMessage As String = Nothing Dim context = CreateMethodContext(runtime, "C.M") ' Valid expression. Dim testData = New CompilationTestData() context.CompileExpression("New Object()", errorMessage, testData) Assert.Null(errorMessage) Dim methodData = testData.GetMethodData("<>x.<>m0") methodData.VerifyIL( "{ // Code size 6 (0x6) .maxstack 1 IL_0000: newobj ""Sub Object..ctor()"" IL_0005: ret }") ' Invalid expression: System.Int32 is not defined in corlib above. testData = New CompilationTestData() context.CompileExpression("1", errorMessage, testData) Assert.Equal("error BC30002: Type 'System.Int32' is not defined.", errorMessage) ' Invalid expression: type in method signature from missing referenced assembly. testData = New CompilationTestData() context.CompileExpression("(New Object()).F()", errorMessage, testData) Assert.Equal("error BC30657: 'F' has a return type that is not supported or parameter types that are not supported.", errorMessage) ' Invalid expression: type forwarded to missing referenced assembly. testData = New CompilationTestData() context.CompileExpression("New Private2()", errorMessage, testData) Assert.Equal("error BC30002: Type 'Private2' is not defined.", errorMessage) End Using End Using End Sub Private Shared Function CreateTypeContextFactory( moduleId As ModuleId, typeToken As Integer) As ExpressionCompiler.CreateContextDelegate Return Function(blocks, useReferencedModulesOnly) Dim compilation = If(useReferencedModulesOnly, blocks.ToCompilationReferencedModulesOnly(moduleId), blocks.ToCompilation()) Return EvaluationContext.CreateTypeContext( compilation, moduleId, typeToken) End Function End Function Private Shared Function CreateMethodContextFactory( moduleId As ModuleId, symReader As ISymUnmanagedReader, methodToken As Integer, localSignatureToken As Integer) As ExpressionCompiler.CreateContextDelegate Return Function(blocks, useReferencedModulesOnly) Dim compilation = If(useReferencedModulesOnly, blocks.ToCompilationReferencedModulesOnly(moduleId), blocks.ToCompilation()) Return EvaluationContext.CreateMethodContext( compilation, MakeDummyLazyAssemblyReaders(), symReader, moduleId, methodToken, methodVersion:=1, ilOffset:=0, localSignatureToken:=localSignatureToken) End Function End Function Private NotInheritable Class PEAssemblyBuilderWithAdditionalReferences Inherits PEModuleBuilder Implements IAssemblyReference Private ReadOnly _builder As CommonPEModuleBuilder Private ReadOnly _objectType As NamespaceTypeDefinitionNoBase Friend Sub New(builder As CommonPEModuleBuilder, emitOptions As EmitOptions, objectType As INamespaceTypeDefinition) MyBase.New(DirectCast(builder.CommonSourceModule, SourceModuleSymbol), emitOptions, builder.OutputKind, builder.SerializationProperties, builder.ManifestResources) _builder = builder _objectType = New NamespaceTypeDefinitionNoBase(objectType) End Sub Public Overrides Iterator Function GetTopLevelSourceTypeDefinitions(context As EmitContext) As IEnumerable(Of INamespaceTypeDefinition) For Each t In MyBase.GetTopLevelSourceTypeDefinitions(context) Yield If(t Is _objectType.UnderlyingType, _objectType, t) Next End Function Public Overrides ReadOnly Property EncSymbolChanges As SymbolChanges Get Return _builder.EncSymbolChanges End Get End Property Public Overrides ReadOnly Property PreviousGeneration As EmitBaseline Get Return _builder.PreviousGeneration End Get End Property Public Overrides ReadOnly Property FieldRvaSupported As Boolean Get Return _builder.FieldRvaSupported End Get End Property Public Overrides ReadOnly Property MethodImplSupported As Boolean Get Return _builder.MethodImplSupported End Get End Property Public Overrides ReadOnly Property SourceAssemblyOpt As ISourceAssemblySymbolInternal Get Return _builder.SourceAssemblyOpt End Get End Property Public Overrides Function GetFiles(context As EmitContext) As IEnumerable(Of IFileReference) Return _builder.GetFiles(context) End Function Protected Overrides Sub AddEmbeddedResourcesFromAddedModules(builder As ArrayBuilder(Of Cci.ManagedResource), diagnostics As DiagnosticBag) End Sub Public Overrides Function GetOrCreateHotReloadExceptionConstructorDefinition() As IMethodSymbolInternal Throw New NotImplementedException() End Function Public Overrides Function TryGetOrCreateSynthesizedHotReloadExceptionType() As INamedTypeSymbolInternal Return Nothing End Function Public Overrides Function GetUsedSynthesizedHotReloadExceptionType() As INamedTypeSymbolInternal Return Nothing End Function Friend Overrides ReadOnly Property AllowOmissionOfConditionalCalls As Boolean Get Return True End Get End Property Private ReadOnly Property Identity As AssemblyIdentity Implements IAssemblyReference.Identity Get Return DirectCast(_builder, IAssemblyReference).Identity End Get End Property Private ReadOnly Property AssemblyVersionPattern As Version Implements IAssemblyReference.AssemblyVersionPattern Get Return DirectCast(_builder, IAssemblyReference).AssemblyVersionPattern End Get End Property End Class End Class End Namespace