' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.

Imports System.Collections.Immutable
Imports System.Runtime.InteropServices
Imports Microsoft.CodeAnalysis.CodeGen
Imports Microsoft.CodeAnalysis.ExpressionEvaluator
Imports Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests
Imports Microsoft.CodeAnalysis.VisualBasic.UnitTests
Imports Microsoft.VisualStudio.Debugger.Evaluation
Imports Roslyn.Test.Utilities
Imports Xunit

Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator.UnitTests

    Public Class StatementTests
        Inherits ExpressionCompilerTestBase

        <Fact>
        Public Sub AddAssignmentStatement()
            Const source = "
Class C
    Sub M()
        Dim d As Double = 0
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="d += 1.1",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size       13 (0xd)
  .maxstack  2
  .locals init (Double V_0) //d
  IL_0000:  ldloc.0
  IL_0001:  ldc.r8     1.1
  IL_000a:  add
  IL_000b:  stloc.0
  IL_000c:  ret
}
")
        End Sub

        <Fact>
        Public Sub AddHandlerStatement()
            Const source = "
Class C
    Event a()
    Sub M()
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="  AddHandler a, AddressOf System.Console.WriteLine",
                errorMessage:=errorMessage)

            'Statements of type 'AddHandlerStatement' are not allowed in the Immediate window.
            Assert.Equal(String.Format(ExpressionEvaluator.Resources.InvalidDebuggerStatement, SyntaxKind.AddHandlerStatement), errorMessage)
        End Sub

        <Fact>
        Public Sub ArrayAccess()
            Const source = "
Module Module1
    Sub Main(args() As String)
    End Sub
End Module
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="Module1.Main",
                expr:="args(1)",
                errorMessage:=errorMessage)
            Assert.Equal("error BC30454: Expression is not a method.", errorMessage)

            testData = EvaluateStatement(
                source,
                methodName:="Module1.Main",
                expr:="args(1) = ""Hi""",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size        9 (0x9)
  .maxstack  3
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  ldstr      ""Hi""
  IL_0007:  stelem.ref
  IL_0008:  ret
}
")

            testData = EvaluateStatement(
                source,
                methodName:="Module1.Main",
                expr:="?args(1)",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size        4 (0x4)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  ldelem.ref
  IL_0003:  ret
}
")

            testData = EvaluateStatement(
                source,
                methodName:="Module1.Main",
                expr:="?args(1) = ""Hi""",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size       18 (0x12)
  .maxstack  3
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  ldelem.ref
  IL_0003:  ldstr      ""Hi""
  IL_0008:  ldc.i4.0
  IL_0009:  call       ""Function Microsoft.VisualBasic.CompilerServices.Operators.CompareString(String, String, Boolean) As Integer""
  IL_000e:  ldc.i4.0
  IL_000f:  ceq
  IL_0011:  ret
}
")
        End Sub

        <Fact>
        Public Sub CallStatement()
            Const source = "
Class C
    Private member As Integer = 1
    Public Sub Increment()
        member += 1
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.Increment",
                expr:="Call (New C).Increment()",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size       11 (0xb)
  .maxstack  1
  .locals init (Integer& V_0)
  IL_0000:  newobj     ""Sub C..ctor()""
  IL_0005:  call       ""Sub C.Increment()""
  IL_000a:  ret
}
")
        End Sub

        <Fact>
        Public Sub ConcatenateAssignmentStatement()
            Const source = "
Module Module1
    Sub M()
        Dim s As String = ""a""
    End Sub
End Module
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="Module1.M",
                expr:="s &= 1",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size       14 (0xe)
  .maxstack  2
  .locals init (String V_0) //s
  IL_0000:  ldloc.0
  IL_0001:  ldc.i4.1
  IL_0002:  call       ""Function Microsoft.VisualBasic.CompilerServices.Conversions.ToString(Integer) As String""
  IL_0007:  call       ""Function String.Concat(String, String) As String""
  IL_000c:  stloc.0
  IL_000d:  ret
}
")
        End Sub

        <Fact>
        Public Sub DivideAssignmentStatement()
            Const source = "
Class C
    Sub M()
        Dim b As Byte = 1
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="b /= 0",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size       20 (0x14)
  .maxstack  2
  .locals init (Byte V_0) //b
  IL_0000:  ldloc.0
  IL_0001:  conv.r8
  IL_0002:  ldc.r8     0
  IL_000b:  div
  IL_000c:  call       ""Function System.Math.Round(Double) As Double""
  IL_0011:  conv.ovf.u1
  IL_0012:  stloc.0
  IL_0013:  ret
}
")
        End Sub

        <Fact>
        Public Sub EmptyStatement()
            Const source = "
Class C
    Sub M()
    End Sub
End Class
"
            ' We should never hit this case in the VS scenario, but testing to make
            ' sure we do something reasonable if we ever did.
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="",
                errorMessage:=errorMessage)

            'Statements of type 'EmptyStatement' are not allowed in the Immediate window.
            Assert.Equal(String.Format(ExpressionEvaluator.Resources.InvalidDebuggerStatement, SyntaxKind.EmptyStatement), errorMessage)
        End Sub

        <Fact>
        Public Sub EndStatement()
            Const source = "
Class C
    Sub M()
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="End",
                errorMessage:=errorMessage)

            'Statements of type 'EndStatement' are not allowed in the Immediate window.
            Assert.Equal(String.Format(ExpressionEvaluator.Resources.InvalidDebuggerStatement, SyntaxKind.EndStatement), errorMessage)
        End Sub

        <Fact>
        Public Sub ExponentiateAssignmentStatement()
            Const source = "
Class C
    Sub M()
        Dim m As Decimal
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="m ^= 2",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size       28 (0x1c)
  .maxstack  3
  .locals init (Decimal V_0) //m
  IL_0000:  ldloca.s   V_0
  IL_0002:  ldloc.0
  IL_0003:  call       ""Function System.Convert.ToDouble(Decimal) As Double""
  IL_0008:  ldc.r8     2
  IL_0011:  call       ""Function System.Math.Pow(Double, Double) As Double""
  IL_0016:  call       ""Sub Decimal..ctor(Double)""
  IL_001b:  ret
}
")
        End Sub

        <Fact>
        Public Sub ExpressionStatement()
            Const source = "
Class C
    Public Sub M()
        Dim x As Integer = 1
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="System.Console.WriteLine()",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size        6 (0x6)
  .maxstack  0
  .locals init (Integer V_0) //x
  IL_0000:  call       ""Sub System.Console.WriteLine()""
  IL_0005:  ret
}
")

            testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="System.Console.Read()",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size        7 (0x7)
  .maxstack  1
  .locals init (Integer V_0) //x
  IL_0000:  call       ""Function System.Console.Read() As Integer""
  IL_0005:  pop
  IL_0006:  ret
}
")

            testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="x",
                errorMessage:=errorMessage)
            Assert.Equal("error BC30454: Expression is not a method.", errorMessage)
        End Sub

        <Fact>
        Public Sub IfStatement()
            Const source = "
Class C
    Sub M()
        Dim x As Integer = 0
    End Sub
End Class
"
            ' The old EE used to support single-line If statements, but Roslyn does not.  This is because Parser.ParseStatementInMethodBody
            ' does directly handle the single-line case. If we end up needing to support single-line if, then we either need to fix parsing
            ' of single-line Ifs in ParseStatementInMethodBody (ADGreen knows more), or we need to duplicate the parser logic for handling
            ' them in the EE.
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="  If True Then x = 1",
                errorMessage:=errorMessage)
            Assert.Equal("error BC30035: Syntax error.", errorMessage)

            testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="  If True Then x = 1 Else x = 2",
                errorMessage:=errorMessage)
            Assert.Equal("error BC30035: Syntax error.", errorMessage)
        End Sub

        <Fact>
        Public Sub IntegerDivideAssignmentStatement()
            Const source = "
Class C
    Sub M()
        Dim odd As UInteger
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="odd \= 2",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size        8 (0x8)
  .maxstack  2
  .locals init (UInteger V_0) //odd
  IL_0000:  ldloc.0
  IL_0001:  conv.u8
  IL_0002:  ldc.i4.2
  IL_0003:  conv.i8
  IL_0004:  div
  IL_0005:  conv.ovf.u4
  IL_0006:  stloc.0
  IL_0007:  ret
}
")
        End Sub

        <Fact>
        Public Sub LeftShiftAssignmentStatement()
            Const source = "
Class C
    Sub M()
        Dim s As Short
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="s <<= 16",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size       10 (0xa)
  .maxstack  3
  .locals init (Short V_0) //s
  IL_0000:  ldloc.0
  IL_0001:  ldc.i4.s   16
  IL_0003:  ldc.i4.s   15
  IL_0005:  and
  IL_0006:  shl
  IL_0007:  conv.i2
  IL_0008:  stloc.0
  IL_0009:  ret
}
")
        End Sub

        <Fact>
        Public Sub MultiplyAssignmentStatement()
            Const source = "
Class C
    Sub M()
        Dim l As ULong
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="l *= l",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size        5 (0x5)
  .maxstack  2
  .locals init (ULong V_0) //l
  IL_0000:  ldloc.0
  IL_0001:  ldloc.0
  IL_0002:  mul.ovf.un
  IL_0003:  stloc.0
  IL_0004:  ret
}
")
        End Sub

        <Fact>
        Public Sub OnErrorResumeNextStatement()
            Const source = "
Class C
    Sub M()
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="On Error Resume Next",
                errorMessage:=errorMessage)

            'Statements of type 'OnErrorResumeNextStatement' are not allowed in the Immediate window.
            Assert.Equal(String.Format(ExpressionEvaluator.Resources.InvalidDebuggerStatement, SyntaxKind.OnErrorResumeNextStatement), errorMessage)
        End Sub

        <Fact>
        Public Sub PrintStatement()
            Const source = "
Class C
    Public Sub M()
        Dim x As Integer = 1
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="?x = 1",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size        5 (0x5)
  .maxstack  2
  .locals init (Integer V_0) //x
  IL_0000:  ldloc.0
  IL_0001:  ldc.i4.1
  IL_0002:  ceq
  IL_0004:  ret
}
")

            ' We should never hit this case in the VS scenario, but testing to make
            ' sure we do something reasonable if we ever did.
            testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="? ",
                errorMessage:=errorMessage)
            Assert.Equal("error BC30201: Expression expected.", errorMessage)

            testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="??x = 1",
                errorMessage:=errorMessage)
            Assert.Equal("error BC30201: Expression expected.", errorMessage)

            testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="?System.Console.WriteLine()",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size        6 (0x6)
  .maxstack  0
  .locals init (Integer V_0) //x
  IL_0000:  call       ""Sub System.Console.WriteLine()""
  IL_0005:  ret
}
")

            testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="?System.Console.Read()",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size        6 (0x6)
  .maxstack  1
  .locals init (Integer V_0) //x
  IL_0000:  call       ""Function System.Console.Read() As Integer""
  IL_0005:  ret
}
")

            testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="?AddressOf System.Console.WriteLine",
                errorMessage:=errorMessage)
            Assert.Equal("error BC30491: Expression does not produce a value.", errorMessage)

            testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="?x += 1",
                errorMessage:=errorMessage)
            Assert.Equal("error BC37237: '+=' is not a valid format specifier", errorMessage) ' not the best error, but not worth modifying parsing to improve...
        End Sub

        <Fact>
        Public Sub RedimStatement()
            Const source = "
Class C
    Public Sub M()
        Dim a(1) As Integer
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="ReDim a(2), a(3)",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size       15 (0xf)
  .maxstack  1
  .locals init (Integer() V_0) //a
  IL_0000:  ldc.i4.3
  IL_0001:  newarr     ""Integer""
  IL_0006:  stloc.0
  IL_0007:  ldc.i4.4
  IL_0008:  newarr     ""Integer""
  IL_000d:  stloc.0
  IL_000e:  ret
}
")
            testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="?ReDim a(2), a(3)",
                errorMessage:=errorMessage)
            Assert.Equal("error BC30201: Expression expected.", errorMessage)
        End Sub

        <Fact>
        Public Sub RedimPreserveStatement()
            Const source = "
Module Module1
    Public Sub M()
        Dim a(1) As Integer
    End Sub
End Module
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="Module1.M",
                expr:="ReDim Preserve a(2)",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size       19 (0x13)
  .maxstack  2
  .locals init (Integer() V_0) //a
  IL_0000:  ldloc.0
  IL_0001:  ldc.i4.3
  IL_0002:  newarr     ""Integer""
  IL_0007:  call       ""Function Microsoft.VisualBasic.CompilerServices.Utils.CopyArray(System.Array, System.Array) As System.Array""
  IL_000c:  castclass  ""Integer()""
  IL_0011:  stloc.0
  IL_0012:  ret
}
")
        End Sub

        <Fact>
        Public Sub RightShiftAssignmentStatement()
            Const source = "
Class C
    Sub M()
        Dim u As UShort = &H8000
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="u >>= &H1",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size        6 (0x6)
  .maxstack  2
  .locals init (UShort V_0) //u
  IL_0000:  ldloc.0
  IL_0001:  ldc.i4.1
  IL_0002:  shr.un
  IL_0003:  conv.u2
  IL_0004:  stloc.0
  IL_0005:  ret
}
")
        End Sub

        <Fact>
        Public Sub SimpleAssignmentStatement()
            Const source = "
Class C
    Private field As Integer = 1
    Property Prop As C
    Public Sub M()
        Dim c1 As New C()
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="field = 2",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size        8 (0x8)
  .maxstack  2
  .locals init (C V_0) //c1
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.2
  IL_0002:  stfld      ""C.field As Integer""
  IL_0007:  ret
}
")
            testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="c1.Prop.field = 2",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size       13 (0xd)
  .maxstack  2
  .locals init (C V_0) //c1
  IL_0000:  ldloc.0
  IL_0001:  callvirt   ""Function C.get_Prop() As C""
  IL_0006:  ldc.i4.2
  IL_0007:  stfld      ""C.field As Integer""
  IL_000c:  ret
}
")
        End Sub

        <Fact>
        Public Sub StopStatement()
            Const source = "
Class C
    Sub M()
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="Stop",
                errorMessage:=errorMessage)

            'Statements of type 'StopStatement' are not allowed in the Immediate window.
            Assert.Equal(String.Format(ExpressionEvaluator.Resources.InvalidDebuggerStatement, SyntaxKind.StopStatement), errorMessage)
        End Sub

        <Fact>
        Public Sub SubtractAssignmentStatement()
            Const source = "
Class C
    Property D As Decimal
    Sub M()
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="d -= 3.14159D",
                errorMessage:=errorMessage)
            Assert.Null(errorMessage)
            testData.GetMethodData("<>x.<>m0").VerifyIL("
{
  // Code size       34 (0x22)
  .maxstack  7
  .locals init (C V_0)
  IL_0000:  ldarg.0
  IL_0001:  dup
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  callvirt   ""Function C.get_D() As Decimal""
  IL_0009:  ldc.i4     0x4cb2f
  IL_000e:  ldc.i4.0
  IL_000f:  ldc.i4.0
  IL_0010:  ldc.i4.0
  IL_0011:  ldc.i4.5
  IL_0012:  newobj     ""Sub Decimal..ctor(Integer, Integer, Integer, Boolean, Byte)""
  IL_0017:  call       ""Function Decimal.Subtract(Decimal, Decimal) As Decimal""
  IL_001c:  callvirt   ""Sub C.set_D(Decimal)""
  IL_0021:  ret
}
")
        End Sub

        <Fact>
        Public Sub WhileStatement()
            Const source = "
Class C
    Sub M()
    End Sub
End Class
"
            Dim errorMessage As String = Nothing
            Dim testData = EvaluateStatement(
                source,
                methodName:="C.M",
                expr:="  While True :: End While",
                errorMessage:=errorMessage)
            Assert.Equal("error BC30035: Syntax error.", errorMessage) ' not the best error, but not worth modifying parsing to improve...
        End Sub

        Private Function EvaluateStatement(source As String, methodName As String, expr As String, <Out> ByRef errorMessage As String, Optional atLineNumber As Integer = -1) As CompilationTestData
            Dim compilationFlags = DkmEvaluationFlags.None
            If expr IsNot Nothing AndAlso expr.StartsWith("?", StringComparison.Ordinal) Then
                ' This mimics Immediate Window behavior...
                compilationFlags = DkmEvaluationFlags.TreatAsExpression
                expr = expr.Substring(1)
            End If
            Dim compilation0 = CreateEmptyCompilationWithReferences(
                {Parse(source)},
                {MscorlibRef_v4_0_30316_17626, SystemRef, MsvbRef},
                options:=TestOptions.DebugDll)
            Dim runtime = CreateRuntimeInstance(compilation0)
            Dim context = CreateMethodContext(runtime, methodName, atLineNumber)
            Dim testData = New CompilationTestData()
            Dim resultProperties As ResultProperties = Nothing
            Dim missingAssemblyIdentities As ImmutableArray(Of AssemblyIdentity) = Nothing
            Dim result = context.CompileExpression(
                    expr,
                    compilationFlags,
                    NoAliases,
                    DebuggerDiagnosticFormatter.Instance,
                    resultProperties,
                    errorMessage,
                    missingAssemblyIdentities,
                    EnsureEnglishUICulture.PreferredOrNull,
                    testData)
            Assert.Empty(missingAssemblyIdentities)
            Return testData
        End Function

    End Class

End Namespace
