/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Test/Semantic/Semantics/ForeachTest.vb
1 421 строка
63 KB
Tomáš Matoušek
Refactoring of extension methods in source packages (#78620) - take 2 (#78894)
26 июн 2025, 18:42
Не верифицирован
26 июн 2025, 18:42
05fc006
Код
Авторство
О чём код?
' 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.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Roslyn.Test.Utilities Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics Public Class ForeachTest : Inherits BasicTestBase <Fact> Public Sub SimpleForeachTest() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="SimpleForeachTest"> <file name="a.vb"> Imports System Class C Shared Sub Main() Dim arr As String() = New String(1) {} arr(0) = "one" arr(1) = "two" For Each s As String In arr Console.WriteLine(s) Next End Sub End Class </file> </compilation>, OutputKind.ConsoleApplication) SemanticInfoTypeTestForeach(compilation1, 1, "String()", "String()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="s", ReadInsideSymbol:="arr, s", ReadOutsideSymbol:="arr", WrittenInsideSymbol:="s", WrittenOutsideSymbol:="arr", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="arr", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub ' Narrowing conversions from the elements in group to element are evaluated and performed at run time <Fact> Public Sub NarrowConversions() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="NarrowConversions"> <file name="a.vb"> Option Strict On Imports System Class C Shared Sub Main() For Each number As Integer In New Long() {45, 3} Console.WriteLine(number) Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Long()", "Long()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="number", ReadInsideSymbol:="number", ReadOutsideSymbol:="", WrittenInsideSymbol:="number", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) Dim verifyItem As ForEachStatementInfo = Me.VerifyForeachSemanticInfo(compilation1, 1) Assert.Equal("Public Overloads Function GetEnumerator() As System.Collections.IEnumerator", verifyItem.GetEnumeratorMethod.ToString) Assert.Equal("Function MoveNext() As Boolean", verifyItem.MoveNextMethod.ToString) Assert.Equal("ReadOnly Property Current As Object", verifyItem.CurrentProperty.ToString) Assert.Equal("Sub Dispose()", verifyItem.DisposeMethod.ToString) End Sub ' Narrowing conversions from the elements in group to element are evaluated and performed at run time <Fact> Public Sub NarrowConversions_2() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="NarrowConversions"> <file name="a.vb"> Option Strict On Imports System Class C Shared Sub Main() For Each number As Integer In New Long() {9876543210} Console.WriteLine(number) Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Long()", "Long()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="number", ReadInsideSymbol:="number", ReadOutsideSymbol:="", WrittenInsideSymbol:="number", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub ' Using the iteration variable in the collection expression <WorkItem(542234, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542234")> <Fact> Public Sub IterationVarInCollectionExpression() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="IterationVarInCollectionExpression"> <file name="a.vb"> Option Infer On Class C Shared Sub Main() For Each x As S In If(True, x, 1) Next End Sub End Class Public Structure S End Structure </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Object", "System.Collections.IEnumerable") GetDeclareSymbolTestForeach(compilation1, Nothing) AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x", ReadInsideSymbol:="x", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) Me.ClassfiConversionTestForeach(compilation1, 1) Dim verifyItem As ForEachStatementInfo = Me.VerifyForeachSemanticInfo(compilation1, 1) Assert.Equal("Function GetEnumerator() As System.Collections.IEnumerator", verifyItem.GetEnumeratorMethod.ToString) Assert.Equal("Function MoveNext() As Boolean", verifyItem.MoveNextMethod.ToString) Assert.Equal("ReadOnly Property Current As Object", verifyItem.CurrentProperty.ToString) Assert.Equal("Sub Dispose()", verifyItem.DisposeMethod.ToString) End Sub ' Using the iteration variable in the collection expression <Fact> Public Sub IterationVarInCollectionExpression_1() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="IterationVarInCollectionExpression"> <file name="a.vb"> Class C Public Shared Sub Main() For Each x As Integer In New Integer() {x + 5, x + 6, x + 7} System.Console.WriteLine(x) Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Integer()", "Integer()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x", ReadInsideSymbol:="x", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub ' Traversing items in 'Nothing' <Fact> Public Sub TraversingNothingStrictOn() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="TraversingNothing"> <file name="a.vb"> Option Infer Off Option Strict On Class C Shared Sub Main() For Each item In Nothing Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "<nothing>", "Object") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="", ReadInsideSymbol:="", ReadOutsideSymbol:="", WrittenInsideSymbol:="", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub ' Traversing items in 'Nothing' <Fact()> Public Sub TraversingNothingStrictOff() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="TraversingNothing"> <file name="a.vb"> Option Strict Off Class C Shared Sub Main() For Each item In Nothing Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "<nothing>", "System.Collections.IEnumerable") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="item", ReadInsideSymbol:="", ReadOutsideSymbol:="", WrittenInsideSymbol:="item", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) Dim verifyItem = VerifyForeachSemanticInfo(compilation1) Assert.NotNull(verifyItem.GetEnumeratorMethod) Assert.NotNull(verifyItem.MoveNextMethod) Assert.NotNull(verifyItem.CurrentProperty) Assert.NotNull(verifyItem.DisposeMethod) End Sub ' Nested ForEach can use a var declared in the outer ForEach <WorkItem(542080, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542080")> <WorkItem(542234, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542234")> <Fact> Public Sub NestedForeach() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="NestedForeach"> <file name="a.vb"> Class C Shared Sub Main() Dim c(3)() As Integer For Each x As Integer() In c ReDim x(3) For i As Integer = 0 To 3 x(i) = i Next For Each y As Integer In x System.Console.WriteLine (y) Next Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Integer()()", "Integer()()") GetDeclareSymbolTestForeach(compilation1, Nothing) AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="i, x, y", ReadInsideSymbol:="c, i, x, y", ReadOutsideSymbol:="", WrittenInsideSymbol:="i, x, y", WrittenOutsideSymbol:="c", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="c", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) SemanticInfoTypeTestForeach(compilation1, 2, "Integer()", "Integer()") GetDeclareSymbolTestForeach(compilation1, Nothing, 2) AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="y", ReadInsideSymbol:="x, y", ReadOutsideSymbol:="c, i, x", WrittenInsideSymbol:="y", WrittenOutsideSymbol:="c, i, x", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="x", DataFlowsOutSymbol:="", index:=2) AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True, index:=2) ClassfiConversionTestForeach(compilation1, 2) VerifyForeachSemanticInfo(compilation1, 2) End Sub ' Inner foreach loop referencing the outer foreach loop iteration variable <WorkItem(542080, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542080")> <Fact> Public Sub NestedForeach_1() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="NestedForeach_1"> <file name="a.vb"> Class C Public Shared Sub Main() Dim S As String() = New String() {"ABC", "XYZ"} For Each x As String In S For Each y As Char In x System.Console.WriteLine(y) Next Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "String()", "String()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x, y", ReadInsideSymbol:="S, x, y", ReadOutsideSymbol:="", WrittenInsideSymbol:="x, y", WrittenOutsideSymbol:="S", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="S", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) SemanticInfoTypeTestForeach(compilation1, 2, "String", "String") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="y", ReadInsideSymbol:="x, y", ReadOutsideSymbol:="S", WrittenInsideSymbol:="y", WrittenOutsideSymbol:="S, x", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="x", DataFlowsOutSymbol:="", index:=2) AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True, index:=2) ClassfiConversionTestForeach(compilation1, 2) VerifyForeachSemanticInfo(compilation1, 2) End Sub ' Breaking from nested Loops <Fact> Public Sub BreakFromForeach() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="BreakFromForeach"> <file name="a.vb"> Class C Public Shared Sub Main() Dim S As String() = New String() {"ABC", "XYZ"} For Each x As String In S For Each y As Char In x If y = "B"c Then Exit For Else System.Console.WriteLine(y) End If Next Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "String()", "String()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x, y", ReadInsideSymbol:="S, x, y", ReadOutsideSymbol:="", WrittenInsideSymbol:="x, y", WrittenOutsideSymbol:="S", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="S", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) SemanticInfoTypeTestForeach(compilation1, 2, "String", "String") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="y", ReadInsideSymbol:="x, y", ReadOutsideSymbol:="S", WrittenInsideSymbol:="y", WrittenOutsideSymbol:="S, x", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="x", DataFlowsOutSymbol:="", index:=2) AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True, index:=2) ClassfiConversionTestForeach(compilation1, 2) VerifyForeachSemanticInfo(compilation1, 2) End Sub ' Continuing for nested Loops <WorkItem(542234, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542234")> <Fact> Public Sub ContinueInForeach() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="ContinueInForeach"> <file name="a.vb"> Class C Public Shared Sub Main() Dim S As String() = New String() {"ABC", "XYZ"} For Each x As String In S For Each y As Char In x If y = "B"c Then Continue For End If System.Console.WriteLine(y) Next y Next x End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "String()", "String()") GetDeclareSymbolTestForeach(compilation1, Nothing) AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x, y", ReadInsideSymbol:="S, x, y", ReadOutsideSymbol:="", WrittenInsideSymbol:="x, y", WrittenOutsideSymbol:="S", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="S", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) SemanticInfoTypeTestForeach(compilation1, 2, "String", "String") GetDeclareSymbolTestForeach(compilation1, Nothing, 2) AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="y", ReadInsideSymbol:="x, y", ReadOutsideSymbol:="S", WrittenInsideSymbol:="y", WrittenOutsideSymbol:="S, x", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="x", DataFlowsOutSymbol:="", index:=2) AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True, index:=2) ClassfiConversionTestForeach(compilation1, 2) VerifyForeachSemanticInfo(compilation1, 2) End Sub ' Query expression works in foreach <Fact()> Public Sub QueryExpressionInForeach() Dim compilation1 = CreateCompilationWithMscorlib40AndVBRuntimeAndReferences( <compilation name="QueryExpressionInForeach"> <file name="a.vb"> Imports System Imports System.Linq Option Infer On Class C Public Shared Sub Main() For Each x In From w In New Integer() {1, 2, 3} Select z = w.ToString() System.Console.WriteLine(x.ToLower()) Next End Sub End Class </file> </compilation>, references:={TestBase.LinqAssemblyRef}) SemanticInfoTypeTestForeach(compilation1, 1, "System.Collections.Generic.IEnumerable(Of String)", "System.Collections.Generic.IEnumerable(Of String)") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="w, x, z", ReadInsideSymbol:="w, x", ReadOutsideSymbol:="", WrittenInsideSymbol:="w, x, z", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub ' No confusion in a foreach statement when from is a value type <Fact> Public Sub ReDimFrom() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="ReDimFrom"> <file name="a.vb"> Option Infer On Class C Public Shared Sub Main() Dim src = New System.Collections.ArrayList() src.Add(New from(1)) For Each x As from In src System.Console.WriteLine(x.X) Next End Sub End Class Public Structure from Dim X As Integer Public Sub New(x as Integer) X = x End Sub End Structure </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "System.Collections.ArrayList", "System.Collections.ArrayList") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x", ReadInsideSymbol:="src, x", ReadOutsideSymbol:="src", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="src", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="src", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <Fact> Public Sub BC30302ERR_TypeCharWithType1() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation> <file name="c.vb"> Option Infer On Class C Shared Sub Main() For Each x% In New Integer() {1, 1} Next For Each x& In New Long() {1, 1} Next For Each x! In New Double() {1, 1} Next For Each x# In New Double() {1, 1} Next For Each x@ In New Decimal() {1, 1} Next 'COMPILEERROR: BC30302 For Each x% As Long In New Long() {1, 1, 1} Next For Each x# As Single In New Double() {1, 1, 1} Next For Each x@ As Decimal In New Decimal() {1, 1, 1} Next For Each x! As Object In New Long() {1, 1, 1} Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Integer()", "Integer()") SemanticInfoTypeTestForeach(compilation1, 2, "Long()", "Long()") SemanticInfoTypeTestForeach(compilation1, 3, "Double()", "Double()") SemanticInfoTypeTestForeach(compilation1, 4, "Double()", "Double()") SemanticInfoTypeTestForeach(compilation1, 5, "Decimal()", "Decimal()") SemanticInfoTypeTestForeach(compilation1, 6, "Long()", "Long()") SemanticInfoTypeTestForeach(compilation1, 7, "Double()", "Double()") SemanticInfoTypeTestForeach(compilation1, 8, "Decimal()", "Decimal()") SemanticInfoTypeTestForeach(compilation1, 9, "Long()", "Long()") For i As Integer = 1 To 9 AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x", ReadInsideSymbol:="", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="x, x, x, x, x, x, x, x", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="", index:=i) AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True, index:=i) ClassfiConversionTestForeach(compilation1, i) VerifyForeachSemanticInfo(compilation1, i) Next End Sub <Fact> Public Sub BC30039ERR_LoopControlMustNotBeProperty() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="LoopControlMustNotBeProperty"> <file name="a.vb"> Option Infer On Imports System Class C Inherits B Property P() As Integer Shadows F As Integer Sub Method1(A As Integer, ByRef B As Integer) ' error For Each P In new Integer(){1} Next ' warning For Each F In Integer(){2} Next For Each Me.F In Integer(){3} Next For Each MyBase.F In {4} Next For Each A In {5} Next For Each B In {6} Next End Sub Shared Sub Main() End Sub End Class Class B Public F As Integer End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Integer()", "Integer()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="", ReadInsideSymbol:="Me", ReadOutsideSymbol:="B, Me", WrittenInsideSymbol:="", WrittenOutsideSymbol:="A, B, Me", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="Me", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <Fact> Public Sub BC30277ERR_TypecharNoMatch2_2() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="TypecharNoMatch2"> <file name="a.vb"> Class C Public Shared Sub Main() 'declare with explicit type, use in next with a type char") For Each x As Integer In New Integer() {1, 1, 1} 'COMPILEERROR: BC30277, "x#" Next x# For Each [me] As Integer In New Integer() {1, 1, 1} Next me% End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Integer()", "Integer()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x", ReadInsideSymbol:="", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="me", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) SemanticInfoTypeTestForeach(compilation1, 2, "Integer()", "Integer()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="me", ReadInsideSymbol:="", ReadOutsideSymbol:="", WrittenInsideSymbol:="me", WrittenOutsideSymbol:="x", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="", index:=2) AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True, index:=2) ClassfiConversionTestForeach(compilation1, 2) VerifyForeachSemanticInfo(compilation1, 2) End Sub <Fact> Public Sub BC30288ERR_DuplicateLocals1_1() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="DuplicateLocals1"> <file name="a.vb"> Class C Shared Sub Main() For Each x As Integer In New Integer() {1, 2, 3} Dim x As Integer Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Integer()", "Integer()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x, x", ReadInsideSymbol:="", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <WorkItem(542234, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542234")> <Fact> Public Sub BC30290ERR_LocalSameAsFunc_1() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="LocalSameAsFunc"> <file name="a.vb"> Class C Shared Sub Main() End Sub Function goo() 'COMPILEERROR: BC30290, For Each goo As Integer In New Integer() {1, 2, 3} Next End Function Sub goo1() For Each goo1 As Integer In New Integer() {1, 2, 3} Next End SUB End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Integer()", "Integer()") GetDeclareSymbolTestForeach(compilation1, Nothing) AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="goo", ReadInsideSymbol:="", ReadOutsideSymbol:="", WrittenInsideSymbol:="goo", WrittenOutsideSymbol:="Me", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) SemanticInfoTypeTestForeach(compilation1, 2, "Integer()", "Integer()") GetDeclareSymbolTestForeach(compilation1, Nothing, 2) AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="goo1", ReadInsideSymbol:="", ReadOutsideSymbol:="", WrittenInsideSymbol:="goo1", WrittenOutsideSymbol:="Me", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="", index:=2) AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True, index:=2) ClassfiConversionTestForeach(compilation1, 2) VerifyForeachSemanticInfo(compilation1, 2) End Sub <Fact> Public Sub BC30311ERR_TypeMismatch2_1() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation> <file name="a.vb"> Class C Shared Sub Main() For Each x As Integer In New Exception() {Nothing, Nothing} Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Exception()", "Exception()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x", ReadInsideSymbol:="", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <Fact> Public Sub BC30311ERR_TypeMismatch2_2() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation> <file name="a.vb"> Class C Public Shared Sub Main() Dim numbers2D As Integer()() = New Integer()() {New Integer() {1, 2}, New Integer() {1, 2}} For Each x As Integer In numbers2D System.Console.Write("{0} ", x) Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Integer()()", "Integer()()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x", ReadInsideSymbol:="numbers2D, x", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="numbers2D", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="numbers2D", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <Fact> Public Sub BC30369ERR_BadInstanceMemberAccess_3() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation> <file name="a.vb"> Class C Shared Sub Main() For Each x As Integer In F(x) Next End Sub Private Sub F(x As Integer) End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Void", "Void") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x", ReadInsideSymbol:="x", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <Fact> Public Sub BC30369ERR_BadInstanceMemberAccess_4() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation> <file name="a.vb"> Class C Shared Sub Main() For Each x As Integer In F(x) Next End Sub Private Function F(x As Integer) As Object Return New Object() End Function End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Object", "Object") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x", ReadInsideSymbol:="x", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <WorkItem(542083, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542083")> <Fact> Public Sub BC30369ERR_BadInstanceMemberAccess_5() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation> <file name="a.vb"> Class C Property P1(ByVal x As Integer) As integer Get Return x +5 End Get Set(ByVal Value As integer) End Set End Property Public Shared Sub Main() For Each x As integer In New integer() {P1(x), P1(x), P1(x)} Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Integer()", "Integer()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x", ReadInsideSymbol:="x", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <Fact> Public Sub BC30369ERR_BadInstanceMemberAccess_6() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation> <file name="a.vb"> Class C Public Shared Sub Main() For Each x As Integer In New Integer() {goo(x), goo(x), goo(x)} Next End Sub Function goo(ByRef x As Integer) As Integer x = 10 Return x + 10 End Function End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Integer()", "Integer()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x", ReadInsideSymbol:="x", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <Fact> Public Sub BC30532ERR_DateToDoubleConversion_1() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="DateToDoubleConversion"> <file name="a.vb"> Imports System Class C Shared Sub Main() For Each x As Double In New Date() {#12:00:00 AM#} Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Date()", "Date()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x", ReadInsideSymbol:="", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <WorkItem(542234, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542234")> <Fact()> Public Sub BC32006ERR_CharToIntegralTypeMismatch1_1() Dim compilation1 = CreateCompilationWithMscorlib40AndVBRuntimeAndReferences( <compilation name="CharToIntegralTypeMismatch1"> <file name="a.vb"> Imports System Imports System.Linq Class C Shared Sub Main() For Each x As Integer In From c In "abc" Select c Next End Sub End Class Public Structure S End Structure </file> </compilation>, references:={TestBase.LinqAssemblyRef}) SemanticInfoTypeTestForeach(compilation1, 1, "System.Collections.Generic.IEnumerable(Of Char)", "System.Collections.Generic.IEnumerable(Of Char)") GetDeclareSymbolTestForeach(compilation1, Nothing) AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="c, c, x", ReadInsideSymbol:="c", ReadOutsideSymbol:="", WrittenInsideSymbol:="c, c, x", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <Fact> Public Sub BC32023ERR_ForEachCollectionDesignPattern1_1() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="ForEachCollectionDesignPattern1"> <file name="a.vb"> Class C Shared Sub Main() For Each x As Integer In If(x, x, x) Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "Integer", "Integer") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="x", ReadInsideSymbol:="x", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <WorkItem(542234, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542234")> <Fact> Public Sub VarDeclOutOfForeach() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="VarDeclOutOfForeach"> <file name="a.vb"> Option Strict On Option Infer On Public Class MyClass1 Public Shared Sub Main() Dim z As String For Each z In "" Next End Sub End Class </file> </compilation>) SemanticInfoTypeTestForeach(compilation1, 1, "String", "String") GetDeclareSymbolTestForeach(compilation1, Nothing) AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="", ReadInsideSymbol:="", ReadOutsideSymbol:="", WrittenInsideSymbol:="z", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub ' No confusion in a foreach statement when from is a value type <WorkItem(542081, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542081")> <Fact> Public Sub LambdaAsIteration() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="LambdaAsIteration"> <file name="a.vb"> Imports System Class C Public Shared Sub Main() Dim x As Action For Each x In New Action() {Sub() Console.WriteLine("hello")} x.Invoke() Next End Sub End Class </file> </compilation>) compilation1.VerifyDiagnostics() SemanticInfoTypeTestForeach(compilation1, 1, "System.Action()", "System.Action()") AnalyzeRegionDataFlowTestForeach(compilation1, VariablesDeclaredSymbol:="", ReadInsideSymbol:="x", ReadOutsideSymbol:="", WrittenInsideSymbol:="x", WrittenOutsideSymbol:="", AlwaysAssignedSymbol:="", DataFlowsInSymbol:="", DataFlowsOutSymbol:="") AnalyzeRegionControlFlowTestForeach(compilation1, EntryPoints:=0, ExitPoints:=0, EndPointIsReachable:=True) ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <Fact> Public Sub CollectionHasNoDifferentConvertedTypeForDesignPatternMatch() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="CollectionHasConvertedType"> <file name="a.vb"> Option Strict On Option Infer On Imports System Imports System.Collections Public Class SomethingEnumerable Implements IEnumerable Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator Return Nothing End Function End Class Class C1 Public Shared Sub Main() Dim myCollection As SomethingEnumerable = nothing For Each element In myCollection Console.WriteLine("goo") Next End Sub End Class </file> </compilation>) compilation1.VerifyDiagnostics() SemanticInfoTypeTestForeach(compilation1, 1, "SomethingEnumerable", "SomethingEnumerable") ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <Fact> Public Sub CollectionHasConvertedTypeIEnumerable() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="CollectionHasConvertedType"> <file name="a.vb"> Option Strict On Option Infer On Imports System Imports System.Collections Public Class SomethingEnumerable Implements IEnumerable Public Function GetEnumerator2() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator Return Nothing End Function End Class Class C1 Public Shared Sub Main() Dim myCollection As SomethingEnumerable = nothing For Each element In myCollection Console.WriteLine("goo") Next End Sub End Class </file> </compilation>) compilation1.VerifyDiagnostics() SemanticInfoTypeTestForeach(compilation1, 1, "SomethingEnumerable", "System.Collections.IEnumerable") ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <Fact> Public Sub CollectionHasConvertedTypeGenericIEnumerable() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="CollectionHasConvertedType"> <file name="a.vb"> Option Strict On Option Infer On Imports System Imports System.Collections.Generic Public Interface IBetterEnumerable(Of T) Inherits IEnumerable(Of T) End Interface Public Class SomethingEnumerable(Of T) Implements IEnumerable(Of T) Public Function GetEnumerator1() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator Return Nothing End Function Public Function GetEnumerator2() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator Return Nothing End Function End Class Class C1 Public Shared Sub Main() Dim myCollection3 As SomethingEnumerable(Of String) = nothing For Each element In myCollection3 Console.WriteLine("goo") Next End Sub End Class </file> </compilation>) compilation1.VerifyDiagnostics() SemanticInfoTypeTestForeach(compilation1, 1, "SomethingEnumerable(Of String)", "System.Collections.Generic.IEnumerable(Of String)") ClassfiConversionTestForeach(compilation1) VerifyForeachSemanticInfo(compilation1) End Sub <Fact> Public Sub GetDeclaredSymbolOfForEachStatement() Dim compilation1 = CreateCompilationWithMscorlib40( <compilation name="CollectionHasConvertedType"> <file name="a.vb"> Option Strict On Option Infer On Imports System Imports System.Collection Class C1 Public Shared Sub Main() For Each element1 In new List() Next For Each element2 as Object In new List() Next End Sub End Class </file> </compilation>) GetDeclareSymbolTestForeach(compilation1, Nothing, 1) GetDeclareSymbolTestForeach(compilation1, Nothing, 2) End Sub <WorkItem(667616, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/667616")> <Fact> Public Sub PortableLibraryStringForEach() Dim comp = CreateEmptyCompilationWithReferences( <compilation> <file name="a.vb"> Public Class C Public Sub Test(s As String) For Each c In s Next End Sub End Class </file> </compilation>, {SystemRuntimePP7Ref}) comp.VerifyDiagnostics() Dim tree = comp.SyntaxTrees.Single() Dim model = comp.GetSemanticModel(tree) Dim loopSyntax = tree.GetRoot().DescendantNodes().OfType(Of ForEachStatementSyntax)().Single() Dim loopInfo = model.GetForEachStatementInfo(loopSyntax) AssertEx.Equal(Of ISymbol)(comp.GetSpecialTypeMember(SpecialMember.System_Collections_IEnumerable__GetEnumerator), loopInfo.GetEnumeratorMethod) AssertEx.Equal(Of ISymbol)(comp.GetSpecialTypeMember(SpecialMember.System_Collections_IEnumerator__Current), loopInfo.CurrentProperty) AssertEx.Equal(Of ISymbol)(comp.GetSpecialTypeMember(SpecialMember.System_Collections_IEnumerator__MoveNext), loopInfo.MoveNextMethod) AssertEx.Equal(Of ISymbol)(comp.GetSpecialTypeMember(SpecialMember.System_IDisposable__Dispose), loopInfo.DisposeMethod) ' The spec says that the element type is object. ' Therefore, we should infer object for "var". Assert.Equal(SpecialType.System_Object, loopInfo.CurrentProperty.Type.SpecialType) ' However, to match dev11, we actually infer "char" for "var". Dim typeInfo = model.GetTypeInfo(DirectCast(loopSyntax.ControlVariable, IdentifierNameSyntax)) Assert.Equal(SpecialType.System_Char, typeInfo.Type.SpecialType) Assert.Equal(typeInfo.Type, typeInfo.ConvertedType) Dim conv = model.GetConversion(loopSyntax.ControlVariable) Assert.Equal(ConversionKind.Identity, conv.Kind) End Sub <WorkItem(667616, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/667616")> <Fact> Public Sub PortableLibraryStringForEach_ExplicitCast() Dim comp = CreateEmptyCompilationWithReferences( <compilation> <file name="a.vb"> Public Class C Public Sub Test(s As Object) For Each c In DirectCast(s, String) Next End Sub End Class </file> </compilation>, {SystemRuntimePP7Ref}) comp.VerifyDiagnostics() Dim tree = comp.SyntaxTrees.Single() Dim model = comp.GetSemanticModel(tree) Dim loopSyntax = tree.GetRoot().DescendantNodes().OfType(Of ForEachStatementSyntax)().Single() Dim loopInfo = model.GetForEachStatementInfo(loopSyntax) AssertEx.Equal(Of ISymbol)(comp.GetSpecialTypeMember(SpecialMember.System_Collections_IEnumerable__GetEnumerator), loopInfo.GetEnumeratorMethod) AssertEx.Equal(Of ISymbol)(comp.GetSpecialTypeMember(SpecialMember.System_Collections_IEnumerator__Current), loopInfo.CurrentProperty) AssertEx.Equal(Of ISymbol)(comp.GetSpecialTypeMember(SpecialMember.System_Collections_IEnumerator__MoveNext), loopInfo.MoveNextMethod) AssertEx.Equal(Of ISymbol)(comp.GetSpecialTypeMember(SpecialMember.System_IDisposable__Dispose), loopInfo.DisposeMethod) ' The spec says that the element type is object. ' Therefore, we should infer object for "var". Assert.Equal(SpecialType.System_Object, loopInfo.CurrentProperty.Type.SpecialType) ' However, to match dev11, we actually infer "char" for "var". Dim typeInfo = model.GetTypeInfo(DirectCast(loopSyntax.ControlVariable, IdentifierNameSyntax)) Assert.Equal(SpecialType.System_Char, typeInfo.Type.SpecialType) Assert.Equal(typeInfo.Type, typeInfo.ConvertedType) Dim conv = model.GetConversion(loopSyntax.ControlVariable) Assert.Equal(ConversionKind.Identity, conv.Kind) End Sub <WorkItem(529956, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529956")> <Fact> Public Sub CastArrayToIEnumerable() Dim source = <compilation> <file name="a.vb"> Imports System Imports System.Collections Public Class C Public Shared Widening Operator CType(s As String) As C Return New C() End Operator End Class Module Program Sub Main(args As String()) For Each x As C In args Next For Each x As C In DirectCast(args, IEnumerable) Next End Sub End Module </file> </compilation> Dim comp = CreateCompilationWithMscorlib40AndVBRuntime(source) comp.AssertNoDiagnostics() Dim udc = comp.GlobalNamespace.GetMember(Of NamedTypeSymbol)("C").GetMember(Of MethodSymbol)(WellKnownMemberNames.ImplicitConversionName) Dim tree = comp.SyntaxTrees.Single() Dim model = comp.GetSemanticModel(tree) Dim loopSyntaxes = tree.GetRoot().DescendantNodes().OfType(Of ForEachStatementSyntax)().ToArray() Assert.Equal(2, loopSyntaxes.Length) Dim loopInfo0 = model.GetForEachStatementInfo(loopSyntaxes(0)) Assert.Equal(comp.GetSpecialType(SpecialType.System_Array), loopInfo0.GetEnumeratorMethod.ContainingType) ' Unlike C#, the spec doesn't say that arrays use IEnumerable AssertEx.Equal(Of ISymbol)(comp.GetSpecialTypeMember(SpecialMember.System_Collections_IEnumerator__Current), loopInfo0.CurrentProperty) AssertEx.Equal(Of ISymbol)(comp.GetSpecialTypeMember(SpecialMember.System_Collections_IEnumerator__MoveNext), loopInfo0.MoveNextMethod) AssertEx.Equal(Of ISymbol)(comp.GetSpecialTypeMember(SpecialMember.System_IDisposable__Dispose), loopInfo0.DisposeMethod) Assert.Equal(SpecialType.System_String, loopInfo0.ElementType.SpecialType) Assert.Equal(udc, loopInfo0.ElementConversion.Method) Assert.Equal(ConversionKind.NarrowingReference, loopInfo0.CurrentConversion.Kind) Dim loopInfo1 = model.GetForEachStatementInfo(loopSyntaxes(1)) AssertEx.Equal(Of ISymbol)(comp.GetSpecialTypeMember(SpecialMember.System_Collections_IEnumerable__GetEnumerator), loopInfo1.GetEnumeratorMethod) ' No longer using System.Array method. Assert.Equal(loopInfo0.CurrentProperty, loopInfo1.CurrentProperty) Assert.Equal(loopInfo0.MoveNextMethod, loopInfo1.MoveNextMethod) Assert.Equal(loopInfo0.DisposeMethod, loopInfo1.DisposeMethod) Assert.Equal(SpecialType.System_Object, loopInfo1.ElementType.SpecialType) ' No longer string. Assert.Null(loopInfo1.ElementConversion.Method) ' No longer using UDC. Assert.Equal(ConversionKind.Identity, loopInfo1.CurrentConversion.Kind) ' Now identity End Sub Private Function SemanticInfoTypeTestForeach(compilation As VisualBasicCompilation, index As Integer, ParamArray names As String()) As SemanticInfoSummary Dim node = GetForEachStatement(compilation, index) Dim expression = node.Expression Dim model = GetModel(compilation) Dim semanticInfo = model.GetSemanticInfoSummary(expression) If "<nothing>" = names(0) Then Assert.Null(semanticInfo.Type) Else Assert.Equal(names(0), semanticInfo.Type.ToDisplayString()) End If If names.Count > 1 Then Assert.Equal(names(1), semanticInfo.ConvertedType.ToDisplayString()) If names(0) = "Object" Then If names(1) = "Object" Then Assert.True(Conversions.IsIdentityConversion(semanticInfo.ImplicitConversion.Kind)) Else Assert.True(Conversions.IsNarrowingConversion(semanticInfo.ImplicitConversion.Kind)) End If Else Assert.True(Conversions.IsWideningConversion(semanticInfo.ImplicitConversion.Kind)) End If Else Assert.Equal(names(0), semanticInfo.ConvertedType.ToDisplayString()) Assert.Equal(ConversionKind.Identity, semanticInfo.ImplicitConversion.Kind) End If Return semanticInfo End Function Private Function GetDeclareSymbolTestForeach(compilation As VisualBasicCompilation, symName As String, Optional index As Integer = 1) As Symbol Dim node = GetForEachStatement(compilation, index) Dim model = GetModel(compilation) Dim symbol = model.GetDeclaredSymbolFromSyntaxNode(node) If symName Is Nothing Then Assert.Null(symbol) Else Assert.NotNull(symbol) Assert.Equal(symName.ToLowerInvariant(), symbol.Name.ToLowerInvariant()) End If Return symbol End Function Private Function AnalyzeRegionDataFlowTestForeach(compilation As VisualBasicCompilation, VariablesDeclaredSymbol As String, ReadInsideSymbol As String, ReadOutsideSymbol As String, WrittenInsideSymbol As String, WrittenOutsideSymbol As String, AlwaysAssignedSymbol As String, DataFlowsInSymbol As String, DataFlowsOutSymbol As String, Optional index As Integer = 1) As DataFlowAnalysis Dim node = GetForEachBlock(compilation, index) Dim model = GetModel(compilation) Dim analyze = model.AnalyzeDataFlow(node, node) Assert.Equal(VariablesDeclaredSymbol, GetSymbolNamesSortedAndJoined(analyze.VariablesDeclared)) Assert.Equal(ReadInsideSymbol, GetSymbolNamesSortedAndJoined(analyze.ReadInside)) Assert.Equal(ReadOutsideSymbol, GetSymbolNamesSortedAndJoined(analyze.ReadOutside)) Assert.Equal(WrittenInsideSymbol, GetSymbolNamesSortedAndJoined(analyze.WrittenInside)) Assert.Equal(WrittenOutsideSymbol, GetSymbolNamesSortedAndJoined(analyze.WrittenOutside)) Assert.Equal(AlwaysAssignedSymbol, GetSymbolNamesSortedAndJoined(analyze.AlwaysAssigned)) Assert.Equal(DataFlowsInSymbol, GetSymbolNamesSortedAndJoined(analyze.DataFlowsIn)) Assert.Equal(DataFlowsOutSymbol, GetSymbolNamesSortedAndJoined(analyze.DataFlowsOut)) Return analyze End Function Private Function AnalyzeRegionControlFlowTestForeach( compilation As VisualBasicCompilation, Optional EntryPoints As Integer = 0, Optional ExitPoints As Integer = 0, Optional EndPointIsReachable As Boolean = True, Optional index As Integer = 1) As ControlFlowAnalysis Dim node = GetForEachBlock(compilation, index) Dim model = GetModel(compilation) Dim analyze = model.AnalyzeControlFlow(node, node) Assert.Equal(EntryPoints, analyze.EntryPoints.Count) Assert.Equal(ExitPoints, analyze.ExitPoints.Count) Assert.Equal(EndPointIsReachable, analyze.EndPointIsReachable) Return analyze End Function Private Function ClassfiConversionTestForeach(compilation As VisualBasicCompilation, Optional index As Integer = 1) As Conversion Dim node = GetForEachStatement(compilation, index) Dim expression = node.Expression Dim model = GetModel(compilation) Dim semanticInfo = model.GetSemanticInfoSummary(expression) If semanticInfo.ConvertedType Is Nothing Then Return Nothing End If Dim conv = model.ClassifyConversion(expression, semanticInfo.ConvertedType) If (conv.Kind = ConversionKind.Identity) Then Assert.True(conv.Exists) Assert.True(conv.IsIdentity) End If If (semanticInfo.Type IsNot Nothing AndAlso semanticInfo.ConvertedType IsNot Nothing AndAlso semanticInfo.Type.ToDisplayString() <> "?" AndAlso semanticInfo.Type.ToDisplayString() <> "Void" AndAlso semanticInfo.ConvertedType.ToDisplayString() <> "?" AndAlso semanticInfo.ConvertedType.ToDisplayString() <> "Void") Then Assert.Equal(conv.Kind, semanticInfo.ImplicitConversion.Kind) End If Return conv End Function Private Function GetSymbolNamesSortedAndJoined(Of T As ISymbol)(symbols As IEnumerable(Of T)) As String Return String.Join(", ", symbols.Select(Function(symbol) symbol.Name).OrderBy(Function(name) name)) End Function Private Function GetModel(compilation As VisualBasicCompilation) As SemanticModel Dim tree = compilation.SyntaxTrees.First Dim model = compilation.GetSemanticModel(tree) Return model End Function Private Function GetForEachStatement(compilation As VisualBasicCompilation, index As Integer) As ForEachStatementSyntax Dim tree = compilation.SyntaxTrees.First Dim node = tree.FindNodeOrTokenByKind(SyntaxKind.ForEachStatement, index).AsNode() Dim ForEachStatement = TryCast(node, ForEachStatementSyntax) Return ForEachStatement End Function Private Function GetForEachBlock(compilation As VisualBasicCompilation, index As Integer) As ForEachBlockSyntax Dim tree = compilation.SyntaxTrees.First Dim node = tree.FindNodeOrTokenByKind(SyntaxKind.ForEachBlock, index).AsNode() Return DirectCast(node, ForEachBlockSyntax) End Function Private Function VerifyForeachSemanticInfo(compilation As VisualBasicCompilation, Optional index As Integer = 1) As ForEachStatementInfo Dim node = GetForEachBlock(compilation, index) Dim semanticModel = GetModel(compilation) Dim foreachStatementInfo = semanticModel.GetForEachStatementInfo(node) 'Assert.Null(foreachStatementInfo.CurrentProperty) 'Assert.Null(foreachStatementInfo.DisposeMethod) 'Assert.Null(foreachStatementInfo.GetEnumeratorMethod) 'Assert.Null(foreachStatementInfo.MoveNextMethod) Return (foreachStatementInfo) End Function 'Private Function GetVariableDeclarator(compilation As VisualBasicCompilation, index As Integer) As VariableDeclaratorSyntax ' Dim node = GetForEachStatement(compilation, index) ' Dim VariableDeclarator = node.DescendantNodes.Select(Function(x) TryCast(x, VariableDeclaratorSyntax)).Where(Function(x) x IsNot Nothing).ToList() ' Assert.True(VariableDeclarator.Count() <= 1) ' Return If(VariableDeclarator.Count = 1, VariableDeclarator.First(), Nothing) 'End Function End Class End Namespace