' 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 Microsoft.CodeAnalysis.CodeGen Imports Microsoft.CodeAnalysis.ExpressionEvaluator Imports Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE Imports Microsoft.CodeAnalysis.VisualBasic.UnitTests Imports Microsoft.VisualStudio.Debugger.Evaluation Imports Roslyn.Test.Utilities Imports Xunit Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator.UnitTests Public Class WinMdTests Inherits ExpressionCompilerTestBase ''' ''' Handle runtime assemblies rather than Windows.winmd ''' (compile-time assembly) since those are the assemblies ''' loaded in the debuggee. ''' Public Sub Win8RuntimeAssemblies() Const source = "Class C Shared Sub M(f As Windows.Storage.StorageFolder, p As Windows.Foundation.Collections.PropertySet) End Sub End Class" Dim comp = CreateEmptyCompilation({source}, options:=TestOptions.DebugDll, references:=WinRtRefs) Dim runtimeAssemblies = ExpressionCompilerTestHelpers.GetRuntimeWinMds("Windows.Storage", "Windows.Foundation.Collections") Assert.True(runtimeAssemblies.Length >= 2) ' no reference to Windows.winmd WithRuntimeInstance(comp, {MscorlibRef}.Concat(runtimeAssemblies), Sub(runtime) Dim context = CreateMethodContext(runtime, "C.M") Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileExpression("If(p Is Nothing, f, Nothing)", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.1 IL_0001: brfalse.s IL_0005 IL_0003: ldnull IL_0004: ret IL_0005: ldarg.0 IL_0006: ret }") End Sub) End Sub Public Sub Win8OnWin8() CompileTimeAndRuntimeAssemblies( ImmutableArray.Create( MscorlibRef, AssemblyMetadata.CreateFromImage(ToVersion1_3(TestResources.ExpressionCompiler.Windows)).GetReference(), AssemblyMetadata.CreateFromImage(ToVersion1_3(TestResources.ExpressionCompiler.LibraryA)).GetReference(), AssemblyMetadata.CreateFromImage(TestResources.ExpressionCompiler.LibraryB).GetReference()), ImmutableArray.Create( MscorlibRef, AssemblyMetadata.CreateFromImage(ToVersion1_3(TestResources.ExpressionCompiler.WindowsData)).GetReference(), AssemblyMetadata.CreateFromImage(ToVersion1_3(TestResources.ExpressionCompiler.WindowsStorage)).GetReference(), AssemblyMetadata.CreateFromImage(ToVersion1_3(TestResources.ExpressionCompiler.LibraryA)).GetReference(), AssemblyMetadata.CreateFromImage(TestResources.ExpressionCompiler.LibraryB).GetReference()), "Windows.Storage") End Sub Public Sub Win8OnWin10() CompileTimeAndRuntimeAssemblies( ImmutableArray.Create( MscorlibRef, AssemblyMetadata.CreateFromImage(ToVersion1_3(TestResources.ExpressionCompiler.Windows)).GetReference(), AssemblyMetadata.CreateFromImage(ToVersion1_3(TestResources.ExpressionCompiler.LibraryA)).GetReference(), AssemblyMetadata.CreateFromImage(TestResources.ExpressionCompiler.LibraryB).GetReference()), ImmutableArray.Create( MscorlibRef, AssemblyMetadata.CreateFromImage(ToVersion1_4(TestResources.ExpressionCompiler.WindowsData)).GetReference(), AssemblyMetadata.CreateFromImage(ToVersion1_4(TestResources.ExpressionCompiler.WindowsStorage)).GetReference(), AssemblyMetadata.CreateFromImage(ToVersion1_3(TestResources.ExpressionCompiler.LibraryA)).GetReference(), AssemblyMetadata.CreateFromImage(TestResources.ExpressionCompiler.LibraryB).GetReference()), "Windows.Storage") End Sub Public Sub Win10OnWin10() CompileTimeAndRuntimeAssemblies( ImmutableArray.Create( MscorlibRef, AssemblyMetadata.CreateFromImage(ToVersion1_4(TestResources.ExpressionCompiler.WindowsData)).GetReference(), AssemblyMetadata.CreateFromImage(ToVersion1_4(TestResources.ExpressionCompiler.WindowsStorage)).GetReference(), AssemblyMetadata.CreateFromImage(ToVersion1_4(TestResources.ExpressionCompiler.LibraryA)).GetReference(), AssemblyMetadata.CreateFromImage(TestResources.ExpressionCompiler.LibraryB).GetReference()), ImmutableArray.Create( MscorlibRef, AssemblyMetadata.CreateFromImage(ToVersion1_4(TestResources.ExpressionCompiler.Windows)).GetReference(), AssemblyMetadata.CreateFromImage(ToVersion1_4(TestResources.ExpressionCompiler.LibraryA)).GetReference(), AssemblyMetadata.CreateFromImage(TestResources.ExpressionCompiler.LibraryB).GetReference()), "Windows") End Sub Private Sub CompileTimeAndRuntimeAssemblies( compileReferences As ImmutableArray(Of MetadataReference), runtimeReferences As ImmutableArray(Of MetadataReference), storageAssemblyName As String) Const source = "Class C Shared Sub M(a As LibraryA.A, b As LibraryB.B, t As Windows.Data.Text.TextSegment, f As Windows.Storage.StorageFolder) End Sub End Class" Dim c0 = CreateEmptyCompilation({source}, compileReferences, TestOptions.DebugDll) WithRuntimeInstance(c0, runtimeReferences, Sub(runtime) Dim context = CreateMethodContext(runtime, "C.M") Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileExpression("If(a, If(b, If(t, f)))", errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 17 (0x11) .maxstack 2 IL_0000: ldarg.0 IL_0001: dup IL_0002: brtrue.s IL_0010 IL_0004: pop IL_0005: ldarg.1 IL_0006: dup IL_0007: brtrue.s IL_0010 IL_0009: pop IL_000a: ldarg.2 IL_000b: dup IL_000c: brtrue.s IL_0010 IL_000e: pop IL_000f: ldarg.3 IL_0010: ret }") testData = New CompilationTestData() Dim result = context.CompileExpression("f", errorMessage, testData) Assert.Null(errorMessage) Dim methodData = testData.GetMethodData("<>x.<>m0") methodData.VerifyIL( "{ // Code size 2 (0x2) .maxstack 1 IL_0000: ldarg.3 IL_0001: ret }") ' Check return type is from runtime assembly. Dim assemblyReference = AssemblyMetadata.CreateFromImage(result.Assembly).GetReference() Dim comp = VisualBasicCompilation.Create( assemblyName:=ExpressionCompilerUtilities.GenerateUniqueName(), references:=runtimeReferences.Concat(ImmutableArray.Create(Of MetadataReference)(assemblyReference))) Using metadata = ModuleMetadata.CreateFromImage(result.Assembly) Dim reader = metadata.MetadataReader Dim typeDef = reader.GetTypeDef("<>x") Dim methodHandle = reader.GetMethodDefHandle(typeDef, "<>m0") Dim [module] = DirectCast(comp.GetMember("<>x").ContainingModule, PEModuleSymbol) Dim metadataDecoder = New MetadataDecoder([module]) Dim signatureHeader As SignatureHeader = Nothing Dim metadataException As BadImageFormatException = Nothing Dim parameters = metadataDecoder.GetSignatureForMethod(methodHandle, signatureHeader, metadataException) Assert.Equal(parameters.Length, 5) Dim actualReturnType = parameters(0).Type Assert.Equal(actualReturnType.TypeKind, TypeKind.Class) ' not error Dim expectedReturnType = comp.GetMember("Windows.Storage.StorageFolder") Assert.Equal(expectedReturnType, actualReturnType) Assert.Equal(storageAssemblyName, actualReturnType.ContainingAssembly.Name) End Using End Sub) End Sub ''' ''' Assembly-qualified name containing "ContentType=WindowsRuntime", ''' and referencing runtime assembly. ''' Public Sub AssemblyQualifiedName() Const source = "Class C Shared Sub M(f As Windows.Storage.StorageFolder, p As Windows.Foundation.Collections.PropertySet) End Sub End Class" Dim comp = CreateEmptyCompilation({source}, WinRtRefs, TestOptions.DebugDll) Dim runtimeAssemblies = ExpressionCompilerTestHelpers.GetRuntimeWinMds("Windows.Storage", "Windows.Foundation.Collections") WithRuntimeInstance(comp, {MscorlibRef}.Concat(runtimeAssemblies), Sub(runtime) Dim context = CreateMethodContext(runtime, "C.M") Dim aliases = ImmutableArray.Create( VariableAlias("s", "Windows.Storage.StorageFolder, Windows.Storage, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime"), VariableAlias("d", "Windows.Foundation.DateTime, Windows.Foundation, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime")) Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileExpression( "If(DirectCast(s.Attributes, Object), d.UniversalTime)", DkmEvaluationFlags.TreatAsExpression, aliases, errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 55 (0x37) .maxstack 2 IL_0000: ldstr ""s"" IL_0005: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" IL_000a: castclass ""Windows.Storage.StorageFolder"" IL_000f: callvirt ""Function Windows.Storage.StorageFolder.get_Attributes() As Windows.Storage.FileAttributes"" IL_0014: box ""Windows.Storage.FileAttributes"" IL_0019: dup IL_001a: brtrue.s IL_0036 IL_001c: pop IL_001d: ldstr ""d"" IL_0022: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" IL_0027: unbox.any ""Windows.Foundation.DateTime"" IL_002c: ldfld ""Windows.Foundation.DateTime.UniversalTime As Long"" IL_0031: box ""Long"" IL_0036: ret }") End Sub) End Sub Private Shared Function ToVersion1_3(bytes As Byte()) As Byte() Return ExpressionCompilerTestHelpers.ToVersion1_3(bytes) End Function Private Shared Function ToVersion1_4(bytes As Byte()) As Byte() Return ExpressionCompilerTestHelpers.ToVersion1_4(bytes) End Function End Class End Namespace