' 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 Microsoft.CodeAnalysis.Test.Utilities Imports Roslyn.Test.Utilities Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests Public Class CodeGenMulti_dimentional Inherits BasicTestBase Public Sub MultidimendionalArrayCreateWithInitializer() CompileAndVerify( public Module A Public Sub Main() Dim arr As Integer(,) = New Integer(1, 2) {{1, 2, 3}, {1, 2, 3}} System.Console.Write(arr(1, 1)) End Sub End Module , options:=TestOptions.ReleaseExe.WithModuleName("MODULE"), expectedOutput:="2"). VerifyIL("A.Main", .__StaticArrayInitTypeSize=24 .D64E555B758C5B66DFAC42F18587BB1B3C9BCFA8" IL_000d: call "Sub System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)" IL_0012: ldc.i4.1 IL_0013: ldc.i4.1 IL_0014: call "Integer(*,*).Get" IL_0019: call "Sub System.Console.Write(Integer)" IL_001e: ret } ]]>) End Sub Public Sub MultidimendionalArrayCreateWithInitializer001() CompileAndVerify( public Module A Public Sub Main() Dim arr As Integer(,) = New Integer(1, 2) {{1, 2, 3}, {1, Integer.Parse("42"), 3}} System.Console.Write(arr(1, 1)) End Sub End Module , options:=TestOptions.ReleaseExe.WithModuleName("MODULE"), expectedOutput:="42"). VerifyIL("A.Main", .__StaticArrayInitTypeSize=24 .A4B74E064E285570B3499538C5B205C3D0972FDF" IL_000d: call "Sub System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)" IL_0012: dup IL_0013: ldc.i4.1 IL_0014: ldc.i4.1 IL_0015: ldstr "42" IL_001a: call "Function Integer.Parse(String) As Integer" IL_001f: call "Integer(*,*).Set" IL_0024: ldc.i4.1 IL_0025: ldc.i4.1 IL_0026: call "Integer(*,*).Get" IL_002b: call "Sub System.Console.Write(Integer)" IL_0030: ret } ]]>) End Sub Public Sub MultidimendionalArrayCreateWithInitializer002() CompileAndVerify( public Module A Public Sub Main() Dim arr As Integer(,) = New Integer(1, 2) {{Integer.Parse("1"), Integer.Parse("2"), Integer.Parse("3")}, {Integer.Parse("4"), Integer.Parse("5"), Integer.Parse("6")}} System.Console.Write(arr(1, 1)) End Sub End Module , expectedOutput:="5"). VerifyIL("A.Main", ) End Sub Public Sub MultidimendionalArrayCreateWithInitializer003() CompileAndVerify( Public Module A Public Sub Main() Dim arr As Integer(,) = New Integer(1, -1) {{}, {}} System.Console.Write(arr.Length) End Sub End Module , expectedOutput:="0"). VerifyIL("A.Main", ) End Sub Public Sub MultidimendionalArrayCreateWithInitializer004() CompileAndVerify( Public Module A Public Sub Main() Dim arr As Integer(,) = New Integer(-1, -1) {} System.Console.Write(arr.Length) End Sub End Module , expectedOutput:="0"). VerifyIL("A.Main", ) End Sub Public Sub MultidimendionalArrayCreate() CompileAndVerify( public Module A Public Sub Main() Dim arr As Integer(,) = New Integer(1,2) {} System.Console.Write(arr.Length) End Sub End Module , expectedOutput:="6"). VerifyIL("A.Main", ) End Sub Public Sub MultidimendionalArrayCreateGeneric() CompileAndVerify( public Module A Public Sub Main() foo(Of String)() c1(Of Long).foo() End Sub Class c1(Of T) Public Shared Sub foo() Dim arr As T(,) = New T(1, 2) {} System.Console.Write(arr.Length) End Sub End Class Public Sub foo(Of T)() Dim arr As T(,) = New T(1, 2) {} System.Console.Write(arr.Length) End Sub End Module , expectedOutput:="66"). VerifyIL("A.foo(Of T)()", ) End Sub Public Sub MultidimendionalArrayGetSetAddress() CompileAndVerify( public Module A Public Sub Main() foo(Of String)("hello") c1(Of Long).foo(123) End Sub Class c1(Of T) Public Shared Sub foo(e as T) Dim arr As T(,) = New T(2, 3) {} arr(1, 2) = e System.Console.Write(arr(1, 2).ToString) Dim v as T = arr(1, 2) System.Console.Write(v.ToString) End Sub End Class Public Sub foo(Of T)(e as T) Dim arr As T(,) = New T(2, 3) {} arr(1, 2) = e System.Console.Write(arr(1, 2).ToString) Dim v as T = arr(1, 2) System.Console.Write(v.ToString) End Sub End Module , expectedOutput:="hellohello123123"). VerifyIL("A.foo(Of T)(T)", ) End Sub Public Sub MixMultiAndJaggedArray() CompileAndVerify( Imports System Module Module1 Sub Main() Dim x = New Exception(,,) {} Dim y = New Exception(,,) {{{}}} Dim z = New Exception(,)() {} End Sub End Module ).VerifyDiagnostics() End Sub ' Declaration multi- dimensional array Public Sub DeclarationmultiDimensionalArray() CompileAndVerify( Imports System Module Module1 Sub Main() Dim myArray1 As Integer(,) = New Integer(-1, -1) {} Dim myArray2 As Integer(,) = New Integer(3, 1) {} Dim myArray3 As Integer(,,) = New Integer(3, 1, 2) {} Dim myArray4 As Integer(,) = New Integer(2147483646, 2147483646) {} Dim myArray5 As Integer(,) = New Integer(2147483648UI - 1, 2147483648UI - 1) {} End Sub End Module ).VerifyIL("Module1.Main", ) End Sub ' Declaration multi- dimensional array Public Sub DeclarationmultiDimensionalArray_1() CompileAndVerify( Imports System Module Module1 Sub Main() Dim myArray6 As Integer(,,,,) = Nothing myArray6 = New Integer(4, 5, 8, 3, 6) {} End Sub End Module ).VerifyIL("Module1.Main", ) End Sub ' Declaration multi- dimensional array Public Sub DeclarationmultiDimensionalArray_2() CompileAndVerify( Imports System Module Module1 Private Delegate Sub myDelegate(myString As String) Sub Main() Dim myArray1 As myInterface(,) = New myInterface(3, 1) {} Dim myArray2 As myDelegate(,) = New myDelegate(3, 1) {} Dim myArray3 = New Integer(Number.One, Number.Two) {} End Sub End Module Interface myInterface End Interface Enum Number One Two End Enum ).VerifyIL("Module1.Main", ) End Sub ' Declaration multi- dimensional array Public Sub DeclarationmultiDimensionalArray_3() CompileAndVerify( Class C1 Public Shared Sub Main() Dim myLength As Integer = 3 Dim arr As Integer(,) = New Integer(myLength, 1) {} End Sub Private Class A Private x As Integer = 1 Private arr As Integer(,) = New Integer(x, 4) {} End Class End Class ).VerifyIL("C1.Main", ) End Sub ' Declaration multi- dimensional array Public Sub DeclarationmultiDimensionalArray_5() CompileAndVerify( Imports System Module Module1 Sub Main() Dim myArray8 As Integer(,) = New Integer(-1, 4) {} Dim arrDouble#(,) = New Double(1, 2) {} Dim arrDecimal@(,) = New Decimal(1, 2) {} Dim arrString$(,) = New String(1, 2) {} Dim arrInteger%(,) = New Integer(1, 2) {} Dim arrLong&(,) = New Long(1, 2) {} Dim arrSingle!(,) = New Single(1, 2) {} End Sub End Module ).VerifyIL("Module1.Main", ) End Sub ' Initialize multi- dimensional array Public Sub InitializemultiDimensionalArray() CompileAndVerify( Option Infer On Imports System Imports Microsoft.VisualBasic.Information Module Module1 Sub Main() Dim myArray1 As Integer(,,) = {{{0, 1}, {2, 3}}, {{4, 5}, {6, 7}}} Dim myArray2 As Single(,) = New Single(2, 1) {{CSng(1.0), CSng(2.0)}, {CSng(3.0), CSng(4.0)}, {CSng(5.0), CSng(6.0)}} Dim myArray3 As Long(,) = New Long(,) {{1, 2}, {3, 4}, {5, 6}} Dim myArray4 As Char(,) myArray4 = New Char(2, 1) {{"1"c, "2"c}, {"3"c, "4"c}, {"5"c, "6"c}} Dim myArray5 As Decimal(,) myArray5 = New Decimal(,) {{CDec(1.0), CDec(2.0)}, {CDec(3.0), CDec(4.0)}, {CDec(5.0), CDec(6.0)}} Dim myArray6 As Integer(,) = New Integer(-1, -1) {} Dim myArray7 As Integer(,) = New Integer(,) {{}} Dim myArray8 As Integer(,,) = New Integer(,,) {{{}}} Dim myArray9 As String(,) = New String(2, 1) {{"a"c, "b"c}, {"c"c, "d"c}, {"e"c, "f"c}} Console.WriteLine(UBound(myArray1, 1)) Console.WriteLine(UBound(myArray1, 2)) Console.WriteLine(UBound(myArray1, 3)) Console.WriteLine(UBound(myArray2, 1)) Console.WriteLine(UBound(myArray2, 2)) Console.WriteLine(UBound(myArray3, 1)) Console.WriteLine(UBound(myArray3, 2)) Console.WriteLine(UBound(myArray4, 1)) Console.WriteLine(UBound(myArray4, 2)) Console.WriteLine(UBound(myArray5, 1)) Console.WriteLine(UBound(myArray5, 2)) Console.WriteLine(UBound(myArray6, 1)) Console.WriteLine(UBound(myArray6, 2)) Console.WriteLine(UBound(myArray7, 1)) Console.WriteLine(UBound(myArray7, 2)) Console.WriteLine(UBound(myArray8, 1)) Console.WriteLine(UBound(myArray8, 2)) Console.WriteLine(UBound(myArray8, 3)) Console.WriteLine(UBound(myArray9, 1)) Console.WriteLine(UBound(myArray9, 2)) End Sub End Module , expectedOutput:=) End Sub ' Use different kinds of var as index upper bound Public Sub DifferentVarAsBound() CompileAndVerify( Option Infer On Imports Microsoft.VisualBasic.Information Module Module1 Property prop As Integer Sub Main(args As String()) Dim arr1(3, prop) As Integer Dim arr2(3, fun()) As Integer Dim x = fun() Dim arr3(x, 1) As Integer Dim z() As Integer Dim y() As Integer Dim replyCounts(,) As Short = New Short(UBound(z, 1), UBound(y, 1)) {} End Sub Function fun() As Integer Return 3 End Function Sub foo(x As Integer) Dim arr1(3, x) As Integer End Sub End Module ).VerifyIL("Module1.Main", ) End Sub ' Specify lower bound and up bound for multi-dimensional array Public Sub SpecifyLowerAndUpBound() CompileAndVerify( Module Module1 Property prop As Integer Sub Main(args As String()) Dim arr1(0 To 0, 0 To -1) As Integer End Sub End Module ).VerifyIL("Module1.Main", ) End Sub ' Array creation expression can be part of an anonymous object creation expression Public Sub ArrayCreateAsAnonymous() CompileAndVerify( Option Infer On Imports System Imports Microsoft.VisualBasic.Information Module Module1 Sub Main(args As String()) Dim a0 = New With { Key.b4 = New Integer(1, 2) {}, _ Key.b5 = New Integer(1, 1) {{1, 2}, {2, 3}}, Key.b6 = New Integer()() {New Integer(1) {}, New Integer(2) {}}, Key.b7 = New Integer(2)() {}, Key.b8 = New Integer(1)() {New Integer(0) {}, New Integer(1) {}}, Key.b9 = New Integer() {1, 2, 3}, Key.b10 = New Integer(,) {{1, 2}, {2, 3}} } Console.WriteLine(UBound(a0.b4, 1)) Console.WriteLine(UBound(a0.b4, 2)) Console.WriteLine(UBound(a0.b5, 1)) Console.WriteLine(UBound(a0.b5, 2)) Console.WriteLine(UBound(a0.b6, 1)) Console.WriteLine(UBound(a0.b7, 1)) Console.WriteLine(UBound(a0.b8, 1)) Console.WriteLine(UBound(a0.b9, 1)) Console.WriteLine(UBound(a0.b10, 1)) Console.WriteLine(UBound(a0.b10, 2)) End Sub End Module , expectedOutput:=) End Sub ' Accessing an array's 0th element should work fine Public Sub AccessZero() CompileAndVerify( Imports System Module Module1 Sub Main(args As String()) Dim arr As Integer(,) = New Integer(4, 4) {} arr(0, 0) = 5 Console.WriteLine(arr(0, 0)) End Sub End Module , expectedOutput:=).VerifyIL("Module1.Main", ) End Sub ' Accessing an array's maxlength element should work fine Public Sub AccessMaxLength() CompileAndVerify( Imports System Module Module1 Sub Main(args As String()) Dim arr As Integer(,) = New Integer(4, 3) {} arr(4, 3) = 5 Console.WriteLine(arr(4, 3)) End Sub End Module , expectedOutput:=).VerifyIL("Module1.Main", ) End Sub ' Accessing an array's -1 element should throw an exception Public Sub AccessLessThanMin() CompileAndVerify( Imports System Module Module1 Sub Main(args As String()) Dim arr As Integer(,) = New Integer(4, 4) {} Try arr(-1, 1) = 5 arr(1, -1) = 5 arr(-1, -1) = 5 Catch generatedExceptionName As System.IndexOutOfRangeException End Try End Sub End Module ).VerifyIL("Module1.Main", ) End Sub ' Accessing an array's maxlength+1 element should throw an exception Public Sub AccessGreaterThanMax() CompileAndVerify( Imports System Module Module1 Sub Main(args As String()) Dim arr As Integer(,) = New Integer(4, 3) {} Try arr(5, 3) = 5 arr(4, 4) = 5 arr(5, 4) = 5 Catch End Try End Sub End Module ).VerifyIL("Module1.Main", ) End Sub ' Accessing an array's index with a variable of type int, short, byte should work Public Sub AccessWithDifferentType() CompileAndVerify( Option Infer On Imports System Module Module1 Sub Main(args As String()) Dim arr As Integer(,) = New Integer(4, 4) {} Dim idx As Integer = 2 Dim idx1 As Byte = 1 Dim idx3 As Short = 4 Dim idx4 = 2.0 Dim idx5 As Long = 3L arr(idx, 3) = 100 arr(idx1, 3) = 100 arr(idx3, 3) = 100 arr(cint(idx4), 3) = 100 arr(cint(idx5), 3) = 100 End Sub End Module ).VerifyIL("Module1.Main", ) End Sub ' Passing an element to a function as a byVal or byRef parameter should work Public Sub ArrayAsArgument() CompileAndVerify( Imports System Module Module1 Sub Main(args As String()) Dim arr As Integer(,) = New Integer(,) {{1, 2}} ElementTaker((arr(0, 1))) Console.WriteLine(arr(0, 1)) ElementTaker(arr(0, 1)) Console.WriteLine(arr(0, 1)) End Sub Public Function ElementTaker(ByRef val As Integer) As Integer val = val + 5 Return val End Function End Module , expectedOutput:=).VerifyIL("Module1.Main", ) End Sub ' Passing an element to a function as a byVal or byRef parameter should work Public Sub ArrayAsArgument_1() CompileAndVerify( Imports System Module Module1 Sub Main(args As String()) Dim arr As Integer(,) = New Integer(,) {{1, 2}} ElementTaker(arr(0, 1)) Console.WriteLine(arr(0, 1)) End Sub Public Function ElementTaker(ByVal val As Integer) As Integer val = 5 Return val End Function End Module , expectedOutput:=).VerifyIL("Module1.Main", ) End Sub ' Assigning nothing to an array variable Public Sub AssignNothingToArray() CompileAndVerify( Imports System Module Module1 Public Sub Main() Dim arr As Integer(,) = New Integer(0, 1) {{1, 2}} Dim arr1 As Integer(,) = Nothing arr = Nothing arr(0, 1) = 3 arr1(0, 1) = 3 End Sub End Module ).VerifyIL("Module1.Main", ) End Sub ' Assigning a smaller array to a bigger array or vice versa should work Public Sub AssignArrayToArray() CompileAndVerify( Imports System Imports Microsoft.VisualBasic.Information Module Program Public Sub Main() Dim arr1 As Integer(,) = New Integer(4, 1) {{1, 2}, {3, 4}, {5, 6}, {8, 9}, {100, 1210}} Dim arr2 As Integer(,) = New Integer(2, 1) {{6, 7}, {8, 1}, {2, 12}} arr1 = arr2 Dim arr3 As Integer(,) = New Integer(1, 1) {{6, 7}, {9, 8}} Dim arr4 As Integer(,) = New Integer(2, 2) {{1, 2, 3}, {4, 5, 6}, {8, 0, 2}} arr3 = arr4 Console.WriteLine(UBound(arr1, 1)) Console.WriteLine(UBound(arr1, 2)) Console.WriteLine(UBound(arr2, 1)) Console.WriteLine(UBound(arr2, 2)) Console.WriteLine(UBound(arr3, 1)) Console.WriteLine(UBound(arr3, 2)) Console.WriteLine(UBound(arr4, 1)) Console.WriteLine(UBound(arr4, 2)) End Sub End Module , expectedOutput:=) End Sub ' Access index by enum Public Sub AccessIndexByEnum() CompileAndVerify( Imports System Module Module1 Public Sub Main() Dim cube As Integer(,) = New Integer(1, 2) {} cube(Number.One, Number.Two) = 1 Console.WriteLine(cube(Number.One, Number.Two)) End Sub End Module Enum Number One Two End Enum , expectedOutput:=).VerifyIL("Module1.Main", ) End Sub ' Assigning a struct variable to an element should work Public Sub AssigningStructToElement() CompileAndVerify( Imports System Module Module1 Public Sub Main() Dim arr As myStruct(,) = New myStruct(2, 1) {} Dim ms As myStruct ms.x = 4 ms.y = 5 arr(2, 0) = ms End Sub End Module Structure myStruct Public x As Integer Public y As Integer End Structure ).VerifyIL("Module1.Main", ) End Sub ' Using foreach on a multi-dimensional array Public Sub TravallingMultiDemensionalArray() CompileAndVerify( Imports System Module Module1 Public Sub Main() Dim arr As Integer(,,) = New Integer(,,) {{{1, 2}, {4, 5}}} For Each i As Integer In arr Console.WriteLine(i) Next End Sub End Module , expectedOutput:=) End Sub ' Overload method by different dimension of array Public Sub OverloadByDiffDimensionArray() CompileAndVerify( Module Program Sub Main(args As String()) End Sub Sub foo(ByRef arg(,,) As Integer) End Sub Sub foo(ByRef arg(,) As Integer) End Sub Sub foo(ByRef arg() As Integer) End Sub End Module ).VerifyDiagnostics() End Sub ' Multi-dimensional array args could not as entry point Public Sub MultidimensionalArgsAsEntryPoint() CompileAndVerify( Class B Public Shared Sub Main(args As String(,)) End Sub Public Shared Sub Main() End Sub End Class Class M1 Public Shared Sub Main(args As String(,)) End Sub End Class ).VerifyDiagnostics() End Sub ' Declare multi-dimensional and Jagged array Public Sub MixedArray() CompileAndVerify( Imports Microsoft.VisualBasic.Information Class program Public Shared Sub Main() Dim x = New Integer(,)() {} Dim y(,)() As Byte = New Byte(,)() {{New Byte() {2, 1, 3}}, {New Byte() {3, 0}}} System.Console.WriteLine(UBound(y, 1)) System.Console.WriteLine(UBound(y, 2)) End Sub End Class , expectedOutput:=) End Sub ' Parse an Attribute instance that takes a generic type with an generic argument that is a multi-dimensional array Public Sub Generic() CompileAndVerify( Imports System <TypeAttribute(GetType(Program(Of [String])(,)))> _ Public Class Foo End Class Class Program(Of T) End Class Class TypeAttribute Inherits Attribute Public Sub New(value As Type) End Sub End Class ).VerifyDiagnostics() End Sub Public Sub MDArrayTypeRef() Dim csCompilation = CreateCSharpCompilation("CS", , compilationOptions:=New Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) csCompilation.VerifyDiagnostics() Dim vbCompilation = CreateVisualBasicCompilation("VB", , compilationOptions:=New VisualBasicCompilationOptions(OutputKind.ConsoleApplication), referencedCompilations:={csCompilation}) Dim vbVerifier = CompileAndVerify(vbCompilation, expectedOutput:=) vbVerifier.VerifyDiagnostics() End Sub End Class End Namespace