' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. Imports System.Collections.Immutable Imports System.Globalization Imports System.Reflection.Metadata Imports System.Threading Imports Microsoft.CodeAnalysis.CodeGen Imports Microsoft.CodeAnalysis.ExpressionEvaluator Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.VisualStudio.Debugger.Evaluation Imports Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation Imports Microsoft.DiaSymReader Imports Roslyn.Test.Utilities Imports Xunit Imports CommonResources = Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests.Resources Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests Public Class ExpressionCompilerTests Inherits ExpressionCompilerTestBase Const SimpleSource = " Class C Shared Sub M() End Sub End Class " ''' ''' Each assembly should have a unique MVID and assembly name. ''' Public Sub UniqueModuleVersionId() Dim comp = CreateCompilationWithMscorlib({SimpleSource}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "C.M") Dim errorMessage As String = Nothing Dim result = context.CompileExpression("1", errorMessage) Dim mvid1 = result.Assembly.GetModuleVersionId() Dim name1 = result.Assembly.GetAssemblyName() Assert.NotEqual(mvid1, Guid.Empty) context = CreateMethodContext(runtime, "C.M", previous:=New VisualBasicMetadataContext(context)) result = context.CompileExpression("2", errorMessage) Dim mvid2 = result.Assembly.GetModuleVersionId() Dim name2 = result.Assembly.GetAssemblyName() Assert.NotEqual(mvid2, Guid.Empty) Assert.NotEqual(mvid2, mvid1) Assert.NotEqual(name2.FullName, name1.FullName) End Sub Public Sub ParseError() Dim comp = CreateCompilationWithMscorlib({SimpleSource}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "C.M") Dim errorMessage As String = Nothing Dim result = context.CompileExpression("M(", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) Assert.Null(result.Assembly) Assert.Equal("(1) : error BC30201: Expression expected.", errorMessage) End Sub ''' ''' Diagnostics should be formatted with the CurrentUICulture. ''' Public Sub FormatterCultureInfo() Dim previousCulture = Thread.CurrentThread.CurrentCulture Dim previousUICulture = Thread.CurrentThread.CurrentUICulture Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("fr-FR") Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("de-DE") Try Dim comp = CreateCompilationWithMscorlib({SimpleSource}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext( runtime, "C.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim missingAssemblyIdentities As ImmutableArray(Of AssemblyIdentity) = Nothing Dim result = context.CompileExpression( DefaultInspectionContext.Instance, "M(", DkmEvaluationFlags.TreatAsExpression, CustomDiagnosticFormatter.Instance, resultProperties, errorMessage, missingAssemblyIdentities, preferredUICulture:=Nothing, testData:=Nothing) Assert.Empty(missingAssemblyIdentities) Assert.Null(result.Assembly) Assert.Equal("LCID=1031, Code=30201", errorMessage) Finally Thread.CurrentThread.CurrentUICulture = previousUICulture Thread.CurrentThread.CurrentCulture = previousCulture End Try End Sub Public Sub BindingError() Const source = " Class C Shared Sub M(o As Object) Dim a As Object() = {} For Each x In a M(x) Next For Each y In a #ExternalSource(""test"", 999) M(y) #End ExternalSource Next End Sub End Class " Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", atLineNumber:=999, expr:="If(y, x)", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Equal("(1) : error BC30451: 'x' is not declared. It may be inaccessible due to its protection level.", errorMessage) End Sub Public Sub EmitError() Const source = " Class C Shared Sub M(o As Object) End Sub End Class " Dim longName = New String("P"c, 1100) Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:=String.Format("New With {{ .{0} = o }}", longName), resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Equal(String.Format("error BC37220: Name '${0}' exceeds the maximum length allowed in metadata.", longName), errorMessage) End Sub Public Sub NoSymbols() Const source = " Class C Shared Function F(o As Object) As Object Return o End Function Shared Sub M(x As Integer) Dim y = x + 1 End Sub End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp, includeSymbols:=False) For Each moduleInstance In runtime.Modules Assert.Null(moduleInstance.SymReader) Next Dim context = CreateMethodContext( runtime, methodName:="C.M") ' Local reference. Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() Dim result = context.CompileExpression("F(y)", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) Assert.Equal("(1) : error BC30451: 'y' is not declared. It may be inaccessible due to its protection level.", errorMessage) ' No local reference. testData = New CompilationTestData() result = context.CompileExpression("F(x)", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) ' Unlike C#, VB doesn't create a temp local to store the return value. testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 12 (0xc) .maxstack 1 .locals init (Integer V_0) IL_0000: ldarg.0 IL_0001: box ""Integer"" IL_0006: call ""Function C.F(Object) As Object"" IL_000b: ret }") End Sub ''' ''' Reuse Compilation if references match, and reuse entire ''' EvaluationContext if references and local scopes match. ''' Public Sub ReuseEvaluationContext() Const sourceA = "Public Interface I End Interface" Const sourceB = "Class C Shared Sub F(o As I) Dim x As Object = 1 If o Is Nothing Then Dim y As Object = 2 y = x Else Dim z As Object End If x = 3 End Sub Shared Sub G() End Sub End Class" Dim compA = CreateCompilationWithMscorlib({sourceA}, compOptions:=TestOptions.DebugDll) Dim referenceA = compA.EmitToImageReference() Dim compB = CreateCompilationWithMscorlib({sourceB}, compOptions:=TestOptions.DebugDll, references:={referenceA}) Dim exeBytes As Byte() = Nothing Dim pdbBytes As Byte() = Nothing Dim references As ImmutableArray(Of MetadataReference) = Nothing compB.EmitAndGetReferences(exeBytes, pdbBytes, references) Const methodVersion = 1 Dim previous As VisualBasicMetadataContext = Nothing Dim startOffset = 0 Dim endOffset = 0 Dim runtime = CreateRuntimeInstance(ExpressionCompilerUtilities.GenerateUniqueName(), references, exeBytes, New SymReader(pdbBytes)) Dim typeBlocks As ImmutableArray(Of MetadataBlock) = Nothing Dim methodBlocks As ImmutableArray(Of MetadataBlock) = Nothing Dim moduleVersionId As Guid = Nothing Dim symReader As ISymUnmanagedReader = Nothing Dim typeToken = 0 Dim methodToken = 0 Dim localSignatureToken = 0 GetContextState(runtime, "C", typeBlocks, moduleVersionId, symReader, typeToken, localSignatureToken) GetContextState(runtime, "C.F", methodBlocks, moduleVersionId, symReader, methodToken, localSignatureToken) ' Get non-empty scopes. Dim scopes = symReader.GetScopes(methodToken, methodVersion, EvaluationContext.IsLocalScopeEndInclusive).WhereAsArray(Function(s) s.Locals.Length > 0) Assert.True(scopes.Length >= 3) Dim outerScope = scopes.First(Function(s) s.Locals.Contains("x")) startOffset = outerScope.StartOffset endOffset = outerScope.EndOffset ' At start of outer scope. Dim context = EvaluationContext.CreateMethodContext(previous, methodBlocks, MakeDummyLazyAssemblyReaders(), symReader, moduleVersionId, methodToken, methodVersion, startOffset, localSignatureToken) Assert.Equal(Nothing, previous) previous = new VisualBasicMetadataContext(context) ' At end of outer scope - not reused because of the nested scope. context = EvaluationContext.CreateMethodContext(previous, methodBlocks, MakeDummyLazyAssemblyReaders(), symReader, moduleVersionId, methodToken, methodVersion, endOffset, localSignatureToken) Assert.NotEqual(context, previous.EvaluationContext) ' Not required, just documentary. ' At type context. context = EvaluationContext.CreateTypeContext(previous, methodBlocks, moduleVersionId, typeToken) Assert.NotEqual(context, previous.EvaluationContext) Assert.Null(context.MethodContextReuseConstraints) Assert.Equal(context.Compilation, previous.Compilation) ' Step through entire method. Dim previousScope As Scope = Nothing previous = new VisualBasicMetadataContext(context) For offset = startOffset To endOffset - 1 Dim scope = scopes.GetInnermostScope(offset) Dim constraints = previous.EvaluationContext.MethodContextReuseConstraints If constraints.HasValue Then Assert.Equal(scope Is previousScope, constraints.GetValueOrDefault().AreSatisfied(moduleVersionId, methodToken, methodVersion, offset)) End If context = EvaluationContext.CreateMethodContext(previous, methodBlocks, MakeDummyLazyAssemblyReaders(), symReader, moduleVersionId, methodToken, methodVersion, offset, localSignatureToken) If scope Is previousScope Then Assert.Equal(context, previous.EvaluationContext) Else ' Different scope. Should reuse compilation. Assert.NotEqual(context, previous.EvaluationContext) If previous.EvaluationContext IsNot Nothing Then Assert.NotEqual(context.MethodContextReuseConstraints, previous.EvaluationContext.MethodContextReuseConstraints) Assert.Equal(context.Compilation, previous.Compilation) End If End If previousScope = scope previous = new VisualBasicMetadataContext(context) Next ' With different references. Dim fewerReferences = references.Remove(referenceA) Assert.Equal(fewerReferences.Length, references.Length - 1) runtime = CreateRuntimeInstance(ExpressionCompilerUtilities.GenerateUniqueName(), fewerReferences, exeBytes, New SymReader(pdbBytes)) methodBlocks = Nothing moduleVersionId = Nothing symReader = Nothing methodToken = 0 localSignatureToken = 0 GetContextState(runtime, "C.F", methodBlocks, moduleVersionId, symReader, methodToken, localSignatureToken) ' Different references. No reuse. context = EvaluationContext.CreateMethodContext(previous, methodBlocks, MakeDummyLazyAssemblyReaders(), symReader, moduleVersionId, methodToken, methodVersion, endOffset - 1, localSignatureToken) Assert.NotEqual(context, previous.EvaluationContext) Assert.True(previous.EvaluationContext.MethodContextReuseConstraints.Value.AreSatisfied(moduleVersionId, methodToken, methodVersion, endOffset - 1)) Assert.NotEqual(context.Compilation, previous.Compilation) previous = new VisualBasicMetadataContext(context) ' Different method. Should reuse Compilation. GetContextState(runtime, "C.G", methodBlocks, moduleVersionId, symReader, methodToken, localSignatureToken) context = EvaluationContext.CreateMethodContext(previous, methodBlocks, MakeDummyLazyAssemblyReaders(), symReader, moduleVersionId, methodToken, methodVersion, ilOffset:=0, localSignatureToken:=localSignatureToken) Assert.NotEqual(context, previous.EvaluationContext) Assert.False(previous.EvaluationContext.MethodContextReuseConstraints.Value.AreSatisfied(moduleVersionId, methodToken, methodVersion, 0)) Assert.Equal(context.Compilation, previous.Compilation) ' No EvaluationContext. Should reuse Compilation previous = New VisualBasicMetadataContext(previous.MetadataBlocks) context = EvaluationContext.CreateMethodContext(previous, methodBlocks, MakeDummyLazyAssemblyReaders(), symReader, moduleVersionId, methodToken, methodVersion, ilOffset:=0, localSignatureToken:=localSignatureToken) Assert.Null(previous.EvaluationContext) Assert.NotNull(context) Assert.Equal(context.Compilation, previous.Compilation) End Sub Public Sub EvaluateLocal() Const source = " Class C Shared Sub M() Dim x As Integer = 1 Dim y As Integer = 2 End Sub End Class " Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="x") testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 2 (0x2) .maxstack 1 .locals init (Integer V_0, //x Integer V_1) //y IL_0000: ldloc.0 IL_0001: ret }") testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="y") testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 2 (0x2) .maxstack 1 .locals init (Integer V_0, //x Integer V_1) //y IL_0000: ldloc.1 IL_0001: ret }") End Sub Public Sub FormatSpecifiers() Const source = " Class C Shared Function F(x As String, y As String) As Object Return x End Function End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp, includeSymbols:=False) Dim context = CreateMethodContext(runtime, methodName:="C.F") Dim errorMessage As String = Nothing ' No format specifiers. Dim result = context.CompileExpression("x", errorMessage) CheckFormatSpecifiers(result) ' Format specifiers on expression. result = context.CompileExpression("x,", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) Assert.Equal("error BC37237: ',' is not a valid format specifier", errorMessage) result = context.CompileExpression("x,,", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) Assert.Equal("error BC37237: ',' is not a valid format specifier", errorMessage) result = context.CompileExpression("x y", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) Assert.Equal("error BC37237: 'y' is not a valid format specifier", errorMessage) result = context.CompileExpression("x yy zz", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) Assert.Equal("error BC37237: 'yy' is not a valid format specifier", errorMessage) result = context.CompileExpression("x,,y", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) Assert.Equal("error BC37237: ',' is not a valid format specifier", errorMessage) result = context.CompileExpression("x,yy,zz,ww", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) CheckFormatSpecifiers(result, "yy", "zz", "ww") result = context.CompileExpression("x, y z", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) Assert.Equal("error BC37237: 'z' is not a valid format specifier", errorMessage) result = context.CompileExpression("x, y , z ", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) CheckFormatSpecifiers(result, "y", "z") result = context.CompileExpression("x, y, z,", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) Assert.Equal("error BC37237: ',' is not a valid format specifier", errorMessage) result = context.CompileExpression("x,y,z;w", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) Assert.Equal("error BC37237: 'z;w' is not a valid format specifier", errorMessage) result = context.CompileExpression("x, y;, z", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) Assert.Equal("error BC37237: 'y;' is not a valid format specifier", errorMessage) ' Format specifiers after comment (ignored). result = context.CompileExpression("x ' ,f", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) CheckFormatSpecifiers(result) ' Format specifiers on assignment value. result = context.CompileAssignment("x", "Nothing, y", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) Assert.Null(result.Assembly) Assert.Null(result.FormatSpecifiers) Assert.Equal("(1) : error BC30035: Syntax error.", errorMessage) ' Format specifiers, no expression. result = context.CompileExpression(",f", errorMessage, Nothing, VisualBasicDiagnosticFormatter.Instance) Assert.Equal("(1) : error BC30201: Expression expected.", errorMessage) End Sub Private Shared Sub CheckFormatSpecifiers(result As CompileResult, ParamArray formatSpecifiers As String()) Assert.NotNull(result.Assembly) If formatSpecifiers.Length = 0 Then Assert.Null(result.FormatSpecifiers) Else AssertEx.Equal(formatSpecifiers, result.FormatSpecifiers) End If End Sub ''' ''' Locals in the generated method should account for temporary slots ''' in the original method. Also, some temporaries may not be included ''' in any scope. ''' Public Sub IncludeTemporarySlots() Const source = " Class C Shared Function F(a As Integer()) As String SyncLock New C() #ExternalSource(""test"", 999) Dim s As String = a(0).ToString() Return s #End ExternalSource End SyncLock End Function End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "C.F", atLineNumber:=999) Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileExpression("a(0)", resultProperties, errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 4 (0x4) .maxstack 2 .locals init (String V_0, //F Object V_1, Boolean V_2, String V_3, //s Boolean V_4) IL_0000: ldarg.0 IL_0001: ldc.i4.0 IL_0002: ldelem.i4 IL_0003: ret }") End Sub Public Sub EvaluateMe() Const source = " Class A Friend Overridable Function F() As String Return Nothing End Function Friend G As String Friend Overridable ReadOnly Property P As String Get Return Nothing End Get End Property End Class Class B Inherits A Friend Overrides Function F() As String Return Nothing End Function Friend Shadows G As String Friend Overrides ReadOnly Property P As String Get Return Nothing End Get End Property Overloads Shared Function F(f1 As System.Func(Of String)) As String Return Nothing End Function Sub M() End Sub End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "B.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() Dim result = context.CompileExpression("If(Me.F(), If(Me.G, Me.P))", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 27 (0x1b) .maxstack 2 IL_0000: ldarg.0 IL_0001: callvirt ""Function B.F() As String"" IL_0006: dup IL_0007: brtrue.s IL_001a IL_0009: pop IL_000a: ldarg.0 IL_000b: ldfld ""B.G As String"" IL_0010: dup IL_0011: brtrue.s IL_001a IL_0013: pop IL_0014: ldarg.0 IL_0015: callvirt ""Function B.get_P() As String"" IL_001a: ret } ") testData = New CompilationTestData() result = context.CompileExpression("F(AddressOf Me.F)", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 19 (0x13) .maxstack 2 IL_0000: ldarg.0 IL_0001: dup IL_0002: ldvirtftn ""Function B.F() As String"" IL_0008: newobj ""Sub System.Func(Of String)..ctor(Object, System.IntPtr)"" IL_000d: call ""Function B.F(System.Func(Of String)) As String"" IL_0012: ret } ") testData = New CompilationTestData() result = context.CompileExpression("F(new System.Func(Of String)(AddressOf Me.F))", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 19 (0x13) .maxstack 2 IL_0000: ldarg.0 IL_0001: dup IL_0002: ldvirtftn ""Function B.F() As String"" IL_0008: newobj ""Sub System.Func(Of String)..ctor(Object, System.IntPtr)"" IL_000d: call ""Function B.F(System.Func(Of String)) As String"" IL_0012: ret } ") End Sub Public Sub EvaluateMyClass() Const source = " Class A Friend Overridable Function F() As String Return Nothing End Function Friend G As String Friend Overridable ReadOnly Property P As String Get Return Nothing End Get End Property End Class Class B Inherits A Friend Overrides Function F() As String Return Nothing End Function Friend Shadows G As String Friend Overrides ReadOnly Property P As String Get Return Nothing End Get End Property Overloads Shared Function F(f1 As System.Func(Of String)) As String Return Nothing End Function Sub M() End Sub End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "B.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() Dim result = context.CompileExpression("If(MyClass.F(), If(MyClass.G, MyClass.P))", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 27 (0x1b) .maxstack 2 IL_0000: ldarg.0 IL_0001: call ""Function B.F() As String"" IL_0006: dup IL_0007: brtrue.s IL_001a IL_0009: pop IL_000a: ldarg.0 IL_000b: ldfld ""B.G As String"" IL_0010: dup IL_0011: brtrue.s IL_001a IL_0013: pop IL_0014: ldarg.0 IL_0015: call ""Function B.get_P() As String"" IL_001a: ret } ") testData = New CompilationTestData() result = context.CompileExpression("F(AddressOf MyClass.F)", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 18 (0x12) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldftn ""Function B.F() As String"" IL_0007: newobj ""Sub System.Func(Of String)..ctor(Object, System.IntPtr)"" IL_000c: call ""Function B.F(System.Func(Of String)) As String"" IL_0011: ret } ") testData = New CompilationTestData() result = context.CompileExpression("F(new System.Func(Of String)(AddressOf MyClass.F))", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 18 (0x12) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldftn ""Function B.F() As String"" IL_0007: newobj ""Sub System.Func(Of String)..ctor(Object, System.IntPtr)"" IL_000c: call ""Function B.F(System.Func(Of String)) As String"" IL_0011: ret } ") End Sub Public Sub EvaluateMyBase() Const source = " Class A Friend Overridable Function F() As String Return Nothing End Function Friend G As String Friend Overridable ReadOnly Property P As String Get Return Nothing End Get End Property End Class Class B Inherits A Friend Overrides Function F() As String Return Nothing End Function Friend Shadows G As String Friend Overrides ReadOnly Property P As String Get Return Nothing End Get End Property Overloads Shared Function F(f1 As System.Func(Of String)) As String Return Nothing End Function Sub M() End Sub End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "B.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() Dim result = context.CompileExpression("If(MyBase.F(), If(MyBase.G, MyBase.P))", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 27 (0x1b) .maxstack 2 IL_0000: ldarg.0 IL_0001: call ""Function A.F() As String"" IL_0006: dup IL_0007: brtrue.s IL_001a IL_0009: pop IL_000a: ldarg.0 IL_000b: ldfld ""A.G As String"" IL_0010: dup IL_0011: brtrue.s IL_001a IL_0013: pop IL_0014: ldarg.0 IL_0015: call ""Function A.get_P() As String"" IL_001a: ret } ") testData = New CompilationTestData() result = context.CompileExpression("F(AddressOf MyBase.F)", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 18 (0x12) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldftn ""Function A.F() As String"" IL_0007: newobj ""Sub System.Func(Of String)..ctor(Object, System.IntPtr)"" IL_000c: call ""Function B.F(System.Func(Of String)) As String"" IL_0011: ret } ") testData = New CompilationTestData() result = context.CompileExpression("F(new System.Func(Of String)(AddressOf MyBase.F))", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 18 (0x12) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldftn ""Function A.F() As String"" IL_0007: newobj ""Sub System.Func(Of String)..ctor(Object, System.IntPtr)"" IL_000c: call ""Function B.F(System.Func(Of String)) As String"" IL_0011: ret } ") End Sub Public Sub EvaluateStructureMe() Const source = " Structure S Shared Function F(x As Object, y As Object) As Object Return Nothing End Function Private x As Object Sub M() End Sub End Structure " Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="S.M", expr:="F(Me, Me.x)") Dim methodData = testData.GetMethodData("<>x.<>m0(ByRef S)") Dim parameter = DirectCast(methodData.Method, MethodSymbol).Parameters.Single() Assert.True(parameter.IsByRef) methodData.VerifyIL(" { // Code size 28 (0x1c) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldobj ""S"" IL_0006: box ""S"" IL_000b: ldarg.0 IL_000c: ldfld ""S.x As Object"" IL_0011: call ""Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object"" IL_0016: call ""Function S.F(Object, Object) As Object"" IL_001b: ret } ") End Sub Public Sub EvaluateSharedMethodParameters() Const source = " Class C Shared Function F(x As Integer, y As Integer) As Object Return x + y End Function Shared Sub M(x As Integer, y As Integer) End Sub End Class " Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="F(y, x)") testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 8 (0x8) .maxstack 2 IL_0000: ldarg.1 IL_0001: ldarg.0 IL_0002: call ""Function C.F(Integer, Integer) As Object"" IL_0007: ret } ") End Sub Public Sub EvaluateInstanceMethodParametersAndLocals() Const source = " Class C Function F(x As Integer) As Object Return x End Function Sub M(x As Integer) Dim y As Integer = 1 End Sub End Class " Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="F(x + y)") testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 10 (0xa) .maxstack 3 .locals init (Integer V_0) //y IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: ldloc.0 IL_0003: add.ovf IL_0004: callvirt ""Function C.F(Integer) As Object"" IL_0009: ret } ") End Sub Public Sub EvaluateLocals() Dim source = " Class C Shared Sub M() Dim x As Integer = 1 If x < 0 Then dim y As Integer = 2 Else #ExternalSource(""test"", 999) dim z As Integer = 3 #End ExternalSource End if End Sub End Class " Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", atLineNumber:=999, expr:="x + z") testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 4 (0x4) .maxstack 2 .locals init (Integer V_0, //x Boolean V_1, Integer V_2, Integer V_3) //z IL_0000: ldloc.0 IL_0001: ldloc.3 IL_0002: add.ovf IL_0003: ret }") End Sub Public Sub EvaluateForEachLocal() Const source = " Class C Shared Function F(args As Object()) As Boolean If args Is Nothing Then Return True End If For Each o In args #ExternalSource(""test"", 999) System.Console.WriteLine() ' Force non-hidden sequence point. #End ExternalSource Next Return False End Function End Class " Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.F", atLineNumber:=999, expr:="o") testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 3 (0x3) .maxstack 1 .locals init (Boolean V_0, //F Boolean V_1, Object() V_2, Integer V_3, Object V_4) //o IL_0000: ldloc.s V_4 IL_0002: ret }") End Sub ''' ''' Generated "Me" parameter should not conflict with existing "[Me]" parameter. ''' Public Sub ParameterNamedMe() Const source = " Class C Function M([Me] As C) As Object Return Nothing End Function End Class " Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="[Me].M(Me)") testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 8 (0x8) .maxstack 2 .locals init (Object V_0) //M IL_0000: ldarg.1 IL_0001: ldarg.0 IL_0002: callvirt ""Function C.M(C) As Object"" IL_0007: ret }") End Sub ''' ''' Generated "Me" parameter should not conflict with existing "[Me]" local. ''' Public Sub LocalNamedMe() Const source = " Class C Function M(o As Object) As Object Dim [Me] = Me Return Nothing End Function End Class " Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="[Me].M(Me)") testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 8 (0x8) .maxstack 2 .locals init (Object V_0, //M C V_1) //Me IL_0000: ldloc.1 IL_0001: ldarg.0 IL_0002: callvirt ""Function C.M(Object) As Object"" IL_0007: ret }") End Sub Public Sub ByRefParameter() Const source = " Class C Shared Function M( ByRef x As Object) As Object Dim y As Object x = Nothing Return Nothing End Function End Class " Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="M(y)") Dim parameter = testData.GetMethodData("<>x.<>m0(ByRef Object)").Method.Parameters.Single() Assert.Equal(RefKind.Ref, parameter.RefKind) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 8 (0x8) .maxstack 1 .locals init (Object V_0, //M Object V_1) //y IL_0000: ldloca.s V_1 IL_0002: call ""Function C.M(ByRef Object) As Object"" IL_0007: ret }") End Sub ''' ''' Method defined in IL where PDB does not contain VB custom metadata. ''' Public Sub LocalType_FromIL() Const il = " .class public C { .method public specialname rtspecialname instance void .ctor() { ret } .field public object F; .method public static void M() { .locals init ([0] class C c1) ret } } " Dim exeBytes As ImmutableArray(Of Byte) = Nothing Dim pdbBytes As ImmutableArray(Of Byte) = Nothing EmitILToArray(il, appendDefaultHeader:=True, includePdb:=True, assemblyBytes:=exeBytes, pdbBytes:=pdbBytes) Dim runtime = CreateRuntimeInstance( assemblyName:=ExpressionCompilerUtilities.GenerateUniqueName(), references:=ImmutableArray.Create(MscorlibRef), exeBytes:=exeBytes.ToArray(), symReader:=New SymReader(pdbBytes.ToArray())) Dim context = CreateMethodContext(runtime, methodName:="C.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() context.CompileExpression("c1.F", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 7 (0x7) .maxstack 1 .locals init (C V_0) //c1 IL_0000: ldloc.0 IL_0001: ldfld ""C.F As Object"" IL_0006: ret } ") End Sub ''' ''' Allow locals with optional custom modifiers. ''' ''' ''' The custom modifiers are not copied to the corresponding local ''' in the generated method since there is no need. ''' Public Sub LocalType_CustomModifiers() Const il = " .class public C { .method public specialname rtspecialname instance void .ctor() { ret } .field public object F; .method public static void M() { .locals init ([0] class C modopt(int32) modopt(object) c1) ret } } " Dim exeBytes As ImmutableArray(Of Byte) = Nothing Dim pdbBytes As ImmutableArray(Of Byte) = Nothing EmitILToArray(il, appendDefaultHeader:=True, includePdb:=True, assemblyBytes:=exeBytes, pdbBytes:=pdbBytes) Dim runtime = CreateRuntimeInstance( assemblyName:=ExpressionCompilerUtilities.GenerateUniqueName(), references:=ImmutableArray.Create(MscorlibRef), exeBytes:=exeBytes.ToArray(), symReader:=New SymReader(pdbBytes.ToArray())) Dim context = CreateMethodContext(runtime, methodName:="C.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() context.CompileExpression("c1.F", resultProperties, errorMessage, testData) Assert.Null(errorMessage) Dim methodData = testData.GetMethodData("<>x.<>m0") Dim locals = methodData.ILBuilder.LocalSlotManager.LocalsInOrder() Dim local = locals.Single() Assert.Equal("C", local.Type.ToString()) Assert.Equal(0, local.CustomModifiers.Length) ' Custom modifiers are not copied methodData.VerifyIL(" { // Code size 7 (0x7) .maxstack 1 .locals init (C V_0) //c1 IL_0000: ldloc.0 IL_0001: ldfld ""C.F As Object"" IL_0006: ret } ") End Sub Public Sub LocalType_ByRefOrPinned() Const il = " .class private auto ansi beforefieldinit C extends [mscorlib]System.Object { .method private hidebysig static void M(string s, int32[] a) cil managed { // Code size 73 (0x49) .maxstack 2 .locals init ([0] string pinned s, [1] int32& pinned f, [2] int32& i) ret } } " Dim exeBytes As ImmutableArray(Of Byte) = Nothing Dim pdbBytes As ImmutableArray(Of Byte) = Nothing EmitILToArray(il, appendDefaultHeader:=True, includePdb:=True, assemblyBytes:=exeBytes, pdbBytes:=pdbBytes) Dim runtime = CreateRuntimeInstance( assemblyName:=ExpressionCompilerUtilities.GenerateUniqueName(), references:=ImmutableArray.Create(MscorlibRef), exeBytes:=exeBytes.ToArray(), symReader:=New SymReader(pdbBytes.ToArray())) Dim context = CreateMethodContext(runtime, methodName:="C.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileExpression("s", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 3 (0x3) .maxstack 1 .locals init (pinned String V_0, //s pinned Integer& V_1, //f Integer& V_2) //i IL_0000: ldloc.0 IL_0001: conv.i IL_0002: ret }") testData = New CompilationTestData() context.CompileAssignment("s", """hello""", errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 7 (0x7) .maxstack 1 .locals init (pinned String V_0, //s pinned Integer& V_1, //f Integer& V_2) //i IL_0000: ldstr ""hello"" IL_0005: stloc.0 IL_0006: ret }") testData = New CompilationTestData() context.CompileExpression("f", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 4 (0x4) .maxstack 1 .locals init (pinned String V_0, //s pinned Integer& V_1, //f Integer& V_2) //i IL_0000: ldloc.1 IL_0001: conv.i IL_0002: ldind.i4 IL_0003: ret }") testData = New CompilationTestData() context.CompileAssignment("f", "1", errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 5 (0x5) .maxstack 2 .locals init (pinned String V_0, //s pinned Integer& V_1, //f Integer& V_2) //i IL_0000: ldloc.1 IL_0001: conv.i IL_0002: ldc.i4.1 IL_0003: stind.i4 IL_0004: ret }") testData = New CompilationTestData() context.CompileExpression("i", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 3 (0x3) .maxstack 1 .locals init (pinned String V_0, //s pinned Integer& V_1, //f Integer& V_2) //i IL_0000: ldloc.2 IL_0001: ldind.i4 IL_0002: ret }") testData = New CompilationTestData() context.CompileAssignment("i", "1", errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 4 (0x4) .maxstack 2 .locals init (pinned String V_0, //s pinned Integer& V_1, //f Integer& V_2) //i IL_0000: ldloc.2 IL_0001: ldc.i4.1 IL_0002: stind.i4 IL_0003: ret }") End Sub Public Sub AssignLocal() Const source = "Class C Shared Sub M() Dim x = 0 End Sub End Class" Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "C.M") Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() context.CompileAssignment("x", "1", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 3 (0x3) .maxstack 1 .locals init (Integer V_0) //x IL_0000: ldc.i4.1 IL_0001: stloc.0 IL_0002: ret }") End Sub Public Sub AssignInstanceMethodParametersAndLocals() Const source = " Class C Private a As Object() Shared Function F(x As Integer) As Integer Return x End Function Sub M(x As Integer) Dim y As Integer End Sub End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "C.M") Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() context.CompileAssignment("Me.a(F(x))", "Me.a(y)", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 27 (0x1b) .maxstack 4 .locals init (Integer V_0) //y IL_0000: ldarg.0 IL_0001: ldfld ""C.a As Object()"" IL_0006: ldarg.1 IL_0007: call ""Function C.F(Integer) As Integer"" IL_000c: ldarg.0 IL_000d: ldfld ""C.a As Object()"" IL_0012: ldloc.0 IL_0013: ldelem.ref IL_0014: call ""Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object"" IL_0019: stelem.ref IL_001a: ret } ") End Sub Public Sub EvaluateNothing() Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = Evaluate( SimpleSource, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="Nothing", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Equal(DkmClrCompilationResultFlags.ReadOnlyResult, resultProperties.Flags) Dim method = testData.GetMethodData("<>x.<>m0").Method Assert.Equal(SpecialType.System_Object, method.ReturnType.SpecialType) Assert.False(method.ReturnsVoid) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 2 (0x2) .maxstack 1 IL_0000: ldnull IL_0001: ret } ") End Sub Public Sub MayHaveSideEffects() Const source = "Imports System Imports System.Diagnostics.Contracts Class C Function F() As Object Return 1 End Function Function G() As Object Return 2 End Function Property P As Object Shared Function H() As Object Return 3 End Function Shared Sub M(o As C, i As Integer, a As Action) End Sub End Class" Dim compilation0 = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(compilation0) Dim context = CreateMethodContext( runtime, methodName:="C.M") CheckResultProperties(context, "o.F()", DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult) ' Calls to methods are reported as having side effects, even if ' the method is marked . This matches the native EE. CheckResultProperties(context, "o.G()", DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "o.P", DkmClrCompilationResultFlags.None) CheckResultProperties(context, "If(a, Sub() i = 1)", DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "If(a, Sub() i += 2)", DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "If(a, Sub() i *= 3)", DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "If(a, Sub() i -= 4)", DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "New C() With {.P = 1}", DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "New C() With {.P = H()}", DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult) End Sub Public Sub IsAssignable() Const source = " Imports System Class C Public F As Integer Public ReadOnly RF As Integer Public Const CF As Integer = 1 Public Event E() Public Custom Event CE As Action AddHandler(value As Action) End AddHandler RemoveHandler(value As Action) End RemoveHandler RaiseEvent() End RaiseEvent End Event Public ReadOnly Property RP As Integer Get Return 0 End Get End Property Public WriteOnly Property WP As Integer Set(value As Integer) End Set End Property Public Property RWP As Integer Public ReadOnly Property RP(x As Integer) As Integer Get Return 0 End Get End Property Public WriteOnly Property WP(x As Integer) As Integer Set(value As Integer) End Set End Property Public Property RWP(x As Integer) As Integer Get Return 0 End Get Set(value As Integer) End Set End Property Public Function M() As Integer Return 0 End Function End Class " Dim compilation0 = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(compilation0) Dim context = CreateMethodContext( runtime, methodName:="C.M") CheckResultProperties(context, "F", DkmClrCompilationResultFlags.None) CheckResultProperties(context, "RF", DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "CF", DkmClrCompilationResultFlags.ReadOnlyResult) ' Note: flags are always None in error cases. CheckResultProperties(context, "E", DkmClrCompilationResultFlags.None, "(1,2): error BC32022: 'Public Event E As C.EEventHandler' is an event, and cannot be called directly. Use a 'RaiseEvent' statement to raise an event.") CheckResultProperties(context, "CE", DkmClrCompilationResultFlags.None, "(1,2): error BC32022: 'Public Event CE As Action' is an event, and cannot be called directly. Use a 'RaiseEvent' statement to raise an event.") CheckResultProperties(context, "RP", DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "WP", DkmClrCompilationResultFlags.None, "(1,2): error BC30524: Property 'WP' is 'WriteOnly'.") CheckResultProperties(context, "RWP", DkmClrCompilationResultFlags.None) CheckResultProperties(context, "RP(1)", DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "WP(1)", DkmClrCompilationResultFlags.None, "(1,2): error BC30524: Property 'WP' is 'WriteOnly'.") CheckResultProperties(context, "RWP(1)", DkmClrCompilationResultFlags.None) CheckResultProperties(context, "M()", DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "Nothing", DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "1", DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "AddressOf M", DkmClrCompilationResultFlags.None, "(1,2): error BC30491: Expression does not produce a value.") CheckResultProperties(context, "GetType(C)", DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "New C()", DkmClrCompilationResultFlags.ReadOnlyResult) End Sub Public Sub IsAssignable_Array() Const source = " Imports System Class C Public ReadOnly RF As Integer() Private Readonly _rp As Integer() Public ReadOnly Property RP As Integer() Get Return _rp End Get End Property Private ReadOnly _m As Integer() Public Function M() As Integer() Return _m End Function End Class " Dim compilation0 = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(compilation0) Dim context = CreateMethodContext( runtime, methodName:="C.M") CheckResultProperties(context, "RF", DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "RF(0)", DkmClrCompilationResultFlags.None) CheckResultProperties(context, "RP", DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "RP(0)", DkmClrCompilationResultFlags.None) CheckResultProperties(context, "M()", DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult) CheckResultProperties(context, "M()(0)", DkmClrCompilationResultFlags.PotentialSideEffect) End Sub Private Shared Sub CheckResultProperties(context As EvaluationContext, expr As String, expectedFlags As DkmClrCompilationResultFlags, Optional expectedErrorMessage As String = Nothing) Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() Dim result = context.CompileExpression(expr, resultProperties, errorMessage, testData) Assert.Equal(expectedErrorMessage, errorMessage) Assert.NotEqual(expectedErrorMessage Is Nothing, result.Assembly Is Nothing) Assert.Equal(expectedFlags, resultProperties.Flags) End Sub ''' ''' Set BooleanResult for bool expressions. ''' Public Sub EvaluateBooleanExpression() Dim source = "Class C Shared Function F() As Boolean Return False End Function Shared Sub M(x As Boolean, y As Boolean?) End Sub End Class" Dim compilation0 = CreateCompilationWithMscorlib( {source}, compOptions:=TestOptions.DebugDll, assemblyName:=ExpressionCompilerUtilities.GenerateUniqueName()) Dim runtime = CreateRuntimeInstance(compilation0) Dim context = CreateMethodContext(runtime, methodName:="C.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing context.CompileExpression("x", resultProperties, errorMessage) Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.BoolResult) context.CompileExpression("y", resultProperties, errorMessage) Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.None) context.CompileExpression("y.Value", resultProperties, errorMessage) Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.BoolResult Or DkmClrCompilationResultFlags.ReadOnlyResult) context.CompileExpression("Not y", resultProperties, errorMessage) Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.ReadOnlyResult) context.CompileExpression("False", resultProperties, errorMessage) Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.BoolResult Or DkmClrCompilationResultFlags.ReadOnlyResult) context.CompileExpression("F()", resultProperties, errorMessage) Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.BoolResult Or DkmClrCompilationResultFlags.ReadOnlyResult Or DkmClrCompilationResultFlags.PotentialSideEffect) End Sub Public Sub EvaluateNonRValueExpression() Const source = " Class C WriteOnly Property P As Object Set End Set End Property Sub M() End Sub End Class " Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="P", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Equal("(1) : error BC30524: Property 'P' is 'WriteOnly'.", errorMessage) End Sub ''' ''' Expression that does not return a value. ''' Public Sub EvaluateVoidExpression() Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = Evaluate( SimpleSource, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="C.M()", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Equal(DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult, resultProperties.Flags) Dim method = testData.GetMethodData("<>x.<>m0").Method Assert.Equal(SpecialType.System_Void, method.ReturnType.SpecialType) Assert.True(method.ReturnsVoid) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 6 (0x6) .maxstack 0 IL_0000: call ""Sub C.M()"" IL_0005: ret }") End Sub Public Sub EvaluateMethodGroup() Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = Evaluate( SimpleSource, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="AddressOf C.M", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Equal("(1) : error BC30491: Expression does not produce a value.", errorMessage) Dim source = " Class C Shared Function F() As Boolean Return True End Function End Class" testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.F", expr:="C.F", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) Assert.Equal(DkmEvaluationResultAccessType.Public, resultProperties.AccessType) Assert.Equal(DkmEvaluationResultCategory.Method, resultProperties.Category) Assert.Equal(DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult Or DkmClrCompilationResultFlags.BoolResult, resultProperties.Flags) Assert.Equal(DkmEvaluationResultTypeModifierFlags.None, resultProperties.ModifierFlags) Assert.Equal(DkmEvaluationResultStorageType.Static, resultProperties.StorageType) End Sub Public Sub EvaluatePropertyGroup() Dim source = " Class C Property P As Boolean End Class " Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.get_P", expr:="P", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) Assert.Equal(DkmEvaluationResultAccessType.Public, resultProperties.AccessType) Assert.Equal(DkmEvaluationResultCategory.Property, resultProperties.Category) Assert.Equal(DkmClrCompilationResultFlags.BoolResult, resultProperties.Flags) Assert.Equal(DkmEvaluationResultTypeModifierFlags.None, resultProperties.ModifierFlags) Assert.Equal(DkmEvaluationResultStorageType.None, resultProperties.StorageType) testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.set_P", expr:="P()", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) Assert.Equal(DkmEvaluationResultAccessType.Public, resultProperties.AccessType) Assert.Equal(DkmEvaluationResultCategory.Property, resultProperties.Category) Assert.Equal(DkmClrCompilationResultFlags.BoolResult, resultProperties.Flags) Assert.Equal(DkmEvaluationResultTypeModifierFlags.None, resultProperties.ModifierFlags) Assert.Equal(DkmEvaluationResultStorageType.None, resultProperties.StorageType) End Sub Public Sub EvaluateXmlMemberAccess() Dim source = "Class C Shared Sub M(x As System.Xml.Linq.XElement) Dim y = x.@ End Sub End Class" Dim allReferences = GetAllXmlReferences() Dim comp = CreateCompilationWithReferences( MakeSources(source), options:=TestOptions.DebugDll, references:=allReferences) Dim exeBytes As Byte() = Nothing Dim pdbBytes As Byte() = Nothing Dim references As ImmutableArray(Of MetadataReference) = Nothing comp.EmitAndGetReferences(exeBytes, pdbBytes, references) Dim runtime = CreateRuntimeInstance( ExpressionCompilerUtilities.GenerateUniqueName(), allReferences, exeBytes, Nothing) Dim context = CreateMethodContext(runtime, "C.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() Dim result = context.CompileExpression("x.@a", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 22 (0x16) .maxstack 3 .locals init (String V_0) IL_0000: ldarg.0 IL_0001: ldstr ""a"" IL_0006: ldstr """" IL_000b: call ""Function System.Xml.Linq.XName.Get(String, String) As System.Xml.Linq.XName"" IL_0010: call ""Function My.InternalXmlHelper.get_AttributeValue(System.Xml.Linq.XElement, System.Xml.Linq.XName) As String"" IL_0015: ret }") End Sub Public Sub AssignByRefParameter() Const source = "Class C Shared Sub M1(ByRef x As Integer) x = 1 End Sub Shared Sub M2(Of T)(ByRef y As T) y = Nothing End Sub End Class" Dim compilation0 = CreateCompilationWithMscorlib( {source}, references:={SystemCoreRef}, compOptions:=TestOptions.DebugDll, assemblyName:=ExpressionCompilerUtilities.GenerateUniqueName()) Dim runtime = CreateRuntimeInstance(compilation0) Dim context = CreateMethodContext( runtime, methodName:="C.M1") Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileAssignment("x", "2", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 4 (0x4) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldc.i4.2 IL_0002: stind.i4 IL_0003: ret } ") context = CreateMethodContext( runtime, methodName:="C.M2") testData = New CompilationTestData() context.CompileAssignment("y", "Nothing", errorMessage, testData) testData.GetMethodData("<>x.<>m0(Of T)").VerifyIL(" { // Code size 8 (0x8) .maxstack 1 IL_0000: ldarg.0 IL_0001: initobj ""T"" IL_0007: ret } ") End Sub Public Sub EvaluateNamespace() Const source = " Namespace N Class C Shared Sub M() End Sub End Class End Namespace " Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="N.C.M", expr:="N", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Equal("(1) : error BC30112: 'N' is a namespace and cannot be used as an expression.", errorMessage) End Sub Public Sub EvaluateType() Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = Evaluate( SimpleSource, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="C", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Equal("(1) : error BC30109: 'C' is a class type and cannot be used as an expression.", errorMessage) End Sub Public Sub RewriteCatchLocal() Const source = "Imports System Class E(Of T) Inherits Exception End Class Class C(Of T) Shared Sub M() Microsoft.VisualBasic.VBMath.Randomize() ' Make sure Microsoft.VisualBasic has been loaded. dim z as Integer = 0 End Sub End Class" Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:= "DirectCast(Function() Dim e1 As E(Of T) = Nothing Try Catch e2 As E(Of T) e1 = e2 End Try Return e1 End Function, Func(Of E(Of T)))()") Dim methodData = testData.GetMethodData("<>x(Of T)._Closure$__._Lambda$__0-0") Dim method = DirectCast(methodData.Method, MethodSymbol) Dim containingType = method.ContainingType Dim returnType = DirectCast(method.ReturnType, NamedTypeSymbol) ' Return type E(Of T) with type argument T from <>x(Of T). Assert.Equal(returnType.TypeArguments(0).ContainingSymbol, containingType.ContainingType) Dim locals = methodData.ILBuilder.LocalSlotManager.LocalsInOrder() Assert.Equal(locals.Length, 2) ' All locals of type E(Of T) with type argument T from <>x(Of T). For Each local In locals Dim localType = DirectCast(local.Type, NamedTypeSymbol) Dim typeArg = localType.TypeArguments(0) Assert.Equal(typeArg.ContainingSymbol, containingType.ContainingType) Next methodData.VerifyIL( "{ // Code size 22 (0x16) .maxstack 2 .locals init (E(Of T) V_0, //e1 E(Of T) V_1) //e2 IL_0000: ldnull IL_0001: stloc.0 .try { IL_0002: leave.s IL_0014 } catch E(Of T) { IL_0004: dup IL_0005: call ""Sub Microsoft.VisualBasic.CompilerServices.ProjectData.SetProjectError(System.Exception)"" IL_000a: stloc.1 IL_000b: ldloc.1 IL_000c: stloc.0 IL_000d: call ""Sub Microsoft.VisualBasic.CompilerServices.ProjectData.ClearProjectError()"" IL_0012: leave.s IL_0014 } IL_0014: ldloc.0 IL_0015: ret }") End Sub Public Sub RewriteSequenceTemps() Const source = "Class C Private F As Object Shared Sub M(Of T As {C, New})() Dim o As T End Sub End Class" Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="New T() With {.F = 1}") Dim methodData = testData.GetMethodData("<>x.<>m0(Of T)") Dim method = DirectCast(methodData.Method, MethodSymbol) Dim returnType = method.ReturnType Assert.Equal(returnType.TypeKind, TypeKind.TypeParameter) Assert.Equal(returnType.ContainingSymbol, method) Dim locals = methodData.ILBuilder.LocalSlotManager.LocalsInOrder() ' Both locals of type T from <>m0(Of T): the original local ' and the temporary for "New T()" in (New T()).F = 1. Assert.Equal(locals.Length, 2) For Each local In locals Dim localType = DirectCast(local.Type, TypeSymbol) Assert.Equal(localType.ContainingSymbol, method) Next testData.GetMethodData("<>x.<>m0").VerifyIL(" { ... }") End Sub Public Sub GenericMethod() Const source = "Class A(Of T) Class B(Of U, V As U) Shared Sub M1(Of W, X As A(Of W).B(Of Object, U()))() End Sub Shared Sub M2() End Sub End Class End Class" Dim compilation0 = CreateCompilationWithMscorlib( {source}, compOptions:=TestOptions.DebugDll, assemblyName:=ExpressionCompilerUtilities.GenerateUniqueName()) Dim runtime = CreateRuntimeInstance(compilation0) Dim context = CreateMethodContext( runtime, methodName:="A.B.M1") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileExpression("If(GetType(V), GetType(X))", resultProperties, errorMessage, testData) Dim methodData = testData.GetMethodData("<>x(Of T, U, V).<>m0(Of W, X)") Dim actualIL = methodData.GetMethodIL() Dim expectedIL = " { // Code size 25 (0x19) .maxstack 2 IL_0000: ldtoken ""V"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: dup IL_000b: brtrue.s IL_0018 IL_000d: pop IL_000e: ldtoken ""X"" IL_0013: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_0018: ret } " AssertEx.AssertEqualToleratingWhitespaceDifferences(expectedIL, actualIL) Assert.Equal(Cci.CallingConvention.Generic, (DirectCast(methodData.Method, Cci.IMethodDefinition)).CallingConvention) context = CreateMethodContext( runtime, methodName:="A.B.M2") testData = New CompilationTestData() context.CompileExpression("If(GetType(T), GetType(U))", resultProperties, errorMessage, testData) methodData = testData.GetMethodData("<>x(Of T, U, V).<>m0") Assert.Equal(Cci.CallingConvention.Default, (DirectCast(methodData.Method, Cci.IMethodDefinition)).CallingConvention) End Sub Public Sub EvaluateCapturedLocalsOutsideLambda() Const source = "Class A Friend Overridable Function F(o As Object) As Object Return 1 End Function End Class Class B Inherits A Friend Overrides Function F(o As Object) As Object Return 2 End Function Shared Overloads Sub F(_f As System.Func(Of Object)) _f() End Sub Sub M(Of T As {A, New})(x As Object) F(Function() Me.F(x)) If x IsNot Nothing Then #ExternalSource(""test"", 999) Dim y = New T() Dim z = 1 F(Function() MyBase.F(y)) #End ExternalSource Else Dim w = 2 F(Function() w) End If End Sub End Class" Dim compilation0 = CreateCompilationWithMscorlib( {source}, compOptions:=TestOptions.DebugDll, assemblyName:=ExpressionCompilerUtilities.GenerateUniqueName()) Dim runtime = CreateRuntimeInstance(compilation0) Dim context = CreateMethodContext( runtime, methodName:="B.M", atLineNumber:=999) Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileExpression("Me.F(y)", resultProperties, errorMessage, testData) testData.GetMethodData("<>x.<>m0(Of T)").VerifyIL( "{ // Code size 23 (0x17) .maxstack 2 .locals init (B._Closure$__3-0(Of T) V_0, //$VB$Closure_0 Boolean V_1, B._Closure$__3-1(Of T) V_2, //$VB$Closure_1 Integer V_3, //z B._Closure$__3-2(Of T) V_4) IL_0000: ldloc.0 IL_0001: ldfld ""B._Closure$__3-0(Of T).$VB$Me As B"" IL_0006: ldloc.2 IL_0007: ldfld ""B._Closure$__3-1(Of T).$VB$Local_y As T"" IL_000c: box ""T"" IL_0011: callvirt ""Function B.F(Object) As Object"" IL_0016: ret }") testData = New CompilationTestData() context.CompileExpression("MyClass.F(y)", resultProperties, errorMessage, testData) testData.GetMethodData("<>x.<>m0(Of T)").VerifyIL( "{ // Code size 23 (0x17) .maxstack 2 .locals init (B._Closure$__3-0(Of T) V_0, //$VB$Closure_0 Boolean V_1, B._Closure$__3-1(Of T) V_2, //$VB$Closure_1 Integer V_3, //z B._Closure$__3-2(Of T) V_4) IL_0000: ldloc.0 IL_0001: ldfld ""B._Closure$__3-0(Of T).$VB$Me As B"" IL_0006: ldloc.2 IL_0007: ldfld ""B._Closure$__3-1(Of T).$VB$Local_y As T"" IL_000c: box ""T"" IL_0011: call ""Function B.F(Object) As Object"" IL_0016: ret }") testData = New CompilationTestData() context.CompileExpression("MyBase.F(x)", resultProperties, errorMessage, testData) testData.GetMethodData("<>x.<>m0(Of T)").VerifyIL( "{ // Code size 23 (0x17) .maxstack 2 .locals init (B._Closure$__3-0(Of T) V_0, //$VB$Closure_0 Boolean V_1, B._Closure$__3-1(Of T) V_2, //$VB$Closure_1 Integer V_3, //z B._Closure$__3-2(Of T) V_4) IL_0000: ldloc.0 IL_0001: ldfld ""B._Closure$__3-0(Of T).$VB$Me As B"" IL_0006: ldloc.0 IL_0007: ldfld ""B._Closure$__3-0(Of T).$VB$Local_x As Object"" IL_000c: call ""Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object"" IL_0011: call ""Function A.F(Object) As Object"" IL_0016: ret }") End Sub ''' ''' Generate PrivateImplementationDetails class ''' for initializer expressions. ''' Public Sub EvaluateInitializerExpression() Const source = "Class C Shared Sub M() End Sub End Class" Dim compilation0 = CreateCompilationWithMscorlib( {source}, references:={SystemCoreRef}, compOptions:=TestOptions.DebugDll.WithModuleName("MODULE"), assemblyName:=ExpressionCompilerUtilities.GenerateUniqueName()) Dim runtime = CreateRuntimeInstance(compilation0) Dim context = CreateMethodContext( runtime, methodName:="C.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileExpression("{ 1, 2, 3, 4, 5 }", resultProperties, errorMessage, testData) Dim methodData = testData.GetMethodData("<>x.<>m0") Assert.Equal(methodData.Method.ReturnType.ToDisplayString(), "Integer()") methodData.VerifyIL( "{ // Code size 18 (0x12) .maxstack 3 IL_0000: ldc.i4.5 IL_0001: newarr ""Integer"" IL_0006: dup IL_0007: ldtoken ""<{#Module#}.dll>.__StaticArrayInitTypeSize=20 <{#Module#}.dll>.1036C5F8EF306104BD582D73E555F4DAE8EECB24"" IL_000c: call ""Sub System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)"" IL_0011: ret }") End Sub Public Sub ExpressionTree() Const source = "Imports System Imports System.Linq.Expressions Class C Shared Function F(e As Expression(Of Func(Of Object))) As Object Return e.Compile()() End Function Shared Sub M(o As Integer) End Sub End Class" Dim compilation0 = CreateCompilationWithMscorlib( {source}, references:={SystemCoreRef}, compOptions:=TestOptions.DebugDll, assemblyName:=ExpressionCompilerUtilities.GenerateUniqueName()) Dim runtime = CreateRuntimeInstance(compilation0) Dim context = CreateMethodContext( runtime, methodName:="C.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileExpression("F(Function() o + 1)", resultProperties, errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 100 (0x64) .maxstack 3 IL_0000: newobj ""Sub <>x._Closure$__0-0..ctor()"" IL_0005: dup IL_0006: ldarg.0 IL_0007: stfld ""<>x._Closure$__0-0.$VB$Local_o As Integer"" IL_000c: ldtoken ""<>x._Closure$__0-0"" IL_0011: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_0016: call ""Function System.Linq.Expressions.Expression.Constant(Object, System.Type) As System.Linq.Expressions.ConstantExpression"" IL_001b: ldtoken ""<>x._Closure$__0-0.$VB$Local_o As Integer"" IL_0020: call ""Function System.Reflection.FieldInfo.GetFieldFromHandle(System.RuntimeFieldHandle) As System.Reflection.FieldInfo"" IL_0025: call ""Function System.Linq.Expressions.Expression.Field(System.Linq.Expressions.Expression, System.Reflection.FieldInfo) As System.Linq.Expressions.MemberExpression"" IL_002a: ldc.i4.1 IL_002b: box ""Integer"" IL_0030: ldtoken ""Integer"" IL_0035: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_003a: call ""Function System.Linq.Expressions.Expression.Constant(Object, System.Type) As System.Linq.Expressions.ConstantExpression"" IL_003f: call ""Function System.Linq.Expressions.Expression.AddChecked(System.Linq.Expressions.Expression, System.Linq.Expressions.Expression) As System.Linq.Expressions.BinaryExpression"" IL_0044: ldtoken ""Object"" IL_0049: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_004e: call ""Function System.Linq.Expressions.Expression.Convert(System.Linq.Expressions.Expression, System.Type) As System.Linq.Expressions.UnaryExpression"" IL_0053: ldc.i4.0 IL_0054: newarr ""System.Linq.Expressions.ParameterExpression"" IL_0059: call ""Function System.Linq.Expressions.Expression.Lambda(Of System.Func(Of Object))(System.Linq.Expressions.Expression, ParamArray System.Linq.Expressions.ParameterExpression()) As System.Linq.Expressions.Expression(Of System.Func(Of Object))"" IL_005e: call ""Function C.F(System.Linq.Expressions.Expression(Of System.Func(Of Object))) As Object"" IL_0063: ret }") End Sub ''' ''' DiagnosticsPass must be run on evaluation method. ''' Public Sub DiagnosticsPass() Const source = "Imports System Imports System.Linq.Expressions Class C Shared Function F(e As Expression(Of Func(Of Object))) As Object Return e.Compile()() End Function Shared Sub M() End Sub End Class" Dim compilation0 = CreateCompilationWithMscorlib( {source}, references:={SystemCoreRef}, compOptions:=TestOptions.DebugDll, assemblyName:=ExpressionCompilerUtilities.GenerateUniqueName()) Dim runtime = CreateRuntimeInstance(compilation0) Dim context = CreateMethodContext( runtime, methodName:="C.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileExpression("F(Function() Return Nothing End Function)", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) Assert.Equal(errorMessage, "(1) : error BC36675: Statement lambdas cannot be converted to expression trees.") End Sub Public Sub EvaluateAsync() Const source = "Imports System Imports System.Threading.Tasks Class C Async Function F() As Task(Of Object) Return Nothing End Function Sub G(f As Func(Of Task(Of Object))) End Sub Sub M() End Sub End Class" Dim compilation0 = CreateCompilationWithMscorlib45AndVBRuntime(MakeSources(source), options:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(compilation0) Dim context = CreateMethodContext(runtime, methodName:="C.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileExpression("G(Async Function() Await F())", resultProperties, errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 37 (0x25) .maxstack 3 .locals init (<>x._Closure$__0-0 V_0) //$VB$Closure_0 IL_0000: newobj ""Sub <>x._Closure$__0-0..ctor()"" IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ldarg.0 IL_0008: stfld ""<>x._Closure$__0-0.$VB$Local_$VB$Me As C"" IL_000d: ldloc.0 IL_000e: ldfld ""<>x._Closure$__0-0.$VB$Local_$VB$Me As C"" IL_0013: ldloc.0 IL_0014: ldftn ""Function <>x._Closure$__0-0._Lambda$__0() As System.Threading.Tasks.Task(Of Object)"" IL_001a: newobj ""Sub System.Func(Of System.Threading.Tasks.Task(Of Object))..ctor(Object, System.IntPtr)"" IL_001f: callvirt ""Sub C.G(System.Func(Of System.Threading.Tasks.Task(Of Object)))"" IL_0024: ret }") End Sub ''' ''' Unnamed temporaries at the end of the local ''' signature should be preserved. ''' Public Sub TrailingUnnamedTemporaries() Const source = "Class C Private F As Object Shared Function M(c As Object()) As Boolean For Each o in c If o IsNot Nothing Then Return True Next Return False End Function End Class" Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="New C() With {.F = 1}") testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 18 (0x12) .maxstack 3 .locals init (Boolean V_0, //M Object() V_1, Integer V_2, Object V_3, Boolean V_4) IL_0000: newobj ""Sub C..ctor()"" IL_0005: dup IL_0006: ldc.i4.1 IL_0007: box ""Integer"" IL_000c: stfld ""C.F As Object"" IL_0011: ret }") End Sub Public Sub ConditionalAttribute() Const source = "Imports System.Diagnostics Class C Shared Sub M(x As Integer) End Sub Shared Sub F(o As Object) End Sub End Class" Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="F(x + 1)") testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 14 (0xe) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldc.i4.1 IL_0002: add.ovf IL_0003: box ""Integer"" IL_0008: call ""Sub C.F(Object)"" IL_000d: ret }") End Sub Public Sub ConditionalAttribute_CollectionInitializer() Const source = "Imports System.Collections Imports System.Collections.Generic Imports System.Diagnostics Class C Implements IEnumerable Private c As New List(Of Object)() Sub Add(o As Object) c.Add(o) End Sub Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator Return c.GetEnumerator() End Function Shared Sub M() End Sub End Class" Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="New C() From {1, 2}") testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 30 (0x1e) .maxstack 3 IL_0000: newobj ""Sub C..ctor()"" IL_0005: dup IL_0006: ldc.i4.1 IL_0007: box ""Integer"" IL_000c: callvirt ""Sub C.Add(Object)"" IL_0011: dup IL_0012: ldc.i4.2 IL_0013: box ""Integer"" IL_0018: callvirt ""Sub C.Add(Object)"" IL_001d: ret }") End Sub Public Sub Repro994485() Const source = " Imports System Enum E A End Enum Class C Function M(e As E?) As Action Dim a As Action = Sub() e.ToString() Dim ee As E = e.Value Return a End Function End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext( runtime, methodName:="C.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() context.CompileExpression("e.HasValue", resultProperties, errorMessage, testData) Dim methodData = testData.GetMethodData("<>x.<>m0") Assert.Equal(DirectCast(methodData.Method, MethodSymbol).ReturnType.SpecialType, SpecialType.System_Boolean) methodData.VerifyIL( "{ // Code size 12 (0xc) .maxstack 1 .locals init (C._Closure$__1-0 V_0, //$VB$Closure_0 System.Action V_1, //M System.Action V_2, //a E V_3) //ee IL_0000: ldloc.0 IL_0001: ldflda ""C._Closure$__1-0.$VB$Local_e As E?"" IL_0006: call ""Function E?.get_HasValue() As Boolean"" IL_000b: ret }") End Sub Public Sub NestedGenericTypes() Const source = " Class C(Of T) Class D(Of U) Sub M(u1 As U, t1 As T, type1 As System.Type, type2 As System.Type) End Sub End Class End Class " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.D.M", expr:="M(u1, t1, GetType(U), GetType(T))", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult) testData.GetMethodData("<>x(Of T, U).<>m0").VerifyIL( "{ // Code size 29 (0x1d) .maxstack 5 IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: ldarg.2 IL_0003: ldtoken ""U"" IL_0008: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000d: ldtoken ""T"" IL_0012: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_0017: callvirt ""Sub C(Of T).D(Of U).M(U, T, System.Type, System.Type)"" IL_001c: ret }") End Sub Public Sub NestedGenericTypes_GenericMethod() Const source = " Class C(Of T) Class D(Of U) Sub M(Of V)(v1 As V, u1 As U, t1 As T, type1 As System.Type, type2 As System.Type, type3 As System.Type) End Sub End Class End Class " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.D.M", expr:="M(v1, u1, t1, GetType(V), GetType(U), GetType(T))", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult) testData.GetMethodData("<>x(Of T, U).<>m0(Of V)").VerifyIL( "{ // Code size 40 (0x28) .maxstack 7 IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: ldarg.2 IL_0003: ldarg.3 IL_0004: ldtoken ""V"" IL_0009: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000e: ldtoken ""U"" IL_0013: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_0018: ldtoken ""T"" IL_001d: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_0022: callvirt ""Sub C(Of T).D(Of U).M(Of V)(V, U, T, System.Type, System.Type, System.Type)"" IL_0027: ret }") End Sub Public Sub MyBaseExpression() Const source = " Class Base End Class Class Derived Inherits Base Sub M() End Sub End Class " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="Derived.M", expr:="MyBase", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Equal("(1) : error BC32027: 'MyBase' must be followed by '.' and an identifier.", errorMessage) End Sub Public Sub NonCapturingLambda() Const source = " Class C Sub M() End Sub End Class " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="(New System.Func(Of Integer, Integer)(Function(x) x + x))(1)", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 43 (0x2b) .maxstack 2 IL_0000: ldsfld ""<>x._Closure$__.$I0-0 As System.Func(Of Integer, Integer)"" IL_0005: brfalse.s IL_000e IL_0007: ldsfld ""<>x._Closure$__.$I0-0 As System.Func(Of Integer, Integer)"" IL_000c: br.s IL_0024 IL_000e: ldsfld ""<>x._Closure$__.$I As <>x._Closure$__"" IL_0013: ldftn ""Function <>x._Closure$__._Lambda$__0-0(Integer) As Integer"" IL_0019: newobj ""Sub System.Func(Of Integer, Integer)..ctor(Object, System.IntPtr)"" IL_001e: dup IL_001f: stsfld ""<>x._Closure$__.$I0-0 As System.Func(Of Integer, Integer)"" IL_0024: ldc.i4.1 IL_0025: callvirt ""Function System.Func(Of Integer, Integer).Invoke(Integer) As Integer"" IL_002a: ret } ") testData.GetMethodData("<>x._Closure$__._Lambda$__0-0").VerifyIL( "{ // Code size 4 (0x4) .maxstack 2 IL_0000: ldarg.1 IL_0001: dup IL_0002: add.ovf IL_0003: ret }") End Sub Public Sub CapturingLambda_Parameter() Const source = " Class C Sub M(p As Integer) End Sub End Class " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="(New System.Func(Of Integer, Integer)(Function(x) x + p))(1)", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 30 (0x1e) .maxstack 3 IL_0000: newobj ""Sub <>x._Closure$__0-0..ctor()"" IL_0005: dup IL_0006: ldarg.1 IL_0007: stfld ""<>x._Closure$__0-0.$VB$Local_p As Integer"" IL_000c: ldftn ""Function <>x._Closure$__0-0._Lambda$__0(Integer) As Integer"" IL_0012: newobj ""Sub System.Func(Of Integer, Integer)..ctor(Object, System.IntPtr)"" IL_0017: ldc.i4.1 IL_0018: callvirt ""Function System.Func(Of Integer, Integer).Invoke(Integer) As Integer"" IL_001d: ret }") testData.GetMethodData("<>x._Closure$__0-0._Lambda$__0").VerifyIL( "{ // Code size 9 (0x9) .maxstack 2 IL_0000: ldarg.1 IL_0001: ldarg.0 IL_0002: ldfld ""<>x._Closure$__0-0.$VB$Local_p As Integer"" IL_0007: add.ovf IL_0008: ret }") End Sub Public Sub CapturingLambda_HoistedParameter() Const source = " Imports System.Collections.Generic Class C Iterator Function M(p As Integer) As IEnumerable(Of Integer) N(p) Yield p N(p) End Function Sub N(p As Integer) End Sub End Class " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.VB$StateMachine_1_M.MoveNext", expr:="(New System.Func(Of Integer, Integer)(Function(x) x + p))(1)", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 30 (0x1e) .maxstack 3 .locals init (Boolean V_0, Integer V_1) IL_0000: newobj ""Sub <>x._Closure$__0-0..ctor()"" IL_0005: dup IL_0006: ldarg.0 IL_0007: stfld ""<>x._Closure$__0-0.$VB$Local_$VB$Me As C.VB$StateMachine_1_M"" IL_000c: ldftn ""Function <>x._Closure$__0-0._Lambda$__0(Integer) As Integer"" IL_0012: newobj ""Sub System.Func(Of Integer, Integer)..ctor(Object, System.IntPtr)"" IL_0017: ldc.i4.1 IL_0018: callvirt ""Function System.Func(Of Integer, Integer).Invoke(Integer) As Integer"" IL_001d: ret }") testData.GetMethodData("<>x._Closure$__0-0._Lambda$__0").VerifyIL( "{ // Code size 14 (0xe) .maxstack 2 IL_0000: ldarg.1 IL_0001: ldarg.0 IL_0002: ldfld ""<>x._Closure$__0-0.$VB$Local_$VB$Me As C.VB$StateMachine_1_M"" IL_0007: ldfld ""C.VB$StateMachine_1_M.$VB$Local_p As Integer"" IL_000c: add.ovf IL_000d: ret }") End Sub Public Sub UntypedLambda() Const source = " Class C Sub M() End Sub End Class " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="Function(x) 1", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( " { // Code size 36 (0x24) .maxstack 2 IL_0000: ldsfld ""<>x._Closure$__.$I0-0 As "" IL_0005: brfalse.s IL_000d IL_0007: ldsfld ""<>x._Closure$__.$I0-0 As "" IL_000c: ret IL_000d: ldsfld ""<>x._Closure$__.$I As <>x._Closure$__"" IL_0012: ldftn ""Function <>x._Closure$__._Lambda$__0-0(Object) As Integer"" IL_0018: newobj ""Sub VB$AnonymousDelegate_0(Of Object, Integer)..ctor(Object, System.IntPtr)"" IL_001d: dup IL_001e: stsfld ""<>x._Closure$__.$I0-0 As "" IL_0023: ret }") testData.GetMethodData("<>x._Closure$__._Lambda$__0-0").VerifyIL( "{ // Code size 2 (0x2) .maxstack 1 IL_0000: ldc.i4.1 IL_0001: ret }") End Sub Public Sub ClassMyBaseCall() Const source = " Class C Sub M() End Sub End Class " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="MyBase.ToString()", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.0 IL_0001: call ""Function Object.ToString() As String"" IL_0006: ret } ") End Sub Public Sub StructureMyBaseCall() Const source = " Structure S Sub M() End Sub End Structure " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="S.M", expr:="MyBase.ToString()", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Equal("(1) : error BC30044: 'MyBase' is not valid within a structure.", errorMessage) End Sub Public Sub ModuleMyBaseCall() Const source = " Module S Sub M() End Sub End Module " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="S.M", expr:="MyBase.ToString()", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Equal("(1) : error BC32001: 'MyBase' is not valid within a Module.", errorMessage) End Sub Public Sub IntegerOverflow() Const source = " Class C Sub M() End Sub End Class " Dim checkedComp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(checkedComp) Dim context = CreateMethodContext(runtime, methodName:="C.M") Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties = Nothing Dim testData As New CompilationTestData() context.CompileExpression("2147483647 + 1", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) Assert.Equal("(1) : error BC30439: Constant expression not representable in type 'Integer'.", errorMessage) ' As in dev12, the global "unchecked" option is not respected at debug time. Dim uncheckedComp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll.WithOverflowChecks(False)) runtime = CreateRuntimeInstance(uncheckedComp) context = CreateMethodContext(runtime, methodName:="C.M") errorMessage = Nothing context.CompileExpression("2147483647 + 1", resultProperties:=Nothing, [error]:=errorMessage, testData:=Nothing, formatter:=VisualBasicDiagnosticFormatter.Instance) Assert.Equal("(1) : error BC30439: Constant expression not representable in type 'Integer'.", errorMessage) End Sub Public Sub AssignmentConversion() Const source = " Class C Sub M(u As UInteger) End Sub End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, methodName:="C.M") Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() context.CompileAssignment("u", "2147483647 + 1", errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) Assert.Equal("(1) : error BC30439: Constant expression not representable in type 'Integer'.", errorMessage) End Sub Public Sub EvaluateStatement() Dim source = " Class C Sub M() End Sub End Class " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="Throw New System.Exception()", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Equal("(1) : error BC30201: Expression expected.", errorMessage) End Sub Public Sub DateTimeFieldConstant() Dim source = " Class C Const D = #01/02/2010# Sub M() End Sub End Class " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="D", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 15 (0xf) .maxstack 1 IL_0000: ldc.i8 0x8cc5955a94ec000 IL_0009: newobj ""Sub Date..ctor(Long)"" IL_000e: ret } ") End Sub Public Sub DecimalFieldConstant() Dim source = " Class C Const D = 3.14D Sub M() End Sub End Class " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="D", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 15 (0xf) .maxstack 5 IL_0000: ldc.i4 0x13a IL_0005: ldc.i4.0 IL_0006: ldc.i4.0 IL_0007: ldc.i4.0 IL_0008: ldc.i4.2 IL_0009: newobj ""Sub Decimal..ctor(Integer, Integer, Integer, Boolean, Byte)"" IL_000e: ret } ") End Sub Public Sub StaticLambdaInDisplayClass() ' Note: I don't think the VB compiler ever generated code like this, but ' it doesn't hurt to make sure we do the right thing if it did... Dim source = ".class private auto ansi C extends [mscorlib]System.Object { .class auto ansi nested assembly '_Closure$__1' extends [mscorlib]System.Object { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .field public class C $VB$Local_c .field private static class [mscorlib]System.Action`1 '_ClosureCache$__4' .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } .method private hidebysig static void '_Lambda$__2'(int32 x) cil managed { ret } } // Need some static method 'Test' with 'x' in scope. .method private hidebysig static void Test(int32 x) cil managed { ret } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ret } }" Dim exeBytes As ImmutableArray(Of Byte) = Nothing Dim pdbBytes As ImmutableArray(Of Byte) = Nothing EmitILToArray(source, appendDefaultHeader:=True, includePdb:=True, assemblyBytes:=exeBytes, pdbBytes:=pdbBytes) Dim runtime = CreateRuntimeInstance( assemblyName:=ExpressionCompilerUtilities.GenerateUniqueName(), references:=ImmutableArray.Create(MscorlibRef), exeBytes:=exeBytes.ToArray(), symReader:=New SymReader(pdbBytes.ToArray())) Dim context = CreateMethodContext( runtime, methodName:="C._Closure$__1._Lambda$__2") Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties = Nothing Dim testData As New CompilationTestData() context.CompileExpression("x", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 2 (0x2) .maxstack 1 IL_0000: ldarg.0 IL_0001: ret } ") End Sub Public Sub ExtensionMethodInContainingType() Dim source = " Imports System.Runtime.CompilerServices Module Module1 Sub Main() Dim s = ""Extend!"" Dim r = s.Method End Sub Private Function Method(s As String) As Integer Return 1 End Function End Module " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="Module1.Main", expr:="s.Method()", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 7 (0x7) .maxstack 1 .locals init (String V_0, //s Integer V_1) //r IL_0000: ldloc.0 IL_0001: call ""Function Module1.Method(String) As Integer"" IL_0006: ret } ") End Sub Public Sub ExtensionMethodInContainingNamespace() Dim source = " Imports System.Runtime.CompilerServices Module Module1 Sub Main() Dim s = ""Extend!"" Dim r = s.Method End Sub End Module Module Module2 Friend Function Method(s As String) As Integer Return 1 End Function End Module " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="Module1.Main", expr:="s.Method()", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 7 (0x7) .maxstack 1 .locals init (String V_0, //s Integer V_1) //r IL_0000: ldloc.0 IL_0001: call ""Function Module2.Method(String) As Integer"" IL_0006: ret } ") End Sub Public Sub ExtensionMethodInImportedNamespace() Dim source = " Imports System.Runtime.CompilerServices Imports NS1 Module Module1 Sub Main() Dim s = ""Extend!"" Dim r = s.Method End Sub End Module Namespace NS1 Module Module2 Public Function Method(s As String) As Integer Return 1 End Function End Module End Namespace " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="Module1.Main", expr:="s.Method()", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 7 (0x7) .maxstack 1 .locals init (String V_0, //s Integer V_1) //r IL_0000: ldloc.0 IL_0001: call ""Function NS1.Module2.Method(String) As Integer"" IL_0006: ret } ") End Sub Public Sub InaccessibleExtensionMethod() ' EE will be able to access this extension method anyway... Dim source = " Imports System.Runtime.CompilerServices Module Module1 Sub Main() Dim s = ""Extend!"" End Sub End Module Module Module2 Private Function Method(s As String) As Integer Return 1 End Function End Module " Dim errorMessage As String = Nothing Dim resultProperties As ResultProperties Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="Module1.Main", expr:="s.Method()", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 7 (0x7) .maxstack 1 .locals init (String V_0) //s IL_0000: ldloc.0 IL_0001: call ""Function Module2.Method(String) As Integer"" IL_0006: ret } ") End Sub Public Sub ConditionalAccessExpressionType() Dim source = "Class C Function F() As Integer Return 0 End Function Function G() As C Return Nothing End Function Private X As System.Xml.Linq.XElement Sub M() End Sub End Class" Dim allReferences = GetAllXmlReferences() Dim comp = CreateCompilationWithReferences( MakeSources(source), options:=TestOptions.DebugDll, references:=allReferences) Dim exeBytes As Byte() = Nothing Dim pdbBytes As Byte() = Nothing Dim references As ImmutableArray(Of MetadataReference) = Nothing comp.EmitAndGetReferences(exeBytes, pdbBytes, references) Dim runtime = CreateRuntimeInstance( ExpressionCompilerUtilities.GenerateUniqueName(), allReferences, exeBytes, Nothing) Dim context = CreateMethodContext(runtime, "C.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() Dim result = context.CompileExpression("Me?.F()", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) Dim methodData = testData.GetMethodData("<>x.<>m0") Assert.Equal(DirectCast(methodData.Method, MethodSymbol).ReturnType.ToDisplayString(), "Integer?") methodData.VerifyIL( "{ // Code size 25 (0x19) .maxstack 1 .locals init (Integer? V_0) IL_0000: ldarg.0 IL_0001: brtrue.s IL_000d IL_0003: ldloca.s V_0 IL_0005: initobj ""Integer?"" IL_000b: ldloc.0 IL_000c: ret IL_000d: ldarg.0 IL_000e: call ""Function C.F() As Integer"" IL_0013: newobj ""Sub Integer?..ctor(Integer)"" IL_0018: ret }") testData = New CompilationTestData() result = context.CompileExpression("(Me?.F())", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) methodData = testData.GetMethodData("<>x.<>m0") Assert.Equal(DirectCast(methodData.Method, MethodSymbol).ReturnType.ToDisplayString(), "Integer?") testData = New CompilationTestData() result = context.CompileExpression("Me?.X.@a", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) Assert.Null(errorMessage) methodData = testData.GetMethodData("<>x.<>m0") Assert.Equal(DirectCast(methodData.Method, MethodSymbol).ReturnType.SpecialType, SpecialType.System_String) methodData.VerifyIL( "{ // Code size 32 (0x20) .maxstack 3 IL_0000: ldarg.0 IL_0001: brtrue.s IL_0005 IL_0003: ldnull IL_0004: ret IL_0005: ldarg.0 IL_0006: ldfld ""C.X As System.Xml.Linq.XElement"" IL_000b: ldstr ""a"" IL_0010: ldstr """" IL_0015: call ""Function System.Xml.Linq.XName.Get(String, String) As System.Xml.Linq.XName"" IL_001a: call ""Function My.InternalXmlHelper.get_AttributeValue(System.Xml.Linq.XElement, System.Xml.Linq.XName) As String"" IL_001f: ret }") testData = New CompilationTestData() result = context.CompileExpression("(New C())?.G()?.F()", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) methodData = testData.GetMethodData("<>x.<>m0") Assert.Equal(DirectCast(methodData.Method, MethodSymbol).ReturnType.ToDisplayString(), "Integer?") testData = New CompilationTestData() result = context.CompileExpression("(New C())?.G().F()", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) methodData = testData.GetMethodData("<>x.<>m0") Assert.Equal(DirectCast(methodData.Method, MethodSymbol).ReturnType.ToDisplayString(), "Integer?") testData = New CompilationTestData() result = context.CompileExpression("G()?.M()", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) methodData = testData.GetMethodData("<>x.<>m0") Assert.True(DirectCast(methodData.Method, MethodSymbol).IsSub) methodData.VerifyIL( "{ // Code size 17 (0x11) .maxstack 2 IL_0000: ldarg.0 IL_0001: callvirt ""Function C.G() As C"" IL_0006: dup IL_0007: brtrue.s IL_000b IL_0009: pop IL_000a: ret IL_000b: call ""Sub C.M()"" IL_0010: ret }") testData = New CompilationTestData() result = context.CompileExpression("(G()?.M())", resultProperties, errorMessage, testData, VisualBasicDiagnosticFormatter.Instance) Assert.Equal(errorMessage, "(1) : error BC30491: Expression does not produce a value.") End Sub Public Sub IteratorParameters() Const source = " Class C Iterator Function F(x As Integer) As System.Collections.IEnumerable Yield x Yield Me ' Until iterators always capture 'Me', do it explicitly. End Function End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "C.VB$StateMachine_1_F.MoveNext") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() context.CompileExpression("x", resultProperties, errorMessage, testData) Dim methodData = testData.GetMethodData("<>x.<>m0") Assert.Equal(SpecialType.System_Int32, methodData.Method.ReturnType.SpecialType) methodData.VerifyIL(" { // Code size 7 (0x7) .maxstack 1 .locals init (Boolean V_0, Integer V_1) IL_0000: ldarg.0 IL_0001: ldfld ""C.VB$StateMachine_1_F.$VB$Local_x As Integer"" IL_0006: ret } ") End Sub Public Sub IteratorGenericLocal() Const source = " Class C(Of T) Iterator Function F(x As Integer) As System.Collections.IEnumerable Dim t1 As T = Nothing Yield t1 t1.ToString() Yield Me ' Until iterators always capture 'Me', do it explicitly. End Function End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "C.VB$StateMachine_1_F.MoveNext") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() context.CompileExpression("x", resultProperties, errorMessage, testData) Dim methodData = testData.GetMethodData("<>x(Of T).<>m0") Assert.Equal(SpecialType.System_Int32, methodData.Method.ReturnType.SpecialType) methodData.VerifyIL(" { // Code size 7 (0x7) .maxstack 1 .locals init (Boolean V_0, Integer V_1) IL_0000: ldarg.0 IL_0001: ldfld ""C(Of T).VB$StateMachine_1_F.$VB$Local_x As Integer"" IL_0006: ret } ") End Sub Public Sub SharedDelegate_Class() Const source = " Delegate Sub D() Class C Shared Sub F() End Sub Shared Sub G(d1 As D) End Sub Shared Sub M() End Sub End Class " Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="G(AddressOf F)") testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 18 (0x12) .maxstack 2 IL_0000: ldnull IL_0001: ldftn ""Sub C.F()"" IL_0007: newobj ""Sub D..ctor(Object, System.IntPtr)"" IL_000c: call ""Sub C.G(D)"" IL_0011: ret } ") End Sub Public Sub SharedDelegate_Structure() Const source = " Delegate Sub D() Structure S Shared Sub F() End Sub Shared Sub G(d1 As D) End Sub Shared Sub M() End Sub End Structure " Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="S.M", expr:="G(AddressOf F)") testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 18 (0x12) .maxstack 2 IL_0000: ldnull IL_0001: ldftn ""Sub S.F()"" IL_0007: newobj ""Sub D..ctor(Object, System.IntPtr)"" IL_000c: call ""Sub S.G(D)"" IL_0011: ret } ") End Sub Public Sub RangeVariableError() Const source = "Class C Shared Sub M() End Sub End Class" Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = Evaluate( source, OutputKind.DynamicallyLinkedLibrary, methodName:="C.M", expr:="From c in ""ABC"" Select c", resultProperties:=resultProperties, errorMessage:=errorMessage) Assert.Equal("(1) : error BC36593: Expression of type 'String' is not queryable. Make sure you are not missing an assembly reference and/or namespace import for the LINQ provider.", errorMessage) End Sub Public Sub Bug1079762() Const source = " Class C Shared Sub F(f1 As System.Func(Of Object, Boolean), o As Object) f1(o) End Sub Shared Sub M(x As Object, y As Object) F(Function(z) z IsNot Nothing AndAlso x IsNot Nothing, 3) End Sub End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll, assemblyName:=GetUniqueName()) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "C._Closure$__2-0._Lambda$__0") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() context.CompileExpression("z", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 2 (0x2) .maxstack 1 .locals init (Boolean V_0) IL_0000: ldarg.1 IL_0001: ret } ") testData = New CompilationTestData() context.CompileExpression("y", resultProperties, errorMessage, testData) Assert.Equal("(1,2): error BC30451: 'y' is not declared. It may be inaccessible due to its protection level.", errorMessage) End Sub Public Sub NonStateMachineTypeParameter() Const source = " Imports System.Collections.Generic Class C Shared Function I(Of T)(array As T()) As IEnumerable(Of T) return array End Function End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll, assemblyName:=GetUniqueName()) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "C.I") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() context.CompileExpression("GetType(T)", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 11 (0xb) .maxstack 1 .locals init (System.Collections.Generic.IEnumerable(Of T) V_0) //I IL_0000: ldtoken ""T"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ret } ") End Sub Public Sub StateMachineTypeParameter() Const source = " Imports System.Collections.Generic Class C Shared Iterator Function I(Of T)(array As T()) As IEnumerable(Of T) For Each a in array Yield a Next End Function End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll, assemblyName:=GetUniqueName()) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "C.VB$StateMachine_1_I.MoveNext") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() context.CompileExpression("GetType(T)", resultProperties, errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x(Of T).<>m0").VerifyIL(" { // Code size 11 (0xb) .maxstack 1 .locals init (Boolean V_0, Integer V_1, Boolean V_2) IL_0000: ldtoken ""T"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ret } ") End Sub Public Sub ModuleWithBadImageFormat() Dim source = " Class C Dim F As Integer = 1 Shared Sub M() End Sub End Class" Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll, assemblyName:=GetUniqueName()) Dim exeBytes() As Byte = Nothing Dim pdbBytes() As Byte = Nothing Dim references As ImmutableArray(Of MetadataReference) = Nothing comp.EmitAndGetReferences(exeBytes, pdbBytes, references) Dim exeReference = AssemblyMetadata.CreateFromImage(exeBytes).GetReference(display:=Guid.NewGuid().ToString("D")) Dim modulesBuilder = ArrayBuilder(Of ModuleInstance).GetInstance() Dim corruptMetadata = New ModuleInstance( metadataReference:=Nothing, moduleMetadata:=Nothing, moduleVersionId:=Nothing, fullImage:=Nothing, metadataOnly:=CommonResources.NoValidTables, symReader:=Nothing, includeLocalSignatures:=False) modulesBuilder.Add(corruptMetadata) modulesBuilder.Add(exeReference.ToModuleInstance(exeBytes, New SymReader(pdbBytes))) modulesBuilder.AddRange(references.Select(Function(r) r.ToModuleInstance(fullImage:=Nothing, symReader:=Nothing))) Dim modules = modulesBuilder.ToImmutableAndFree() Using runtime = New RuntimeInstance(modules) Dim context = CreateMethodContext(runtime, "C.M") Dim resultProperties As ResultProperties Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() ' Verify that we can still evaluate expressions for modules that are not corrupt. context.CompileExpression("(new C()).F", resultProperties, errorMessage, testData) Assert.Null(errorMessage) Assert.Equal(DkmClrCompilationResultFlags.None, resultProperties.Flags) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 11 (0xb) .maxstack 1 IL_0000: newobj ""Sub C..ctor()"" IL_0005: ldfld ""C.F As Integer"" IL_000a: ret }") End Using End Sub Public Sub MissingType() Const libSource = " Public Class Missing End Class " Const source = " Public Class C Public field As Missing Public Sub M(parameter As Missing) Dim local As Missing End Sub End Class " Dim libRef = CreateCompilationWithMscorlib({libSource}, assemblyName:="Lib", compOptions:=TestOptions.DebugDll).EmitToImageReference() Dim comp = CreateCompilationWithReferences({VisualBasicSyntaxTree.ParseText(source)}, {MscorlibRef, libRef}, TestOptions.DebugDll) Dim exeBytes As Byte() = Nothing Dim pdbBytes As Byte() = Nothing Dim unusedReferences As ImmutableArray(Of MetadataReference) = Nothing Dim result = comp.EmitAndGetReferences(exeBytes, pdbBytes, unusedReferences) Assert.True(result) Dim runtime = CreateRuntimeInstance(GetUniqueName(), ImmutableArray.Create(MscorlibRef), exeBytes, New SymReader(pdbBytes)) Dim context = CreateMethodContext(runtime, "C.M") Const expectedError1 = "(1,1): error BC30652: Reference required to assembly 'Lib, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' containing the type 'Missing'. Add one to your project." Const expectedError2 = "(1,2): error BC30652: Reference required to assembly 'Lib, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' containing the type 'Missing'. Add one to your project." Dim expectedMissingAssemblyIdentity As New AssemblyIdentity("Lib") Dim resultProperties As ResultProperties = Nothing Dim actualError As String = Nothing Dim actualMissingAssemblyIdentities As ImmutableArray(Of AssemblyIdentity) = Nothing Dim verify As Action(Of String, String) = Sub(expr, expectedError) context.CompileExpression( DefaultInspectionContext.Instance, expr, DkmEvaluationFlags.TreatAsExpression, DiagnosticFormatter.Instance, resultProperties, actualError, actualMissingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData:=Nothing) Assert.Equal(expectedError, actualError) Assert.Equal(expectedMissingAssemblyIdentity, actualMissingAssemblyIdentities.Single()) End Sub verify("M(Nothing)", expectedError2) verify("field", expectedError2) verify("field.Method", expectedError2) verify("parameter", expectedError1) verify("parameter.Method", expectedError1) verify("local", expectedError1) verify("local.Method", expectedError1) ' Note that even expressions that don't required the missing type will fail because ' the method we synthesize refers to the original locals and parameters. verify("0", expectedError1) End Sub Public Sub ObsoleteAttribute() Const source = " Imports System Imports System.Diagnostics Class C Shared Sub Main() Dim c As New C() End Sub Property P() As Integer End Class " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "C.Main") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing context.CompileExpression("c.P", resultProperties, errorMessage) Assert.Null(errorMessage) End Sub Public Sub DeprecatedAttribute() Const source = " Imports System Imports Windows.Foundation.Metadata Class C Shared Sub Main() Dim c As New C() End Sub Property P() As Integer End Class Namespace Windows.Foundation.Metadata Public NotInheritable Class DeprecatedAttribute : Inherits Attribute Public Sub New(message As String, dtype As DeprecationType, version As UInteger) End Sub Public Sub New(message As String, dtype As DeprecationType, version As UInteger, contract As Type) End Sub End Class Public Enum DeprecationType Deprecate = 0 Remove = 1 End Enum End Namespace " Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "C.Main") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing context.CompileExpression("c.P", resultProperties, errorMessage) Assert.Null(errorMessage) End Sub Public Sub BadPdb_MissingMethod() Const source = " Public Class C Public Shared Sub Main() End Sub End Class " Dim comp = CreateCompilationWithMscorlib({source}) Dim exeBytes As Byte() = Nothing Dim unusedPdbBytes As Byte() = Nothing Dim references As ImmutableArray(Of MetadataReference) = Nothing Dim result = comp.EmitAndGetReferences(exeBytes, unusedPdbBytes, references) Assert.True(result) Dim symReader As ISymUnmanagedReader = New MockSymUnmanagedReader(ImmutableDictionary(Of Integer, MethodDebugInfoBytes).Empty) Dim runtime = CreateRuntimeInstance("assemblyName", references, exeBytes, symReader) Dim evalContext = CreateMethodContext(runtime, "C.Main") Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() evalContext.CompileExpression("1", errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 2 (0x2) .maxstack 1 IL_0000: ldc.i4.1 IL_0001: ret } ") End Sub Public Sub SymUnmanagedReaderNotImplemented() Const source = " Public Class C Public Shared Sub Main() End Sub End Class " Dim comp = CreateCompilationWithMscorlib({source}) Dim exeBytes As Byte() = Nothing Dim unusedPdbBytes As Byte() = Nothing Dim references As ImmutableArray(Of MetadataReference) = Nothing Dim result = comp.EmitAndGetReferences(exeBytes, unusedPdbBytes, references) Assert.True(result) Dim runtime = CreateRuntimeInstance("assemblyName", references, exeBytes, NotImplementedSymUnmanagedReader.Instance) Dim evalContext = CreateMethodContext(runtime, "C.Main") Dim errorMessage As String = Nothing Dim testData As New CompilationTestData() evalContext.CompileExpression("1", errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 2 (0x2) .maxstack 1 IL_0000: ldc.i4.1 IL_0001: ret } ") End Sub Public Sub WithExpression() Const source = "Structure S Friend F As T End Structure Structure T End Structure Class C Shared Sub F(o As System.Action) End Sub Shared Sub M() End Sub End Class" Dim comp = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll, assemblyName:=ExpressionCompilerUtilities.GenerateUniqueName()) Dim runtime = CreateRuntimeInstance(comp) Dim context = CreateMethodContext(runtime, "C.M") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim missingAssemblyIdentities As ImmutableArray(Of AssemblyIdentity) = Nothing Dim testData = New CompilationTestData() context.CompileExpression( InspectionContextFactory.Empty, "F(Sub() Dim o = New S() With o .F = New T() With .F End With End With End Sub)", DkmEvaluationFlags.None, DiagnosticFormatter.Instance, resultProperties, errorMessage, missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData) Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x._Closure$__._Lambda$__0-1").VerifyIL( "{ ... }") End Sub Sub MethodTypeParameterInLambda() Const source = " Class C(Of T) Sub M(Of U)() Dim lambda = Function(u1 As U) As Integer Return u1.GetHashCode() End Function Dim result = lambda(Nothing) End Sub End Class" Dim compilation = CreateCompilationWithMscorlib45AndVBRuntime(MakeSources(source), options:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(compilation) Dim context = CreateMethodContext(runtime, "C._Closure$__1._Lambda$__1-0") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() Dim result = context.CompileExpression("GetType(T)", errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x(Of T, $CLS0).<>m0").VerifyIL(" { // Code size 11 (0xb) .maxstack 1 .locals init (Integer V_0) IL_0000: ldtoken ""T"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ret }") ' As in dev12, there is no way to bind "U" to the method type parameter. ' In particular, there is no way to map back from the lambda to the method ' that declares it to determine the source name of the type parameter ' (which is also not deducible from the mangled form). testData = New CompilationTestData() result = context.CompileExpression("GetType(U)", errorMessage, testData) Assert.Equal("(1,10): error BC30002: Type 'U' is not defined.", errorMessage) ' Sufficiently well-informed users can reference the type parameter using ' its mangled name. testData = New CompilationTestData() result = context.CompileExpression("GetType($CLS0)", errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x(Of T, $CLS0).<>m0").VerifyIL(" { // Code size 11 (0xb) .maxstack 1 .locals init (Integer V_0) IL_0000: ldtoken ""$CLS0"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ret }") End Sub Sub EvaluateLocalInAsyncLambda() Const source = " Imports System.Threading.Tasks Module Module1 Sub Main() Dim GetIntegerAsync = Async Function() As Task(Of Integer) Dim i = 42 Return i End Function Dim result = GetIntegerAsync() End Sub End Module" Dim compilation = CreateCompilationWithMscorlib45AndVBRuntime(MakeSources(source), options:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(compilation) Dim context = CreateMethodContext(runtime, "Module1._Closure$__.VB$StateMachine___Lambda$__0-1.MoveNext") Dim resultProperties As ResultProperties = Nothing Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() Dim result = context.CompileExpression("i", errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 7 (0x7) .maxstack 1 .locals init (Integer V_0, //$VB$ResumableLocal_i$0 Integer V_1, System.Threading.Tasks.Task(Of Integer) V_2, System.Exception V_3) IL_0000: ldarg.0 IL_0001: ldfld ""Module1._Closure$__.VB$StateMachine___Lambda$__0-1.$VB$ResumableLocal_i$0 As Integer"" IL_0006: ret }") End Sub Public Sub GetTypeOpenGenericType() Dim source = " Imports System Class C Sub M() End Sub End Class" Dim compilation = CreateCompilationWithMscorlib({source}, compOptions:=TestOptions.DebugDll) Dim runtime = CreateRuntimeInstance(compilation) Dim context = CreateMethodContext(runtime, "C.M") Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileExpression("GetType(Action(Of ))", errorMessage, testData) Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL(" { // Code size 11 (0xb) .maxstack 1 IL_0000: ldtoken ""System.Action(Of T)"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ret }") End Sub End Class End Namespace