|
' 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 Microsoft.CodeAnalysis.Test.Utilities
Imports Roslyn.Test.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Public Class CodeGenIterators
Inherits BasicTestBase
<Fact>
<WorkItem(1081584, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1081584")>
Public Sub TestYieldInSelectCase()
CompileAndVerify(
<compilation>
<file name="a.vb">
Option Strict On
Imports System
Imports System.Collections.Generic
Module A
Public Sub Main()
For Each s In YieldString()
Console.WriteLine(s)
Next
End Sub
Public Iterator Function YieldString() As IEnumerable(Of String)
For Each b In { True, False }
Select Case True
Case b
Yield "True"
Case Not b
Yield "False"
End Select
Next
End Function
End Module
</file>
</compilation>, expectedOutput:="True
False").VerifyIL("A.VB$StateMachine_1_YieldString.MoveNext", "
{
// Code size 184 (0xb8)
.maxstack 5
.locals init (Integer V_0,
Boolean V_1, //b
Boolean V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""A.VB$StateMachine_1_YieldString.$State As Integer""
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: switch (
IL_001b,
IL_0067,
IL_008f)
IL_0019: ldc.i4.0
IL_001a: ret
IL_001b: ldarg.0
IL_001c: ldc.i4.m1
IL_001d: dup
IL_001e: stloc.0
IL_001f: stfld ""A.VB$StateMachine_1_YieldString.$State As Integer""
IL_0024: ldarg.0
IL_0025: ldc.i4.2
IL_0026: newarr ""Boolean""
IL_002b: dup
IL_002c: ldc.i4.0
IL_002d: ldc.i4.1
IL_002e: stelem.i1
IL_002f: stfld ""A.VB$StateMachine_1_YieldString.$S0 As Boolean()""
IL_0034: ldarg.0
IL_0035: ldc.i4.0
IL_0036: stfld ""A.VB$StateMachine_1_YieldString.$S1 As Integer""
IL_003b: br.s IL_00a6
IL_003d: ldarg.0
IL_003e: ldfld ""A.VB$StateMachine_1_YieldString.$S0 As Boolean()""
IL_0043: ldarg.0
IL_0044: ldfld ""A.VB$StateMachine_1_YieldString.$S1 As Integer""
IL_0049: ldelem.u1
IL_004a: stloc.1
IL_004b: ldc.i4.1
IL_004c: stloc.2
IL_004d: ldloc.2
IL_004e: ldloc.1
IL_004f: bne.un.s IL_0072
IL_0051: ldarg.0
IL_0052: ldstr ""True""
IL_0057: stfld ""A.VB$StateMachine_1_YieldString.$Current As String""
IL_005c: ldarg.0
IL_005d: ldc.i4.1
IL_005e: dup
IL_005f: stloc.0
IL_0060: stfld ""A.VB$StateMachine_1_YieldString.$State As Integer""
IL_0065: ldc.i4.1
IL_0066: ret
IL_0067: ldarg.0
IL_0068: ldc.i4.m1
IL_0069: dup
IL_006a: stloc.0
IL_006b: stfld ""A.VB$StateMachine_1_YieldString.$State As Integer""
IL_0070: br.s IL_0098
IL_0072: ldloc.2
IL_0073: ldloc.1
IL_0074: ldc.i4.0
IL_0075: ceq
IL_0077: bne.un.s IL_0098
IL_0079: ldarg.0
IL_007a: ldstr ""False""
IL_007f: stfld ""A.VB$StateMachine_1_YieldString.$Current As String""
IL_0084: ldarg.0
IL_0085: ldc.i4.2
IL_0086: dup
IL_0087: stloc.0
IL_0088: stfld ""A.VB$StateMachine_1_YieldString.$State As Integer""
IL_008d: ldc.i4.1
IL_008e: ret
IL_008f: ldarg.0
IL_0090: ldc.i4.m1
IL_0091: dup
IL_0092: stloc.0
IL_0093: stfld ""A.VB$StateMachine_1_YieldString.$State As Integer""
IL_0098: ldarg.0
IL_0099: ldarg.0
IL_009a: ldfld ""A.VB$StateMachine_1_YieldString.$S1 As Integer""
IL_009f: ldc.i4.1
IL_00a0: add.ovf
IL_00a1: stfld ""A.VB$StateMachine_1_YieldString.$S1 As Integer""
IL_00a6: ldarg.0
IL_00a7: ldfld ""A.VB$StateMachine_1_YieldString.$S1 As Integer""
IL_00ac: ldarg.0
IL_00ad: ldfld ""A.VB$StateMachine_1_YieldString.$S0 As Boolean()""
IL_00b2: ldlen
IL_00b3: conv.i4
IL_00b4: blt.s IL_003d
IL_00b6: ldc.i4.0
IL_00b7: ret
}
").VerifyIL("A.VB$StateMachine_1_YieldString.IEnumerable.GetEnumerator", "
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call ""Function A.VB$StateMachine_1_YieldString.GetEnumerator() As System.Collections.Generic.IEnumerator(Of String)""
IL_0006: ret
}")
End Sub
<Fact>
Public Sub SingletonIterator()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
For Each i In Goo
Console.WriteLine(i)
Next
End Sub
iterator function Goo as IEnumerable(of Integer)
Yield 42
End Function
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="42").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
// Code size 55 (0x37)
.maxstack 3
.locals init (Integer V_0)
IL_0000: ldarg.0
IL_0001: ldfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0010
IL_000a: ldloc.0
IL_000b: ldc.i4.1
IL_000c: beq.s IL_002c
IL_000e: ldc.i4.0
IL_000f: ret
IL_0010: ldarg.0
IL_0011: ldc.i4.m1
IL_0012: dup
IL_0013: stloc.0
IL_0014: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0019: ldarg.0
IL_001a: ldc.i4.s 42
IL_001c: stfld "Module1.VB$StateMachine_1_Goo.$Current As Integer"
IL_0021: ldarg.0
IL_0022: ldc.i4.1
IL_0023: dup
IL_0024: stloc.0
IL_0025: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_002a: ldc.i4.1
IL_002b: ret
IL_002c: ldarg.0
IL_002d: ldc.i4.m1
IL_002e: dup
IL_002f: stloc.0
IL_0030: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0035: ldc.i4.0
IL_0036: ret
}
]]>).VerifyIL("Module1.VB$StateMachine_1_Goo.IEnumerable.GetEnumerator", <![CDATA[
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call "Function Module1.VB$StateMachine_1_Goo.GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
IL_0006: ret
}
]]>)
End Sub
<Fact>
Public Sub TwoVarsSameName()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
For Each i In Goo
Console.Write(i)
Next
End Sub
Iterator Function Goo() As IEnumerable(Of Integer)
Dim arr(1) As Integer
arr(0) = 42
For Each x In arr
Yield x
Yield x
Next
For Each x In "abc"
Yield System.Convert.ToInt32(x)
Yield System.Convert.ToInt32(x)
Next
End Function
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="424200979798989999").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
// Code size 340 (0x154)
.maxstack 3
.locals init (Integer V_0,
Integer() V_1) //arr
IL_0000: ldarg.0
IL_0001: ldfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: switch (
IL_0023,
IL_0072,
IL_0092,
IL_0100,
IL_0125)
IL_0021: ldc.i4.0
IL_0022: ret
IL_0023: ldarg.0
IL_0024: ldc.i4.m1
IL_0025: dup
IL_0026: stloc.0
IL_0027: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_002c: ldc.i4.2
IL_002d: newarr "Integer"
IL_0032: stloc.1
IL_0033: ldloc.1
IL_0034: ldc.i4.0
IL_0035: ldc.i4.s 42
IL_0037: stelem.i4
IL_0038: ldarg.0
IL_0039: ldloc.1
IL_003a: stfld "Module1.VB$StateMachine_1_Goo.$S0 As Integer()"
IL_003f: ldarg.0
IL_0040: ldc.i4.0
IL_0041: stfld "Module1.VB$StateMachine_1_Goo.$S2 As Integer"
IL_0046: br.s IL_00a9
IL_0048: ldarg.0
IL_0049: ldarg.0
IL_004a: ldfld "Module1.VB$StateMachine_1_Goo.$S0 As Integer()"
IL_004f: ldarg.0
IL_0050: ldfld "Module1.VB$StateMachine_1_Goo.$S2 As Integer"
IL_0055: ldelem.i4
IL_0056: stfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$1 As Integer"
IL_005b: ldarg.0
IL_005c: ldarg.0
IL_005d: ldfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$1 As Integer"
IL_0062: stfld "Module1.VB$StateMachine_1_Goo.$Current As Integer"
IL_0067: ldarg.0
IL_0068: ldc.i4.1
IL_0069: dup
IL_006a: stloc.0
IL_006b: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0070: ldc.i4.1
IL_0071: ret
IL_0072: ldarg.0
IL_0073: ldc.i4.m1
IL_0074: dup
IL_0075: stloc.0
IL_0076: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_007b: ldarg.0
IL_007c: ldarg.0
IL_007d: ldfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$1 As Integer"
IL_0082: stfld "Module1.VB$StateMachine_1_Goo.$Current As Integer"
IL_0087: ldarg.0
IL_0088: ldc.i4.2
IL_0089: dup
IL_008a: stloc.0
IL_008b: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0090: ldc.i4.1
IL_0091: ret
IL_0092: ldarg.0
IL_0093: ldc.i4.m1
IL_0094: dup
IL_0095: stloc.0
IL_0096: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_009b: ldarg.0
IL_009c: ldarg.0
IL_009d: ldfld "Module1.VB$StateMachine_1_Goo.$S2 As Integer"
IL_00a2: ldc.i4.1
IL_00a3: add.ovf
IL_00a4: stfld "Module1.VB$StateMachine_1_Goo.$S2 As Integer"
IL_00a9: ldarg.0
IL_00aa: ldfld "Module1.VB$StateMachine_1_Goo.$S2 As Integer"
IL_00af: ldarg.0
IL_00b0: ldfld "Module1.VB$StateMachine_1_Goo.$S0 As Integer()"
IL_00b5: ldlen
IL_00b6: conv.i4
IL_00b7: blt.s IL_0048
IL_00b9: ldarg.0
IL_00ba: ldstr "abc"
IL_00bf: stfld "Module1.VB$StateMachine_1_Goo.$S3 As String"
IL_00c4: ldarg.0
IL_00c5: ldc.i4.0
IL_00c6: stfld "Module1.VB$StateMachine_1_Goo.$S5 As Integer"
IL_00cb: br.s IL_013c
IL_00cd: ldarg.0
IL_00ce: ldarg.0
IL_00cf: ldfld "Module1.VB$StateMachine_1_Goo.$S3 As String"
IL_00d4: ldarg.0
IL_00d5: ldfld "Module1.VB$StateMachine_1_Goo.$S5 As Integer"
IL_00da: callvirt "Function String.get_Chars(Integer) As Char"
IL_00df: stfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$4 As Char"
IL_00e4: ldarg.0
IL_00e5: ldarg.0
IL_00e6: ldfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$4 As Char"
IL_00eb: call "Function System.Convert.ToInt32(Char) As Integer"
IL_00f0: stfld "Module1.VB$StateMachine_1_Goo.$Current As Integer"
IL_00f5: ldarg.0
IL_00f6: ldc.i4.3
IL_00f7: dup
IL_00f8: stloc.0
IL_00f9: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_00fe: ldc.i4.1
IL_00ff: ret
IL_0100: ldarg.0
IL_0101: ldc.i4.m1
IL_0102: dup
IL_0103: stloc.0
IL_0104: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0109: ldarg.0
IL_010a: ldarg.0
IL_010b: ldfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$4 As Char"
IL_0110: call "Function System.Convert.ToInt32(Char) As Integer"
IL_0115: stfld "Module1.VB$StateMachine_1_Goo.$Current As Integer"
IL_011a: ldarg.0
IL_011b: ldc.i4.4
IL_011c: dup
IL_011d: stloc.0
IL_011e: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0123: ldc.i4.1
IL_0124: ret
IL_0125: ldarg.0
IL_0126: ldc.i4.m1
IL_0127: dup
IL_0128: stloc.0
IL_0129: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_012e: ldarg.0
IL_012f: ldarg.0
IL_0130: ldfld "Module1.VB$StateMachine_1_Goo.$S5 As Integer"
IL_0135: ldc.i4.1
IL_0136: add.ovf
IL_0137: stfld "Module1.VB$StateMachine_1_Goo.$S5 As Integer"
IL_013c: ldarg.0
IL_013d: ldfld "Module1.VB$StateMachine_1_Goo.$S5 As Integer"
IL_0142: ldarg.0
IL_0143: ldfld "Module1.VB$StateMachine_1_Goo.$S3 As String"
IL_0148: callvirt "Function String.get_Length() As Integer"
IL_014d: blt IL_00cd
IL_0152: ldc.i4.0
IL_0153: ret
}
]]>).VerifyIL("Module1.VB$StateMachine_1_Goo.IEnumerable.GetEnumerator", <![CDATA[
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call "Function Module1.VB$StateMachine_1_Goo.GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
IL_0006: ret
}
]]>)
End Sub
<Fact>
Public Sub ReadonlyProperty()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
For Each x In p1
Console.Write(x)
Next
End Sub
Public ReadOnly Iterator Property p1 As IEnumerable(Of Integer)
Get
Yield 42
End Get
End Property
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="42").VerifyIL("Module1.VB$StateMachine_2_get_p1.MoveNext()", <![CDATA[
{
// Code size 55 (0x37)
.maxstack 3
.locals init (Integer V_0)
IL_0000: ldarg.0
IL_0001: ldfld "Module1.VB$StateMachine_2_get_p1.$State As Integer"
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0010
IL_000a: ldloc.0
IL_000b: ldc.i4.1
IL_000c: beq.s IL_002c
IL_000e: ldc.i4.0
IL_000f: ret
IL_0010: ldarg.0
IL_0011: ldc.i4.m1
IL_0012: dup
IL_0013: stloc.0
IL_0014: stfld "Module1.VB$StateMachine_2_get_p1.$State As Integer"
IL_0019: ldarg.0
IL_001a: ldc.i4.s 42
IL_001c: stfld "Module1.VB$StateMachine_2_get_p1.$Current As Integer"
IL_0021: ldarg.0
IL_0022: ldc.i4.1
IL_0023: dup
IL_0024: stloc.0
IL_0025: stfld "Module1.VB$StateMachine_2_get_p1.$State As Integer"
IL_002a: ldc.i4.1
IL_002b: ret
IL_002c: ldarg.0
IL_002d: ldc.i4.m1
IL_002e: dup
IL_002f: stloc.0
IL_0030: stfld "Module1.VB$StateMachine_2_get_p1.$State As Integer"
IL_0035: ldc.i4.0
IL_0036: ret
}
]]>)
End Sub
<Fact>
Public Sub ReadWriteProperty()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
System.Console.Write(save Is Nothing)
p1 = p1
For Each x In save
Console.Write(x)
Next
End Sub
Private save As IEnumerable(Of Integer)
Public Iterator Property p1 As IEnumerable(Of Integer)
Get
Yield 42
End Get
Set(value As IEnumerable(Of Integer))
save = value
End Set
End Property
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="True42")
End Sub
<Fact>
Public Sub ParamCapture()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
For Each i In Goo(42)
Console.WriteLine(i)
Next
End Sub
iterator function Goo(x as integer) as IEnumerable(of Integer)
Yield x
End Function
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="42").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
// Code size 59 (0x3b)
.maxstack 3
.locals init (Integer V_0)
IL_0000: ldarg.0
IL_0001: ldfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0010
IL_000a: ldloc.0
IL_000b: ldc.i4.1
IL_000c: beq.s IL_0030
IL_000e: ldc.i4.0
IL_000f: ret
IL_0010: ldarg.0
IL_0011: ldc.i4.m1
IL_0012: dup
IL_0013: stloc.0
IL_0014: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0019: ldarg.0
IL_001a: ldarg.0
IL_001b: ldfld "Module1.VB$StateMachine_1_Goo.$VB$Local_x As Integer"
IL_0020: stfld "Module1.VB$StateMachine_1_Goo.$Current As Integer"
IL_0025: ldarg.0
IL_0026: ldc.i4.1
IL_0027: dup
IL_0028: stloc.0
IL_0029: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_002e: ldc.i4.1
IL_002f: ret
IL_0030: ldarg.0
IL_0031: ldc.i4.m1
IL_0032: dup
IL_0033: stloc.0
IL_0034: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0039: ldc.i4.0
IL_003a: ret
}
]]>)
End Sub
<Fact>
Public Sub NestedForeach()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
For Each i In Goo({1,2,3,4,5})
Console.Write(i)
Next
End Sub
iterator function Goo(x As IEnumerable(of Integer)) as IEnumerable(of Integer)
For Each i In x
Yield i
Next
End Function
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="12345").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
// Code size 175 (0xaf)
.maxstack 3
.locals init (Boolean V_0,
Integer V_1,
Integer V_2) //i
IL_0000: ldarg.0
IL_0001: ldfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0006: stloc.1
IL_0007: ldloc.1
IL_0008: ldc.i4.s -3
IL_000a: sub
IL_000b: switch (
IL_002f,
IL_0024,
IL_0024,
IL_0026,
IL_002f)
IL_0024: ldc.i4.0
IL_0025: ret
IL_0026: ldarg.0
IL_0027: ldc.i4.m1
IL_0028: dup
IL_0029: stloc.1
IL_002a: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_002f: nop
.try
{
IL_0030: ldloc.1
IL_0031: ldc.i4.s -3
IL_0033: beq.s IL_003b
IL_0035: ldloc.1
IL_0036: ldc.i4.1
IL_0037: beq.s IL_007b
IL_0039: br.s IL_0048
IL_003b: ldarg.0
IL_003c: ldc.i4.m1
IL_003d: dup
IL_003e: stloc.1
IL_003f: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0044: ldc.i4.1
IL_0045: stloc.0
IL_0046: leave.s IL_00ad
IL_0048: ldarg.0
IL_0049: ldarg.0
IL_004a: ldfld "Module1.VB$StateMachine_1_Goo.$VB$Local_x As System.Collections.Generic.IEnumerable(Of Integer)"
IL_004f: callvirt "Function System.Collections.Generic.IEnumerable(Of Integer).GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
IL_0054: stfld "Module1.VB$StateMachine_1_Goo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_0059: br.s IL_0084
IL_005b: ldarg.0
IL_005c: ldfld "Module1.VB$StateMachine_1_Goo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_0061: callvirt "Function System.Collections.Generic.IEnumerator(Of Integer).get_Current() As Integer"
IL_0066: stloc.2
IL_0067: ldarg.0
IL_0068: ldloc.2
IL_0069: stfld "Module1.VB$StateMachine_1_Goo.$Current As Integer"
IL_006e: ldarg.0
IL_006f: ldc.i4.1
IL_0070: dup
IL_0071: stloc.1
IL_0072: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0077: ldc.i4.1
IL_0078: stloc.0
IL_0079: leave.s IL_00ad
IL_007b: ldarg.0
IL_007c: ldc.i4.m1
IL_007d: dup
IL_007e: stloc.1
IL_007f: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0084: ldarg.0
IL_0085: ldfld "Module1.VB$StateMachine_1_Goo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_008a: callvirt "Function System.Collections.IEnumerator.MoveNext() As Boolean"
IL_008f: brtrue.s IL_005b
IL_0091: leave.s IL_00ab
}
finally
{
IL_0093: ldloc.1
IL_0094: ldc.i4.0
IL_0095: bge.s IL_00aa
IL_0097: ldarg.0
IL_0098: ldfld "Module1.VB$StateMachine_1_Goo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_009d: brfalse.s IL_00aa
IL_009f: ldarg.0
IL_00a0: ldfld "Module1.VB$StateMachine_1_Goo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
IL_00a5: callvirt "Sub System.IDisposable.Dispose()"
IL_00aa: endfinally
}
IL_00ab: ldc.i4.0
IL_00ac: ret
IL_00ad: ldloc.0
IL_00ae: ret
}
]]>).VerifyIL("Module1.VB$StateMachine_1_Goo.IEnumerable.GetEnumerator", <![CDATA[
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call "Function Module1.VB$StateMachine_1_Goo.GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
IL_0006: ret
}
]]>)
End Sub
<Fact>
Public Sub NestedFor()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
For Each i In Goo()
Console.Write(i)
Next
End Sub
iterator function Goo() as IEnumerable(of Integer)
For i = 1 to 5
Yield i
Next
End Function
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="12345").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
// Code size 89 (0x59)
.maxstack 3
.locals init (Integer V_0)
IL_0000: ldarg.0
IL_0001: ldfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0010
IL_000a: ldloc.0
IL_000b: ldc.i4.1
IL_000c: beq.s IL_0037
IL_000e: ldc.i4.0
IL_000f: ret
IL_0010: ldarg.0
IL_0011: ldc.i4.m1
IL_0012: dup
IL_0013: stloc.0
IL_0014: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0019: ldarg.0
IL_001a: ldc.i4.1
IL_001b: stfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_i$0 As Integer"
IL_0020: ldarg.0
IL_0021: ldarg.0
IL_0022: ldfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_i$0 As Integer"
IL_0027: stfld "Module1.VB$StateMachine_1_Goo.$Current As Integer"
IL_002c: ldarg.0
IL_002d: ldc.i4.1
IL_002e: dup
IL_002f: stloc.0
IL_0030: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0035: ldc.i4.1
IL_0036: ret
IL_0037: ldarg.0
IL_0038: ldc.i4.m1
IL_0039: dup
IL_003a: stloc.0
IL_003b: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0040: ldarg.0
IL_0041: ldarg.0
IL_0042: ldfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_i$0 As Integer"
IL_0047: ldc.i4.1
IL_0048: add.ovf
IL_0049: stfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_i$0 As Integer"
IL_004e: ldarg.0
IL_004f: ldfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_i$0 As Integer"
IL_0054: ldc.i4.5
IL_0055: ble.s IL_0020
IL_0057: ldc.i4.0
IL_0058: ret
}
]]>).VerifyIL("Module1.VB$StateMachine_1_Goo.IEnumerable.GetEnumerator", <![CDATA[
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call "Function Module1.VB$StateMachine_1_Goo.GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
IL_0006: ret
}
]]>)
End Sub
<Fact>
Public Sub LocalsInDispose()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
For Each i In Goo()
Console.Write(i)
Next
End Sub
iterator function Goo() as IEnumerable(of Integer)
Dim x = 1
Try
x += 1
Yield x
Exit Function
Finally
x += 1
Dim y = x
Console.Write(x)
Console.Write(y.ToString())
End Try
End Function
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="233").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
// Code size 182 (0xb6)
.maxstack 3
.locals init (Boolean V_0,
Integer V_1,
Integer V_2) //y
IL_0000: ldarg.0
IL_0001: ldfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0006: stloc.1
IL_0007: ldloc.1
IL_0008: ldc.i4.s -3
IL_000a: sub
IL_000b: switch (
IL_0036,
IL_0024,
IL_0024,
IL_0026,
IL_0036)
IL_0024: ldc.i4.0
IL_0025: ret
IL_0026: ldarg.0
IL_0027: ldc.i4.m1
IL_0028: dup
IL_0029: stloc.1
IL_002a: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_002f: ldarg.0
IL_0030: ldc.i4.1
IL_0031: stfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
IL_0036: nop
.try
{
IL_0037: ldloc.1
IL_0038: ldc.i4.s -3
IL_003a: beq.s IL_0042
IL_003c: ldloc.1
IL_003d: ldc.i4.1
IL_003e: beq.s IL_0076
IL_0040: br.s IL_004f
IL_0042: ldarg.0
IL_0043: ldc.i4.m1
IL_0044: dup
IL_0045: stloc.1
IL_0046: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_004b: ldc.i4.1
IL_004c: stloc.0
IL_004d: leave.s IL_00b4
IL_004f: ldarg.0
IL_0050: ldarg.0
IL_0051: ldfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
IL_0056: ldc.i4.1
IL_0057: add.ovf
IL_0058: stfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
IL_005d: ldarg.0
IL_005e: ldarg.0
IL_005f: ldfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
IL_0064: stfld "Module1.VB$StateMachine_1_Goo.$Current As Integer"
IL_0069: ldarg.0
IL_006a: ldc.i4.1
IL_006b: dup
IL_006c: stloc.1
IL_006d: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0072: ldc.i4.1
IL_0073: stloc.0
IL_0074: leave.s IL_00b4
IL_0076: ldarg.0
IL_0077: ldc.i4.m1
IL_0078: dup
IL_0079: stloc.1
IL_007a: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_007f: leave.s IL_00b2
}
finally
{
IL_0081: ldloc.1
IL_0082: ldc.i4.0
IL_0083: bge.s IL_00b1
IL_0085: ldarg.0
IL_0086: ldarg.0
IL_0087: ldfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
IL_008c: ldc.i4.1
IL_008d: add.ovf
IL_008e: stfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
IL_0093: ldarg.0
IL_0094: ldfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
IL_0099: stloc.2
IL_009a: ldarg.0
IL_009b: ldfld "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
IL_00a0: call "Sub System.Console.Write(Integer)"
IL_00a5: ldloca.s V_2
IL_00a7: call "Function Integer.ToString() As String"
IL_00ac: call "Sub System.Console.Write(String)"
IL_00b1: endfinally
}
IL_00b2: ldc.i4.0
IL_00b3: ret
IL_00b4: ldloc.0
IL_00b5: ret
}
]]>).VerifyIL("Module1.VB$StateMachine_1_Goo.IEnumerable.GetEnumerator", <![CDATA[
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call "Function Module1.VB$StateMachine_1_Goo.GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
IL_0006: ret
}
]]>)
End Sub
<Fact>
Public Sub TryCatch()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
For Each i In Goo()
Console.Write(i.Message)
Next
End Sub
iterator function Goo() as IEnumerable(of Exception)
Dim ex As exception = nothing
Try
yield New Exception("1")
Throw New Exception("2")
Catch ex
End Try
Yield ex
End Function
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="12").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
// Code size 172 (0xac)
.maxstack 3
.locals init (Boolean V_0,
Integer V_1,
System.Exception V_2) //ex
IL_0000: ldarg.0
IL_0001: ldfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0006: stloc.1
IL_0007: ldloc.1
IL_0008: ldc.i4.s -3
IL_000a: sub
IL_000b: switch (
IL_0035,
IL_0028,
IL_0028,
IL_002a,
IL_0035,
IL_009f)
IL_0028: ldc.i4.0
IL_0029: ret
IL_002a: ldarg.0
IL_002b: ldc.i4.m1
IL_002c: dup
IL_002d: stloc.1
IL_002e: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0033: ldnull
IL_0034: stloc.2
IL_0035: nop
.try
{
IL_0036: ldloc.1
IL_0037: ldc.i4.s -3
IL_0039: beq.s IL_0041
IL_003b: ldloc.1
IL_003c: ldc.i4.1
IL_003d: beq.s IL_006b
IL_003f: br.s IL_004e
IL_0041: ldarg.0
IL_0042: ldc.i4.m1
IL_0043: dup
IL_0044: stloc.1
IL_0045: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_004a: ldc.i4.1
IL_004b: stloc.0
IL_004c: leave.s IL_00aa
IL_004e: ldarg.0
IL_004f: ldstr "1"
IL_0054: newobj "Sub System.Exception..ctor(String)"
IL_0059: stfld "Module1.VB$StateMachine_1_Goo.$Current As System.Exception"
IL_005e: ldarg.0
IL_005f: ldc.i4.1
IL_0060: dup
IL_0061: stloc.1
IL_0062: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0067: ldc.i4.1
IL_0068: stloc.0
IL_0069: leave.s IL_00aa
IL_006b: ldarg.0
IL_006c: ldc.i4.m1
IL_006d: dup
IL_006e: stloc.1
IL_006f: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0074: ldstr "2"
IL_0079: newobj "Sub System.Exception..ctor(String)"
IL_007e: throw
}
catch System.Exception
{
IL_007f: dup
IL_0080: call "Sub Microsoft.VisualBasic.CompilerServices.ProjectData.SetProjectError(System.Exception)"
IL_0085: stloc.2
IL_0086: call "Sub Microsoft.VisualBasic.CompilerServices.ProjectData.ClearProjectError()"
IL_008b: leave.s IL_008d
}
IL_008d: ldarg.0
IL_008e: ldloc.2
IL_008f: stfld "Module1.VB$StateMachine_1_Goo.$Current As System.Exception"
IL_0094: ldarg.0
IL_0095: ldc.i4.2
IL_0096: dup
IL_0097: stloc.1
IL_0098: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_009d: ldc.i4.1
IL_009e: ret
IL_009f: ldarg.0
IL_00a0: ldc.i4.m1
IL_00a1: dup
IL_00a2: stloc.1
IL_00a3: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_00a8: ldc.i4.0
IL_00a9: ret
IL_00aa: ldloc.0
IL_00ab: ret
}
]]>)
End Sub
<Fact>
Public Sub TryFinally()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
For Each i In Goo()
Console.Write(i.Message)
Next
End Sub
iterator function Goo() as IEnumerable(of Exception)
Dim ex As exception = nothing
Try
yield New Exception("1")
Finally
ex = New Exception("2")
End Try
Yield ex
Try
Try
yield New Exception("3")
Throw New Exception()
Finally
ex = New Exception("4")
End Try
Catch ex1 As Exception
End Try
Yield ex
End Function
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="1234")
End Sub
<Fact>
Public Sub TryYieldFinally()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
For Each i In Goo()
Console.Write(i)
Next
End Sub
iterator function Goo() as IEnumerable(of integer)
Dim j as String = ""
Dim i = 1
Try
Try
throw new exception
Catch ex as exception
j = j + "#" + i.ToString() + "#"
End try
Yield i
Finally
Console.Write(j)
End Try
End Function
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="1#1#")
End Sub
<Fact>
Public Sub TryInLoop()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections
Module Module1
Sub Main()
For Each i In f()
Console.Write(i)
Next
End Sub
Iterator Function f() As IEnumerable
For i = 1 To 3
Dim j as String = ""
Try
Try
Yield i
throw new exception
Catch ex as exception
j = j + "#" + i.ToString() + "#"
End try
Yield i
Finally
Console.Write(j)
End Try
Next
End Function
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="11#1#22#2#33#3#")
End Sub
<Fact>
Public Sub InStruct()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections
Imports System.Collections.Generic
Module Module1
Sub Main()
Dim s As New S1
For Each i In s.f
Console.Write(i)
Next
For Each i In s.f
Console.Write(i)
Next
s.x = 42
For Each i In s.f
Console.Write(i)
Next
End Sub
Structure S1
Public x As integer
public Iterator Function f() As IEnumerable(of Integer)
Yield x
x += 1
Yield x
End Function
End Structure
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="01014243")
End Sub
<Fact>
Public Sub UnusedParams()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections
Imports System.Collections.Generic
Module Module1
Sub Main()
Dim s As New cls1
For Each i In s.f(Nothing, Nothing)
Console.Write(i)
Next
End Sub
class cls1
public Iterator Function f(x As Guid, y As Guid) As IEnumerable(of Integer)
Yield 1
Yield 2
End Function
End class
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="12").VerifyIL("Module1.cls1.VB$StateMachine_1_f.GetEnumerator()", <![CDATA[
{
// Code size 84 (0x54)
.maxstack 2
.locals init (Module1.cls1.VB$StateMachine_1_f V_0)
IL_0000: ldarg.0
IL_0001: ldfld "Module1.cls1.VB$StateMachine_1_f.$State As Integer"
IL_0006: ldc.i4.s -2
IL_0008: bne.un.s IL_0027
IL_000a: ldarg.0
IL_000b: ldfld "Module1.cls1.VB$StateMachine_1_f.$InitialThreadId As Integer"
IL_0010: call "Function System.Threading.Thread.get_CurrentThread() As System.Threading.Thread"
IL_0015: callvirt "Function System.Threading.Thread.get_ManagedThreadId() As Integer"
IL_001a: bne.un.s IL_0027
IL_001c: ldarg.0
IL_001d: ldc.i4.0
IL_001e: stfld "Module1.cls1.VB$StateMachine_1_f.$State As Integer"
IL_0023: ldarg.0
IL_0024: stloc.0
IL_0025: br.s IL_003a
IL_0027: ldc.i4.0
IL_0028: newobj "Sub Module1.cls1.VB$StateMachine_1_f..ctor(Integer)"
IL_002d: stloc.0
IL_002e: ldloc.0
IL_002f: ldarg.0
IL_0030: ldfld "Module1.cls1.VB$StateMachine_1_f.$VB$Me As Module1.cls1"
IL_0035: stfld "Module1.cls1.VB$StateMachine_1_f.$VB$Me As Module1.cls1"
IL_003a: ldloc.0
IL_003b: ldarg.0
IL_003c: ldfld "Module1.cls1.VB$StateMachine_1_f.$P_x As System.Guid"
IL_0041: stfld "Module1.cls1.VB$StateMachine_1_f.$VB$Local_x As System.Guid"
IL_0046: ldloc.0
IL_0047: ldarg.0
IL_0048: ldfld "Module1.cls1.VB$StateMachine_1_f.$P_y As System.Guid"
IL_004d: stfld "Module1.cls1.VB$StateMachine_1_f.$VB$Local_y As System.Guid"
IL_0052: ldloc.0
IL_0053: ret
}
]]>)
End Sub
<Fact>
Public Sub InferredEnumerable()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
Dim i = Iterator Function()
yield 123
End Function
goo(i)
Dim i1 = Iterator Function()
End Function
goo(i1)
Dim i2 as Func(Of IEnumerator(of integer)) = Iterator Function()
Yield 1
Yield "aa"
End Function
goo(i2)
End Sub
Public Sub goo(Of T)(x As Func(of T))
Console.WriteLine(GetType(T))
End Sub
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:=<![CDATA[
System.Collections.Generic.IEnumerable`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Object]
System.Collections.Generic.IEnumerator`1[System.Int32]
]]>)
End Sub
<Fact>
Public Sub EnumeratorWithParameter()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
Dim e = Goo(42)
While e.MoveNext
Console.WriteLine(e.Current)
End While
End Sub
iterator function Goo(x as integer) as IEnumerator(of Integer)
Yield x
End Function
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="42").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
// Code size 59 (0x3b)
.maxstack 3
.locals init (Integer V_0)
IL_0000: ldarg.0
IL_0001: ldfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0010
IL_000a: ldloc.0
IL_000b: ldc.i4.1
IL_000c: beq.s IL_0030
IL_000e: ldc.i4.0
IL_000f: ret
IL_0010: ldarg.0
IL_0011: ldc.i4.m1
IL_0012: dup
IL_0013: stloc.0
IL_0014: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0019: ldarg.0
IL_001a: ldarg.0
IL_001b: ldfld "Module1.VB$StateMachine_1_Goo.$VB$Local_x As Integer"
IL_0020: stfld "Module1.VB$StateMachine_1_Goo.$Current As Integer"
IL_0025: ldarg.0
IL_0026: ldc.i4.1
IL_0027: dup
IL_0028: stloc.0
IL_0029: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_002e: ldc.i4.1
IL_002f: ret
IL_0030: ldarg.0
IL_0031: ldc.i4.m1
IL_0032: dup
IL_0033: stloc.0
IL_0034: stfld "Module1.VB$StateMachine_1_Goo.$State As Integer"
IL_0039: ldc.i4.0
IL_003a: ret
}
]]>).VerifyIL("Module1.Goo", <![CDATA[
{
// Code size 14 (0xe)
.maxstack 3
IL_0000: ldc.i4.0
IL_0001: newobj "Sub Module1.VB$StateMachine_1_Goo..ctor(Integer)"
IL_0006: dup
IL_0007: ldarg.0
IL_0008: stfld "Module1.VB$StateMachine_1_Goo.$VB$Local_x As Integer"
IL_000d: ret
}
]]>)
End Sub
<Fact>
Public Sub GenericEnumerator()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Module1
Sub Main()
Dim e = Goo(42)
While e.MoveNext
Console.WriteLine(e.Current)
End While
End Sub
iterator function Goo(of T)(x as T) as IEnumerator(of T)
Yield x
End Function
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="42").VerifyIL("Module1.VB$StateMachine_1_Goo(Of SM$T).MoveNext", <![CDATA[
{
// Code size 59 (0x3b)
.maxstack 3
.locals init (Integer V_0)
IL_0000: ldarg.0
IL_0001: ldfld "Module1.VB$StateMachine_1_Goo(Of SM$T).$State As Integer"
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0010
IL_000a: ldloc.0
IL_000b: ldc.i4.1
IL_000c: beq.s IL_0030
IL_000e: ldc.i4.0
IL_000f: ret
IL_0010: ldarg.0
IL_0011: ldc.i4.m1
IL_0012: dup
IL_0013: stloc.0
IL_0014: stfld "Module1.VB$StateMachine_1_Goo(Of SM$T).$State As Integer"
IL_0019: ldarg.0
IL_001a: ldarg.0
IL_001b: ldfld "Module1.VB$StateMachine_1_Goo(Of SM$T).$VB$Local_x As SM$T"
IL_0020: stfld "Module1.VB$StateMachine_1_Goo(Of SM$T).$Current As SM$T"
IL_0025: ldarg.0
IL_0026: ldc.i4.1
IL_0027: dup
IL_0028: stloc.0
IL_0029: stfld "Module1.VB$StateMachine_1_Goo(Of SM$T).$State As Integer"
IL_002e: ldc.i4.1
IL_002f: ret
IL_0030: ldarg.0
IL_0031: ldc.i4.m1
IL_0032: dup
IL_0033: stloc.0
IL_0034: stfld "Module1.VB$StateMachine_1_Goo(Of SM$T).$State As Integer"
IL_0039: ldc.i4.0
IL_003a: ret
}
]]>).VerifyIL("Module1.Goo", <![CDATA[
{
// Code size 14 (0xe)
.maxstack 3
IL_0000: ldc.i4.0
IL_0001: newobj "Sub Module1.VB$StateMachine_1_Goo(Of T)..ctor(Integer)"
IL_0006: dup
IL_0007: ldarg.0
IL_0008: stfld "Module1.VB$StateMachine_1_Goo(Of T).$VB$Local_x As T"
IL_000d: ret
}
]]>)
End Sub
<Fact>
<WorkItem(703361, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/703361")>
Public Sub VerifyHelpers()
Dim source = <compilation>
<file name="a.vb"><![CDATA[
Imports System.Collections.Generic
Public Class Program
Public Shared Iterator Function Goo() As IEnumerable(Of Integer)
Yield 1
End Function
End Class]]></file>
</compilation>
Dim comp = CreateEmptyCompilationWithReferences(source, {MscorlibRef_v4_0_30316_17626}, New VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
Dim verifier = Me.CompileAndVerify(comp)
Dim il = verifier.VisualizeIL("Program.VB$StateMachine_1_Goo.GetEnumerator()")
Assert.Contains("System.Environment.get_CurrentManagedThreadId()", il, StringComparison.Ordinal)
End Sub
<WorkItem(835430, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/835430")>
<Fact>
Public Sub YieldInWith()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Public Structure MyStruct
Public a As Long
End Structure
Module Module1
Public MyStructs As MyStruct() = New MyStruct() {Nothing}
Sub Main()
For Each i In Goo()
Console.Write(i)
Next
End Sub
Iterator Function Goo() As IEnumerable(Of Integer)
For k = 1 To 2
With MyStructs(0)
Yield 42
System.Console.Write( .a)
End With
Next
End Function
End Module
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="420420")
End Sub
<Fact, WorkItem(9167, "https://github.com/dotnet/roslyn/issues/9167")>
Public Sub IteratorShouldCompileWithoutOptionalAttributes()
#Region "IL For corlib without CompilerGeneratedAttribute Or DebuggerNonUserCodeAttribute"
Dim corlib = "
Namespace System
Public Class [Object]
End Class
Public Class [Int32]
End Class
Public Class [Boolean]
End Class
Public Class [String]
End Class
Public Class Exception
End Class
Public Class NotSupportedException
Inherits Exception
End Class
Public Class ValueType
End Class
Public Class [Enum]
End Class
Public Class Void
End Class
Public Interface IDisposable
Sub Dispose()
End Interface
End Namespace
Namespace System.Collections
Public Interface IEnumerable
Function GetEnumerator() As IEnumerator
End Interface
Public Interface IEnumerator
Function MoveNext() As Boolean
Property Current As Object
Sub Reset()
End Interface
Namespace Generic
Public Interface IEnumerable(Of T)
Inherits IEnumerable
Overloads Function GetEnumerator() As IEnumerator(Of T)
End Interface
Public Interface IEnumerator(Of T)
Inherits IEnumerator
Overloads Property Current As T
End Interface
End Namespace
End Namespace
Namespace System.Threading
Public Class Thread
Shared Property CurrentThread As Thread
Property ManagedThreadId As Integer
End Class
End Namespace
"
#End Region
Dim source = "
Class C
Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
Yield Nothing
End Function
End Class
"
' The compilation succeeds even though CompilerGeneratedAttribute and DebuggerNonUserCodeAttribute are not available.
Dim compilation = CompilationUtils.CreateEmptyCompilation({Parse(source), Parse(corlib)})
Dim verifier = CompileAndVerify(compilation, verify:=Verification.Fails)
verifier.VerifyDiagnostics()
End Sub
<Fact, WorkItem(9463, "https://github.com/dotnet/roslyn/issues/9463")>
Public Sub IEnumerableIteratorReportsDiagnosticsWhenCoreTypesAreMissing()
' Note that IDisposable.Dispose, IEnumerator.Current and other types are missing
' Also, IEnumerator(Of T) doesn't have a get accessor
Dim source = "
Namespace System
Public Class [Object]
End Class
Public Class [Int32]
End Class
Public Class [Boolean]
End Class
Public Class [String]
End Class
Public Class Exception
End Class
Public Class ValueType
End Class
Public Class [Enum]
End Class
Public Class Void
End Class
Public Interface IDisposable
End Interface
End Namespace
Namespace System.Collections
Public Interface IEnumerable
End Interface
Public Interface IEnumerator
End Interface
End Namespace
Namespace System.Collections.Generic
Public Interface IEnumerator(Of T)
WriteOnly Property Current As T
End Interface
End Namespace
Class C
Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
Yield Nothing
End Function
End Class
"
Dim compilation = CreateEmptyCompilation({Parse(source)})
compilation.AssertTheseEmitDiagnostics(<expected>
BC30002: Type 'System.Collections.Generic.IEnumerable' is not defined.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC30524: Property 'System.Collections.Generic.IEnumerator(Of T).Current' is 'WriteOnly'.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.Generic.IEnumerable`1.GetEnumerator' is not defined.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.IEnumerable.GetEnumerator' is not defined.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.IEnumerator.Current' is not defined.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.IEnumerator.MoveNext' is not defined.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.IEnumerator.Reset' is not defined.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.IDisposable.Dispose' is not defined.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</expected>)
End Sub
<Fact, WorkItem(9463, "https://github.com/dotnet/roslyn/issues/9463")>
Public Sub IEnumeratorIteratorReportsDiagnosticsWhenCoreTypesAreMissing()
' Note that IDisposable.Dispose and other types are missing
' Also IEnumerator.Current lacks a get accessor
Dim source = "
Namespace System
Public Class [Object]
End Class
Public Class [Int32]
End Class
Public Class [Boolean]
End Class
Public Class [String]
End Class
Public Class Exception
End Class
Public Class ValueType
End Class
Public Class [Enum]
End Class
Public Class Void
End Class
Public Interface IDisposable
End Interface
End Namespace
Namespace System.Collections
Public Interface IEnumerable
End Interface
Public Interface IEnumerator
WriteOnly Property Current As Object
End Interface
End Namespace
Class C
Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
Yield Nothing
End Function
End Class
"
Dim compilation = CreateEmptyCompilation({Parse(source)})
' No error about IEnumerable
compilation.AssertTheseEmitDiagnostics(<expected>
BC30002: Type 'System.Collections.Generic.IEnumerator' is not defined.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC30524: Property 'System.Collections.IEnumerator.Current' is 'WriteOnly'.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.Generic.IEnumerator`1.Current' is not defined.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.IEnumerator.MoveNext' is not defined.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.IEnumerator.Reset' is not defined.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.IDisposable.Dispose' is not defined.
Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</expected>)
End Sub
<Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
Public Sub StateAfterMoveNext_YieldReturn()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Module Program
Sub Main()
Dim enumerator = C.GetEnumerator()
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
enumerator.Dispose()
Console.Write("disposed ")
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
End Sub
End Module
Class C
Public Shared Iterator Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of String)
Yield " one "
Yield " two "
End Function
End Class
</file>
</compilation>
Dim verifier = CompileAndVerify(source, expectedOutput:="True one disposed False one")
verifier.VerifyIL("C.VB$StateMachine_1_GetEnumerator.Dispose()", "
{
// Code size 9 (0x9)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldc.i4.s -2
IL_0003: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_0008: ret
}
")
End Sub
<Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
Public Sub StateAfterMoveNext_YieldReturn_IEnumerable()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Module Program
Sub Main()
Dim enumerator = C.Produce().GetEnumerator()
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
enumerator.Dispose()
Console.Write("disposed ")
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
End Sub
End Module
Class C
Public Shared Iterator Function Produce() As System.Collections.Generic.IEnumerable(Of String)
Yield " one "
Yield " two "
End Function
End Class
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="True one disposed False one")
' Verify GetEnumerator
Dim source2 =
<compilation>
<file name="a2.vb">
Imports System
Module Program
Sub Main()
Dim enumerable = C.Produce()
Dim enumerator = enumerable.GetEnumerator()
Console.Write(Object.ReferenceEquals(enumerable, enumerator))
Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
Console.Write(enumerator.MoveNext())
Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
enumerator.Dispose()
Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
enumerator.Dispose()
enumerator.Dispose()
Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
End Sub
End Module
Class C
Public Shared Iterator Function Produce() As System.Collections.Generic.IEnumerable(Of Integer)
Yield 42
Yield 43
End Function
End Class
</file>
</compilation>
CompileAndVerify(source2, expectedOutput:="TrueTrueTrueTrueTrueTrue")
End Sub
<Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
Public Sub StateAfterMoveNext_DisposeTwice()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Module Program
Sub Main()
Dim enumerator = C.GetEnumerator()
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
enumerator.Dispose()
Console.Write("disposed ")
enumerator.Dispose()
Console.Write("disposed2 ")
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
End Sub
End Module
Class C
Public Shared Iterator Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of String)
Dim local As String = ""
Yield " one "
local.ToString()
End Function
End Class
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="True one disposed disposed2 False one")
End Sub
<Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
Public Sub StateAfterMoveNext_YieldBreak()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Module Program
Sub Main()
Dim enumerator = C.GetEnumerator(True)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
End Sub
End Module
Class C
Public Shared Iterator Function GetEnumerator(b As Boolean) As System.Collections.Generic.IEnumerator(Of String)
Yield " one "
If b Then
Return
End If
Yield " two "
End Function
End Class
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="True one False one False one")
' Verify GetEnumerator
Dim source2 =
<compilation>
<file name="a2.vb">
Imports System
Module Program
Sub Main()
Dim enumerable = C.Produce(True)
Dim enumerator = enumerable.GetEnumerator()
Console.Write(enumerator.MoveNext())
Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
Console.Write(Not enumerator.MoveNext())
Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
End Sub
End Module
Class C
Public Shared Iterator Function Produce(b As Boolean) As System.Collections.Generic.IEnumerable(Of Integer)
Yield 42
If b Then
Return
End If
Yield 43
End Function
End Class
</file>
</compilation>
' We're not setting the state to "after"/"finished"
' Tracked by https://github.com/dotnet/roslyn/issues/76089
CompileAndVerify(source2, expectedOutput:="TrueTrueTrueFalse")
End Sub
<Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
Public Sub StateAfterMoveNext_EndOfBody()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Module Program
Sub Main()
Dim enumerator = C.GetEnumerator(True)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
End Sub
End Module
Class C
Public Shared Iterator Function GetEnumerator(b As Boolean) As System.Collections.Generic.IEnumerator(Of String)
Yield " one "
Console.Write("done ")
End Function
End Class
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="True one done False one False one")
' Verify GetEnumerator
Dim source2 =
<compilation>
<file name="a2.vb">
Imports System
Module Program
Sub Main()
Dim enumerable = C.Produce(True)
Dim enumerator = enumerable.GetEnumerator()
Console.Write(enumerator.MoveNext())
Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
Console.Write(Not enumerator.MoveNext())
Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
End Sub
End Module
Class C
Public Shared Iterator Function Produce(b As Boolean) As System.Collections.Generic.IEnumerable(Of Integer)
Yield 42
End Function
End Class
</file>
</compilation>
' We're not setting the state to "after"/"finished"
' Tracked by https://github.com/dotnet/roslyn/issues/76089
CompileAndVerify(source2, expectedOutput:="TrueTrueTrueFalse")
End Sub
<Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
Public Sub StateAfterMoveNext_ThrowException()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Module Program
Sub Main()
Dim enumerator = C.GetEnumerator(True)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
Try
Console.Write(enumerator.MoveNext())
Catch e As Exception
Console.Write(e.Message)
End Try
Console.Write(enumerator.Current)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
End Sub
End Module
Class C
Public Shared Iterator Function GetEnumerator(b As Boolean) As System.Collections.Generic.IEnumerator(Of String)
Yield " one "
Throw New Exception("exception")
End Function
End Class
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="True one exception one False one")
' Verify GetEnumerator
Dim source2 =
<compilation>
<file name="a2.vb">
Imports System
Module Program
Sub Main()
Dim enumerable = C.Produce()
Dim enumerator = enumerable.GetEnumerator()
Console.Write(enumerator.MoveNext())
Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
Try
enumerator.MoveNext()
Catch
Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
End Try
End Sub
End Module
Class C
Public Shared Iterator Function Produce() As System.Collections.Generic.IEnumerable(Of Integer)
Yield 42
Throw New Exception("exception")
End Function
End Class
</file>
</compilation>
' We're not setting the state to "after"/"finished"
' Tracked by https://github.com/dotnet/roslyn/issues/76089
CompileAndVerify(source2, expectedOutput:="TrueTrueFalse")
End Sub
<Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
Public Sub StateAfterMoveNext_YieldReturn_InTryFinally()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Module Program
Sub Main()
Dim enumerator = C.GetEnumerator()
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
Console.Write("disposing ")
Try
enumerator.Dispose()
Catch e As Exception
Console.Write(e.Message)
End Try
Console.Write(" disposed ")
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
End Sub
End Module
Class C
Public Shared Iterator Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of String)
Try
Yield " one "
Finally
Throw New Exception("exception")
End Try
End Function
End Class
</file>
</compilation>
Dim verifier = CompileAndVerify(source, expectedOutput:="True one disposing exception disposed False one")
verifier.VerifyIL("C.VB$StateMachine_1_GetEnumerator.Dispose()", "
{
// Code size 44 (0x2c)
.maxstack 2
.locals init (Integer V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.1
IL_0009: bne.un.s IL_0015
IL_000b: ldarg.0
IL_000c: ldc.i4.s -3
IL_000e: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_0013: br.s IL_001c
IL_0015: ldarg.0
IL_0016: ldc.i4.m1
IL_0017: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_001c: ldarg.0
IL_001d: call ""Function C.VB$StateMachine_1_GetEnumerator.MoveNext() As Boolean""
IL_0022: pop
IL_0023: ldarg.0
IL_0024: ldc.i4.s -2
IL_0026: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_002b: ret
}
")
' Verify GetEnumerator
Dim source2 =
<compilation>
<file name="a2.vb">
Imports System
Module Program
Sub Main()
Dim enumerable = C.Produce()
Dim enumerator = enumerable.GetEnumerator()
Console.Write(enumerator.MoveNext())
Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
Try
enumerator.Dispose()
Catch
Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
End Try
End Sub
End Module
Class C
Public Shared Iterator Function Produce() As System.Collections.Generic.IEnumerable(Of Integer)
Try
Yield 42
Finally
Throw New Exception("exception")
End Try
End Function
End Class
</file>
</compilation>
' We're not setting the state to "after"/"finished"
' Tracked by https://github.com/dotnet/roslyn/issues/76089
CompileAndVerify(source2, expectedOutput:="TrueTrueFalse")
End Sub
<Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
Public Sub StateAfterMoveNext_YieldBreak_InTryFinally()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Module Program
Sub Main()
Dim enumerator = C.GetEnumerator(True)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
End Sub
End Module
Class C
Public Shared Iterator Function GetEnumerator(b As Boolean) As System.Collections.Generic.IEnumerator(Of String)
Yield " one "
Try
If b Then
Return
End If
Finally
Console.Write("finally ")
End Try
Yield " two "
End Function
End Class
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="True one finally False one False one")
' Verify GetEnumerator
Dim source2 =
<compilation>
<file name="a2.vb">
Imports System
Imports System.Collections.Generic
Module Program
Sub Main()
Dim enumerable = C.Produce(True)
Dim enumerator = enumerable.GetEnumerator()
Console.Write(enumerator.MoveNext())
Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
Console.Write(Not enumerator.MoveNext())
Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
End Sub
End Module
Class C
Public Shared Iterator Function Produce(b As Boolean) As IEnumerable(Of Integer)
Yield 42
Try
If b Then
Exit Function
End If
Finally
Console.Write(" finally ")
End Try
Yield 43
End Function
End Class
</file>
</compilation>
' We're not setting the state to "after"/"finished"
' Tracked by https://github.com/dotnet/roslyn/issues/76089
CompileAndVerify(source2, expectedOutput:="TrueTrue finally TrueFalse")
End Sub
<Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
Public Sub StateAfterMoveNext_ThrowException_InTryFinally()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Module Program
Sub Main()
Dim enumerator = C.GetEnumerator(True)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
Try
Console.Write(enumerator.MoveNext())
Catch e As Exception
Console.Write(e.Message)
End Try
Console.Write(enumerator.Current)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
enumerator.Dispose()
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
End Sub
End Module
Class C
Public Shared Iterator Function GetEnumerator(b As Boolean) As System.Collections.Generic.IEnumerator(Of String)
Yield " one "
Try
Throw New Exception("exception")
Finally
Console.Write("finally ")
End Try
End Function
End Class
</file>
</compilation>
CompileAndVerify(source, expectedOutput:="True one finally exception one False one False one")
' Verify GetEnumerator
Dim source2 =
<compilation>
<file name="a2.vb">
Imports System
Imports System.Collections.Generic
Module Program
Sub Main()
Dim enumerable = C.Produce()
Dim enumerator = enumerable.GetEnumerator()
Console.Write(enumerator.MoveNext())
Try
enumerator.MoveNext()
Catch ex As Exception
Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
End Try
enumerator.Dispose()
Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
End Sub
End Module
Class C
Public Shared Iterator Function Produce() As IEnumerable(Of Integer)
Yield 42
Try
Throw New Exception("exception")
Finally
Console.Write(" finally ")
End Try
End Function
End Class
</file>
</compilation>
' We're not setting the state to "after"/"finished"
' Tracked by https://github.com/dotnet/roslyn/issues/76089
CompileAndVerify(source2, expectedOutput:="True finally FalseTrue")
End Sub
<Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
Public Sub StateAfterMoveNext_ThrowException_InTryFinally_WithYieldInTry()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Module Program
Sub Main()
Dim enumerator = C.GetEnumerator(True)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
Try
Console.Write(enumerator.MoveNext())
Catch e As Exception
Console.Write(e.Message)
End Try
Console.Write(enumerator.Current)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
End Sub
End Module
Class C
Public Shared Iterator Function GetEnumerator(b As Boolean) As System.Collections.Generic.IEnumerator(Of String)
Try
Yield " one "
If b Then
Throw New Exception("exception")
End If
Finally
Console.Write("finally ")
End Try
End Function
End Class
</file>
</compilation>
Dim verifier = CompileAndVerify(source, expectedOutput:="True one finally exception one False one")
verifier.VerifyIL("C.VB$StateMachine_1_GetEnumerator.Dispose()", "
{
// Code size 44 (0x2c)
.maxstack 2
.locals init (Integer V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.1
IL_0009: bne.un.s IL_0015
IL_000b: ldarg.0
IL_000c: ldc.i4.s -3
IL_000e: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_0013: br.s IL_001c
IL_0015: ldarg.0
IL_0016: ldc.i4.m1
IL_0017: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_001c: ldarg.0
IL_001d: call ""Function C.VB$StateMachine_1_GetEnumerator.MoveNext() As Boolean""
IL_0022: pop
IL_0023: ldarg.0
IL_0024: ldc.i4.s -2
IL_0026: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_002b: ret
}
")
' Verify GetEnumerator
Dim source2 =
<compilation>
<file name="a2.vb">
Imports System
Imports System.Collections.Generic
Module Program
Sub Main()
Dim enumerable = C.Produce()
Dim enumerator = enumerable.GetEnumerator()
Console.Write(enumerator.MoveNext())
Try
enumerator.MoveNext()
Catch ex As Exception
Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
End Try
End Sub
End Module
Class C
Public Shared Iterator Function Produce() As IEnumerable(Of Integer)
Try
Yield 42
Throw New Exception("exception")
Finally
Console.Write(" finally ")
End Try
End Function
End Class
</file>
</compilation>
' We're not setting the state to "after"/"finished"
' Tracked by https://github.com/dotnet/roslyn/issues/76089
CompileAndVerify(source2, expectedOutput:="True finally False")
End Sub
<Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
Public Sub StateAfterMoveNext_YieldReturn_AfterTryFinally()
Dim source =
<compilation>
<file name="a.vb">
Imports System
Imports System.Collections.Generic
Module Program
Sub Main()
Dim enumerator = C.GetEnumerator(True)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
enumerator.Dispose()
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.Current)
End Sub
End Module
Class C
Public Shared Iterator Function GetEnumerator(b As Boolean) As IEnumerator(Of String)
Try
Yield " one "
Finally
Console.Write("finally ")
End Try
Yield " two "
Console.Write("not executed after disposal")
End Function
End Class
</file>
</compilation>
Dim verifier = CompileAndVerify(source, expectedOutput:="True one finally True two False two")
verifier.VerifyIL("C.VB$StateMachine_1_GetEnumerator.MoveNext()", "
{
// Code size 171 (0xab)
.maxstack 3
.locals init (Boolean V_0,
Integer V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_0006: stloc.1
IL_0007: ldloc.1
IL_0008: ldc.i4.s -3
IL_000a: sub
IL_000b: switch (
IL_0033,
IL_0028,
IL_0028,
IL_002a,
IL_0033,
IL_0094)
IL_0028: ldc.i4.0
IL_0029: ret
IL_002a: ldarg.0
IL_002b: ldc.i4.m1
IL_002c: dup
IL_002d: stloc.1
IL_002e: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_0033: nop
.try
{
IL_0034: ldloc.1
IL_0035: ldc.i4.s -3
IL_0037: beq.s IL_003f
IL_0039: ldloc.1
IL_003a: ldc.i4.1
IL_003b: beq.s IL_0064
IL_003d: br.s IL_004c
IL_003f: ldarg.0
IL_0040: ldc.i4.m1
IL_0041: dup
IL_0042: stloc.1
IL_0043: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_0048: ldc.i4.1
IL_0049: stloc.0
IL_004a: leave.s IL_00a9
IL_004c: ldarg.0
IL_004d: ldstr "" one ""
IL_0052: stfld ""C.VB$StateMachine_1_GetEnumerator.$Current As String""
IL_0057: ldarg.0
IL_0058: ldc.i4.1
IL_0059: dup
IL_005a: stloc.1
IL_005b: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_0060: ldc.i4.1
IL_0061: stloc.0
IL_0062: leave.s IL_00a9
IL_0064: ldarg.0
IL_0065: ldc.i4.m1
IL_0066: dup
IL_0067: stloc.1
IL_0068: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_006d: leave.s IL_007e
}
finally
{
IL_006f: ldloc.1
IL_0070: ldc.i4.0
IL_0071: bge.s IL_007d
IL_0073: ldstr ""finally ""
IL_0078: call ""Sub System.Console.Write(String)""
IL_007d: endfinally
}
IL_007e: ldarg.0
IL_007f: ldstr "" two ""
IL_0084: stfld ""C.VB$StateMachine_1_GetEnumerator.$Current As String""
IL_0089: ldarg.0
IL_008a: ldc.i4.2
IL_008b: dup
IL_008c: stloc.1
IL_008d: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_0092: ldc.i4.1
IL_0093: ret
IL_0094: ldarg.0
IL_0095: ldc.i4.m1
IL_0096: dup
IL_0097: stloc.1
IL_0098: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_009d: ldstr ""not executed after disposal""
IL_00a2: call ""Sub System.Console.Write(String)""
IL_00a7: ldc.i4.0
IL_00a8: ret
IL_00a9: ldloc.0
IL_00aa: ret
}
")
verifier.VerifyIL("C.VB$StateMachine_1_GetEnumerator.Dispose()", "
{
// Code size 44 (0x2c)
.maxstack 2
.locals init (Integer V_0)
IL_0000: ldarg.0
IL_0001: ldfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.1
IL_0009: bne.un.s IL_0015
IL_000b: ldarg.0
IL_000c: ldc.i4.s -3
IL_000e: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_0013: br.s IL_001c
IL_0015: ldarg.0
IL_0016: ldc.i4.m1
IL_0017: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_001c: ldarg.0
IL_001d: call ""Function C.VB$StateMachine_1_GetEnumerator.MoveNext() As Boolean""
IL_0022: pop
IL_0023: ldarg.0
IL_0024: ldc.i4.s -2
IL_0026: stfld ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
IL_002b: ret
}
")
' Verify GetEnumerator
Dim source2 =
<compilation>
<file name="a2.vb">
Imports System
Imports System.Collections.Generic
Module Program
Sub Main()
Dim enumerable = C.Produce()
Dim enumerator = enumerable.GetEnumerator()
Console.Write(enumerator.MoveNext())
Console.Write(enumerator.MoveNext())
enumerator.Dispose()
Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
End Sub
End Module
Class C
Public Shared Iterator Function Produce() As IEnumerable(Of Integer)
Try
Yield 42
Finally
Console.Write(" finally ")
End Try
Yield 43
Console.Write("not executed after disposal")
End Function
End Class
</file>
</compilation>
CompileAndVerify(source2, expectedOutput:="True finally TrueTrue")
End Sub
End Class
End Namespace
|