|
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
Imports System
Imports System.Linq
Imports System.Xml.Linq
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Test.Utilities
Imports Xunit
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.FlowAnalysis
Partial Public Class FlowAnalysisTests
Inherits FlowTestBase
#Region "While, Do, Until"
<Fact()>
Public Sub TestDoLoop()
Dim analysis = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestDoLoop">
<file name="a.b">
Module Program
Sub Main()
[|
Do
Loop
|]
End Sub
End Module
</file>
</compilation>)
Dim controlFlowAnalysis = analysis.Item1
Dim dataFlowAnalysis = analysis.Item2
Assert.Equal(0, controlFlowAnalysis.ExitPoints.Count())
Assert.Equal(0, controlFlowAnalysis.EntryPoints.Count())
Assert.False(controlFlowAnalysis.EndPointIsReachable)
End Sub
<Fact()>
Public Sub TestDoLoop02()
Dim analysis = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestDoLoop02">
<file name="a.b">
Module Program
Sub Main()
[|
Do
Loop While True
|]
End Sub
End Module
</file>
</compilation>)
Dim controlFlowAnalysis = analysis.Item1
Dim dataFlowAnalysis = analysis.Item2
Assert.Equal(0, controlFlowAnalysis.ExitPoints.Count())
Assert.Equal(0, controlFlowAnalysis.EntryPoints.Count())
Assert.False(controlFlowAnalysis.EndPointIsReachable)
End Sub
<Fact()>
Public Sub TestExitStatement()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestBreakStatement">
<file name="a.b">
class C
shared sub Goo()
dim x as integer
while true
[|
exit while
while true
exit while
end while
dim y as integer
|]
end while
end sub
end class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(1, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub TestContinueStatement()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestContinueStatement">
<file name="a.b">
class C
shared sub Goo()
dim x as integer
while true
[|
continue while
while true
continue while
end while
dim y as integer
|]
end while
end sub
end class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(1, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub TestLoopWithConstantBooleanFalse()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestLoopWithConstantBooleanFalse">
<file name="a.b">
class C
shared sub Goo()
dim x as integer
[|
while false
end while
|]
end sub
end class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.Equal(True, controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub TestLoopWithConstantBooleanTrue()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestLoopWithConstantBooleanTrue">
<file name="a.b">
class C
shared sub Goo()
dim x as integer
[|
while true
end while
|]
end sub
end sub
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub TestLoopWithConstantBooleanXor()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestLoopWithConstantBooleanXor">
<file name="a.b">
class C
shared sub Goo()
dim x
[|
while true xor false
end while
|]
end sub
end class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub TestLoopWithConstantBooleanNew()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestLoopWithConstantBooleanNew">
<file name="a.b">
class C
shared sub Goo()
dim x as integer
[|
while not new boolean()
end while
|]
end sub
end class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.True(controlFlowAnalysisResults.EndPointIsReachable) 'C# is false but VB does not consider New Boolean() as a constant expression
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub TestLoopWithAssignmentInBody()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestLoopWithAssignmentInBody">
<file name="a.b">
class C
shared sub Goo()
dim x as boolean
[|
while not x
x = true
end while
|]
end sub
end class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.True(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact(), WorkItem(538421, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538421")>
Public Sub TestLoopWithConstantEnumEquality()
Dim analysisResults = CompileAndAnalyzeControlFlow(
<compilation name="TestLoopWithConstantEnumEquality">
<file name="a.b">
Imports System
Class C
Shared Sub Goo()
[|
While DayOfWeek.Sunday = 0
End While
|]
End Sub
End Class
</file>
</compilation>)
Assert.True(analysisResults.StartPointIsReachable)
Assert.False(analysisResults.EndPointIsReachable)
End Sub
<Fact()>
Public Sub TestLoopWithConstantNaNComparison()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestLoopWithConstantNaNComparison">
<file name="a.b">
class C
shared sub Goo()
dim x as integer
[|
while not 0 > double.NaN
end while
|]
end sub
end class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub TestLoopWithConstantNaNComparison2()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestLoopWithConstantNaNComparison2">
<file name="a.b">
class C
shared sub Goo()
dim x as integer
[|
while double.NaN <> double.NaN
end while
|]
end sub
end class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub TestLoopWithConstantStringEquality()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestLoopWithConstantStringEquality">
<file name="a.b">
class C
shared sub Goo()
dim x as integer
[|
while """" = """" + nothing
end while
|]
end sub
end class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub TestLoopWithEmptyBlockAfterIt()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestLoopWithEmptyBlockAfterIt">
<file name="a.b">
class C
shared sub Goo()
dim x as integer
[|
while true
end while
if true then
end if
|]
end sub
end class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub TestLoopWithUnreachableExitStatement()
Dim controlFlowAnalysisResults = CompileAndAnalyzeControlFlow(
<compilation name="TestLoopWithUnreachableExitStatement">
<file name="a.b">
class C
shared sub Main()
[|
while true
if false then
exit while
end if
end while
|]
end sub
end class
</file>
</compilation>)
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
End Sub
<Fact()>
Public Sub TestLoopWithReachableExitStatement()
Dim controlFlowAnalysisResults = CompileAndAnalyzeControlFlow(
<compilation name="TestLoopWithReachableExitStatement">
<file name="a.b">
class C
shared sub Main()
[|
while true
if true then
exit while
end while
|]
end sub
end class
</file>
</compilation>)
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.True(controlFlowAnalysisResults.EndPointIsReachable)
End Sub
<Fact()>
Public Sub TestLoopWithContinueStatement()
Dim controlFlowAnalysisResults = CompileAndAnalyzeControlFlow(
<compilation name="TestLoopWithContinueStatement">
<file name="a.b">
class C
shared sub Main()
[|
while true
continue while
end while
|]
end sub
end class
</file>
</compilation>)
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
End Sub
<Fact()>
Public Sub TestLoopWithContinueAndUnreachableExitStatement()
Dim controlFlowAnalysisResults = CompileAndAnalyzeControlFlow(
<compilation name="TestLoopWithContinueAndUnreachableExitStatement">
<file name="a.b">
class C
shared sub Main()
[|
while true
continue while
exit while
end while
|]
end sub
end class
</file>
</compilation>)
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
End Sub
<Fact()>
Public Sub TestLoopWithConstantTernaryOperator()
Dim controlFlowAnalysisResults = CompileAndAnalyzeControlFlow(
<compilation name="TestLoopWithConstantTernaryOperator">
<file name="a.b">
class C
shared sub Main()
[|
while if(true, true, true)
end while
|]
end sub
end class
</file>
</compilation>)
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
End Sub
<Fact()>
Public Sub TestLoopWithShortCircuitingOr()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestLoopWithShortCircuitingOr">
<file name="a.b">
class C
shared sub Main()
dim x as boolean
[|
while true orelse x
end while
|]
end sub
end class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<WorkItem(539303, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539303")>
<Fact()>
Public Sub DoLoopWithContinue()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="DoLoopWithContinue">
<file name="a.b">
Class A
Function Test1() As Integer
Dim x As Integer = 5
Console.Write(x)
Dim i As Integer
[|
Do
Console.Write(i)
i = i + 1
Continue Do
'Blah
Loop Until i > 5 |]
Return x
End Function
End Class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.True(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned))
Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal("Me, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<WorkItem(539303, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539303")>
<Fact()>
Public Sub DoLoopWithGoto()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="DoLoopWithGoto">
<file name="a.b">
Class A
Function Test1() As Integer
Dim x As Integer = 5
Console.Write(x)
Dim i As Integer
goto l1
[|
l2:
Do
Console.Write(i)
i = i + 1
Continue Do
'Blah
Loop Until i = 5|]
l1: goto l2
Return x
End Function
End Class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(1, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(0, controlFlowAnalysisResults.ExitPoints.Count())
Assert.False(controlFlowAnalysisResults.StartPointIsReachable)
Assert.True(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned))
Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal("i", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal("Me, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub DoWhile()
Dim dataFlowAnalysisResults = CompileAndAnalyzeDataFlow(
<compilation name="DoLoopWithGoto">
<file name="a.b">
Class A
Function Test1() As Integer
Dim x As Integer = 5
While [|x|] < 10
Console.Write(i)
i = i + 1
Continue While
'Blah
End while
End Sub
End Class
</file>
</compilation>)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal("Me, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
#End Region
#Region "For, For Each"
<WorkItem(542234, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542234")>
<Fact()>
Public Sub TestVariablesDeclaredInForLoop()
Dim analysis = CompileAndAnalyzeDataFlow(
<compilation name="TestVariablesDeclaredInForLoop">
<file name="a.b">
class C
public sub F(x as integer)
dim a as integer = 100
[|
For i = 1 To a Step x
Next
|]
dim c as integer
end sub
end class</file>\n</compilation>)
Assert.Equal("i", GetSymbolNamesJoined(analysis.VariablesDeclared))
Assert.Equal("x, a", GetSymbolNamesJoined(analysis.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(analysis.DataFlowsOut))
End Sub
<WorkItem(542234, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542234")>
<Fact()>
Public Sub TestVariablesDeclaredInForeachLoop()
Dim analysis = CompileAndAnalyzeDataFlow(
<compilation name="TestVariablesDeclaredInForeachLoop">
<file name="a.b">
class C
public sub F(x as integer)
Dim ary = New Byte() {1, 2, 3}
[|
For Each a In ary
Next
|]
int b
end sub
end class
</file>
</compilation>)
Assert.Equal("a", GetSymbolNamesJoined(analysis.VariablesDeclared))
Assert.Equal("ary", GetSymbolNamesJoined(analysis.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(analysis.DataFlowsOut))
End Sub
<Fact()>
Public Sub ForEachLoopBody()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Class C1
public shared function goo() as Integer()
return new Integer() {1,2,3}
end function
End Class
Module M
Public Sub Main()
For each unassignedRef1 as C1 in New C1() {unassignedRef1}
[|System.Console.WriteLine(unassignedRef1)
if unassignedRef1 isnot Nothing then
exit for
end if
continue for
return
|]
System.Console.WriteLine(unassignedRef1)
Next
End Sub
End Module
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.True(controlFlowAnalysisResults.Succeeded)
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count)
Assert.Equal(3, controlFlowAnalysisResults.ExitPoints.Count)
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
Assert.True(dataFlowAnalysisResults.Succeeded)
Assert.Empty(dataFlowAnalysisResults.AlwaysAssigned)
Assert.Empty(dataFlowAnalysisResults.Captured)
Assert.Equal(1, dataFlowAnalysisResults.DataFlowsIn.Count)
Assert.Equal("unassignedRef1", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Empty(dataFlowAnalysisResults.DataFlowsOut)
Assert.Equal(1, dataFlowAnalysisResults.ReadInside.Count)
Assert.Equal("unassignedRef1", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(1, dataFlowAnalysisResults.ReadOutside.Count)
Assert.Equal("unassignedRef1", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Empty(dataFlowAnalysisResults.VariablesDeclared)
Assert.Empty(dataFlowAnalysisResults.WrittenInside)
Assert.Equal(1, dataFlowAnalysisResults.WrittenOutside.Count)
Assert.Equal("unassignedRef1", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub ForEachLoopBlock()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Module M
Public Sub Main()
[|
For each x in new Integer() {}
For each y as Integer in new Integer() {}
System.Console.WriteLine(x+y)
Next y, x
|]
End Sub
End Module
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.True(dataFlowAnalysisResults.Succeeded)
Assert.Empty(dataFlowAnalysisResults.AlwaysAssigned)
Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Empty(dataFlowAnalysisResults.Captured)
Assert.Empty(dataFlowAnalysisResults.DataFlowsIn)
Assert.Empty(dataFlowAnalysisResults.DataFlowsOut)
Assert.Equal(2, dataFlowAnalysisResults.ReadInside.Count)
Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Empty(dataFlowAnalysisResults.ReadOutside)
Assert.Equal(2, dataFlowAnalysisResults.WrittenInside.Count)
Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Empty(dataFlowAnalysisResults.WrittenOutside)
Assert.True(controlFlowAnalysisResults.Succeeded)
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.True(controlFlowAnalysisResults.EndPointIsReachable)
End Sub
<Fact()>
Public Sub ForEachCollectionOnly()
Dim dataFlowAnalysisResults = CompileAndAnalyzeDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Module M
Public Sub Main()
For each x in [| new Integer() {1, 2, 3} |]
System.Console.WriteLine(x)
Next x
End Sub
End Module
</file>
</compilation>)
Assert.Empty(dataFlowAnalysisResults.AlwaysAssigned)
Assert.Empty(dataFlowAnalysisResults.VariablesDeclared)
Assert.Empty(dataFlowAnalysisResults.Captured)
Assert.Empty(dataFlowAnalysisResults.DataFlowsIn)
Assert.Empty(dataFlowAnalysisResults.DataFlowsOut)
Assert.Empty(dataFlowAnalysisResults.ReadInside)
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(0, dataFlowAnalysisResults.WrittenInside.Count)
Assert.Empty(dataFlowAnalysisResults.WrittenInside)
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub ForEachControlVariableOnly()
Dim dataFlowAnalysisResults = CompileAndAnalyzeDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Module M
Public Sub Main()
For each [| x |] in new Integer() {1, 2, 3}
System.Console.WriteLine(x)
Next x
End Sub
End Module
</file>
</compilation>)
Assert.True(dataFlowAnalysisResults.Succeeded)
Assert.Empty(dataFlowAnalysisResults.AlwaysAssigned)
Assert.Empty(dataFlowAnalysisResults.VariablesDeclared) ' should be empty, or it could not be extracted.
Assert.Empty(dataFlowAnalysisResults.Captured)
Assert.Empty(dataFlowAnalysisResults.DataFlowsIn)
Assert.Empty(dataFlowAnalysisResults.DataFlowsOut)
Assert.Empty(dataFlowAnalysisResults.ReadInside)
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Empty(dataFlowAnalysisResults.WrittenInside)
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub ForEachNextVariableOnly()
Dim dataFlowAnalysisResults = CompileAndAnalyzeDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Module M
Public Sub Main()
For each x in new Integer() {1, 2, 3}
System.Console.WriteLine(x)
Next [| x |]
End Sub
End Module
</file>
</compilation>)
Assert.False(dataFlowAnalysisResults.Succeeded)
End Sub
<Fact()>
Public Sub CannotAnalyzeAnonymousTypeFieldName()
Dim dataFlowAnalysisResults = CompileAndAnalyzeDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Module M
Public Sub Main()
Dim o = New With { . [|x|] = 1 }
End Sub
End Module
</file>
</compilation>)
Assert.False(dataFlowAnalysisResults.Succeeded)
End Sub
<Fact()>
Public Sub CanAnalyzeAnonymousTypeFieldInitializer()
Dim dataFlowAnalysisResults = CompileAndAnalyzeDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Module M
Public Sub Main()
Dim y As Integer = 1
Dim o = New With { .x = [|y|] }
End Sub
End Module
</file>
</compilation>)
Assert.False(dataFlowAnalysisResults.AlwaysAssigned.Any)
End Sub
<Fact()>
Public Sub ForEachReuseControlVariable()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation>
<file name="a.vb">
Module M
Public Sub Main()
Dim x as Integer
[|For each x in new Integer() {1, 2, x}
System.Console.WriteLine(x)
Next x|]
System.Console.WriteLine(x)
End Sub
End Module
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.True(dataFlowAnalysisResults.Succeeded)
Assert.Empty(dataFlowAnalysisResults.AlwaysAssigned)
Assert.Empty(dataFlowAnalysisResults.VariablesDeclared)
Assert.Empty(dataFlowAnalysisResults.Captured)
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Empty(dataFlowAnalysisResults.WrittenOutside)
Assert.True(controlFlowAnalysisResults.Succeeded)
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.True(controlFlowAnalysisResults.EndPointIsReachable)
End Sub
<Fact()>
Public Sub ForEachLiftedLocal()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Imports System
Module M
Public Sub Main()
Dim del as Action = nothing
For Each a In New Integer() {1, 2}
[|For Each b In New Integer() {3, 4}
Dim x as Integer = x + a + b
if a = 1 andalso b = 3 then
del = Sub() call Console.WriteLine(x)
end if
Next b, a|]
del.Invoke()
End Sub
End Module
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Assert.False(controlFlowAnalysisResults.Succeeded)
End Sub
<Fact()>
Public Sub ForEachLiftedLocal2()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Imports System
Module M
Public Sub Main()
Dim del as Action = nothing
For Each a In New Integer() {1, 2}
[|For Each b In New Integer() {3, 4}
For Each c In New Integer() {3, 4}
Dim x as Integer = x + a + b
if a = 1 andalso b = 3 then
del = Sub() call Console.WriteLine(x)
end if
Next c, b|]
del.Invoke()
End Sub
End Module
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Assert.False(controlFlowAnalysisResults.EntryPoints.Any)
End Sub
<Fact()>
Public Sub ForEachLiftedLocal3()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Imports System
Module M
Public Sub Main()
Dim del as Action = nothing
For Each a In New Integer() {1, 2}
[|For Each b In New Integer() {3, 4}
For Each c In New Integer() {3, 4}
Dim x as Integer = x + a + b
if a = 1 andalso b = 3 then
del = Sub() call Console.WriteLine(x)
end if
Next c, b, a|]
del.Invoke()
End Sub
End Module
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Assert.False(controlFlowAnalysisResults.Succeeded)
End Sub
<Fact()>
Public Sub ForEachLiftedLocal4()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Imports System
Module M
Public Sub Main()
Dim del as Action = nothing
For Each a In New Integer() {1, 2}
[|For Each b In New Integer() {3, 4}
For Each c In New Integer() {3, 4}
Dim x as Integer = x + a + b
if a = 1 andalso b = 3 then
del = Sub() call Console.WriteLine(x)
end if
Next c, b, a|]
del.Invoke()
End Sub
End Module
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Assert.False(controlFlowAnalysisResults.Succeeded)
End Sub
<Fact()>
Public Sub ForEachLiftedLocal5()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Imports System
Module M
Public Sub Main()
Dim del as Action = nothing
For Each a In New Integer() {1, 2}
[|For Each b In New Integer() {3, 4}
For Each c In New Integer() {3, 4}
Dim x as Integer = x + a + b
if a = 1 andalso b = 3 then
del = Sub() call Console.WriteLine(x)
end if
Next c, b|]
Next
del.Invoke()
End Sub
End Module
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Assert.False(controlFlowAnalysisResults.EntryPoints.Any)
End Sub
<Fact()>
Public Sub ForEachLiftedLocal6()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Imports System
Module M
Public Sub Main()
Dim del as Action = nothing
For Each a In New Integer() {1, 2}
[|For Each b In New Integer() {3, 4}
For Each c In New Integer() {3, 4}
For Each d In New Integer() {3, 4}
Dim x as Integer = x + a + b
Next d, c, b|]
Next
del.Invoke()
End Sub
End Module
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Assert.False(controlFlowAnalysisResults.EntryPoints.Any)
End Sub
<Fact()>
Public Sub ForEachLiftedLocal_CorrectRegion()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="ForEachLiftedLocal_CorrectRegion">
<file name="a.vb">
Option Infer On
Imports System
Module M
Public Sub Main()
Dim del as Action = nothing
[|For Each a In New Integer() {1, 2}
For Each b In New Integer() {3, 4}
Dim x as Integer = x + a + b
if a = 1 andalso b = 3 then
del = Sub() call Console.WriteLine(x)
end if
Next b, a|]
del.Invoke()
End Sub
End Module
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.True(dataFlowAnalysisResults.Succeeded)
Assert.True(dataFlowAnalysisResults.Succeeded)
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured))
Assert.True(controlFlowAnalysisResults.Succeeded)
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.True(controlFlowAnalysisResults.EndPointIsReachable)
End Sub
<Fact()>
Public Sub ForEachReadInsideCollection()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Option Strict On
Class C
Shared Property P1(ByVal x As Integer) As Integer
Get
Return x + 5
End Get
Set(ByVal Value As Integer)
End Set
End Property
Shared Function F(p as Integer) as Integer
return p + 1
End Function
Shared Field() as Integer = {3,4,5}
Public Shared Sub Main()
Dim X As Integer = 1
Dim Y As Integer = 1
Dim Z As Integer = 1
[|
For Each Y As Integer In New Integer() {P1(X), F(Y), Field(Z)}
Console.WriteLine(Y)
Next
|]
End Sub
End Class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.True(dataFlowAnalysisResults.Succeeded)
Assert.Equal("X, Z, Y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
End Sub
<WorkItem(542112, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542112")>
<Fact()>
Public Sub ForEachExitPoints_Failure()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation>
<file name="a.vb">
Option Strict On
Option Infer On
Public Class MyClass1
Public Shared Sub Main()
For each I in new Integer() {1, 2, 3}
[|
For each J in new Integer() {4, 5, 6}
Exit For
Next j, i
|]
End Sub
End Class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Assert.False(controlFlowAnalysisResults.Succeeded)
End Sub
<Fact()>
Public Sub ForEachExitPoints_Success()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation>
<file name="a.vb">
Option Strict On
Option Infer On
Public Class MyClass1
Public Shared Sub Main()
For each I in new Integer() {1, 2, 3}
[|
For each J in new Integer() {4, 5, 6}
Exit For
Next
|]
Next
End Sub
End Class
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Assert.True(controlFlowAnalysisResults.Succeeded)
Assert.Empty(controlFlowAnalysisResults.ExitPoints)
End Sub
<Fact()>
Public Sub Bug9014()
Xunit.Assert.Throws(Of ArgumentException)(
Sub()
Dim analysisResults =
CompileAndAnalyzeControlAndDataFlow(
<compilation>
<file name="a.vb">
Option Infer On
Module M
Public Sub Main()
For each x in [| new Integer() {1, 2, 3} |]
System.Console.WriteLine(x)
Next x
End Sub
End Module
</file>
</compilation>)
End Sub)
End Sub
<Fact()>
Public Sub ForEachVariablesDeclared()
Dim tree = VisualBasicSyntaxTree.ParseText(<file>
Public Module Program
Public Sub Main()
Dim args = new String(){ "hi" }
For Each s in args
Dim b as Integer() = new Integer(){args.Length}
Next
End Sub
End Module
</file>.Value)
Dim comp = VisualBasicCompilation.Create("ForEach",
syntaxTrees:={tree},
references:={MsvbRef, MscorlibRef})
Dim semanticModel = comp.GetSemanticModel(tree)
Dim foreachBlock = tree.GetRoot.DescendantNodes.OfType(Of ForEachBlockSyntax).Single
Dim flow = semanticModel.AnalyzeDataFlow(foreachBlock)
Assert.Equal(2, flow.VariablesDeclared.Count)
Assert.Equal(True, flow.VariablesDeclared.Any(Function(s) s.Name = "b"))
Assert.Equal(True, flow.VariablesDeclared.Any(Function(s) s.Name = "s"))
End Sub
<WorkItem(543462, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543462")>
<Fact()>
Public Sub NextStatementSyntaxInForEach()
Dim compilation = CreateCompilationWithMscorlib40AndVBRuntime(
<compilation>
<file name="a.vb">
Module Program
Sub Main(args As String())
For Each i In New Integer() {4, 5}
Next
End Sub
End Module
</file>
</compilation>)
Dim tree = compilation.SyntaxTrees.First()
Dim model = compilation.GetSemanticModel(tree)
Dim stmtNode = DirectCast(tree.GetCompilationUnitRoot().FindToken(tree.GetRoot.ToFullString().IndexOf("Next", StringComparison.Ordinal)).Parent, NextStatementSyntax)
Dim analysis = model.AnalyzeControlFlow(stmtNode, stmtNode)
Assert.False(analysis.Succeeded)
End Sub
#End Region
#Region "Goto, Label"
<Fact, WorkItem(8784, "DevDiv_Projects/Roslyn")>
Public Sub TestRegionGotoElseIf()
Dim analysis = CompileAndAnalyzeControlAndDataFlow(
<compilation name="RegionForIfElseIfWithoutElse">
<file name="a.b">
Module Program
Function Main(ByVal p As Long) As Long
Dim v = 111
[|
If 123 = p Then
Return v - 1
ElseIf -1 = p Then
L: Return p * v
ElseIf p = 1 Then
v = 222
Else
v = 212
End If
|]
goto L
End Function
End Module
</file>
</compilation>)
Dim controlFlowAnalysis = analysis.Item1
Dim dataFlowAnalysis = analysis.Item2
Assert.Equal(2, controlFlowAnalysis.ExitPoints.Count())
Assert.Equal(1, controlFlowAnalysis.EntryPoints.Count())
Assert.True(controlFlowAnalysis.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysis.VariablesDeclared))
Assert.Empty(dataFlowAnalysis.AlwaysAssigned)
Assert.Equal("p, v", GetSymbolNamesJoined(dataFlowAnalysis.DataFlowsIn))
Assert.Empty(dataFlowAnalysis.DataFlowsOut)
Assert.Equal("p, v", GetSymbolNamesJoined(dataFlowAnalysis.ReadInside))
Assert.Equal("v", GetSymbolNamesJoined(dataFlowAnalysis.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysis.ReadOutside))
Assert.Equal("p, v", GetSymbolNamesJoined(dataFlowAnalysis.WrittenOutside))
End Sub
<Fact, WorkItem(8784, "DevDiv_Projects/Roslyn")>
Public Sub TestRegionGotoDoWhile()
Dim analysis = CompileAndAnalyzeControlAndDataFlow(
<compilation name="RegionForIfElseIfWithoutElse">
<file name="a.b"><![CDATA[
Module Program
Function M(ByVal p As Long) As Long
'[|
Do While 10 <= p
L:
p = p - 3
If p < 0 Then
Return -p
End If
Loop
'|]
GoTo L
End Sub
End Module
]]></file>
</compilation>)
Dim controlFlowAnalysis = analysis.Item1
Dim dataFlowAnalysis = analysis.Item2
Assert.Equal(1, controlFlowAnalysis.ExitPoints.Count())
Assert.Equal(1, controlFlowAnalysis.EntryPoints.Count())
Assert.True(controlFlowAnalysis.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysis.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysis.AlwaysAssigned))
Assert.Equal("p", GetSymbolNamesJoined(dataFlowAnalysis.DataFlowsIn))
Assert.Empty(dataFlowAnalysis.DataFlowsOut)
Assert.Equal("p", GetSymbolNamesJoined(dataFlowAnalysis.ReadInside))
Assert.Equal("p", GetSymbolNamesJoined(dataFlowAnalysis.WrittenInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysis.ReadOutside))
Assert.Equal("p", GetSymbolNamesJoined(dataFlowAnalysis.WrittenOutside))
End Sub
<Fact, WorkItem(543399, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543399")>
Public Sub GotoLabelName()
Dim dataFlowResults = CompileAndAnalyzeDataFlow(
<compilation>
<file name="a.vb">
Module Program
Sub Main(args As String())
GoTo [|45|]
End Sub
End Module
</file>
</compilation>)
Assert.False(dataFlowResults.Succeeded)
End Sub
#End Region
#Region "Return"
<Fact()>
Public Sub TestReturnStatements01()
Dim analysis = CompileAndAnalyzeControlFlow(
<compilation name="TestReturnStatements01">
<file name="a.b">
class C
public sub F(x as integer)
[|
return
|]
end sub
end class
</file>
</compilation>)
Assert.Equal(1, analysis.ExitPoints.Count())
End Sub
<Fact()>
Public Sub TestReturnStatements02()
Dim analysis = CompileAndAnalyzeControlFlow(
<compilation name="TestReturnStatements02">
<file name="a.b">
class C
public sub F(x as integer)
if x = 0 then return
[|
if x = 1 then return
|]
if x = 2 then return
end sub
end class
</file>
</compilation>)
Assert.Equal(1, analysis.ExitPoints.Count())
End Sub
<WorkItem(539295, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539295")>
<Fact()>
Public Sub TestReturnStatements03()
Dim analysis = CompileAndAnalyzeControlFlow(
<compilation name="TestReturnStatements03">
<file name="a.b">
class C
public sub F(x as integer)
if x = 0 then return
[|
if x = 1 then exit sub
|]
if x = 2 then return
end sub
end class
</file>
</compilation>)
Assert.Equal(1, analysis.ExitPoints.Count())
Assert.Equal(0, analysis.EntryPoints.Count())
Assert.True(analysis.StartPointIsReachable)
Assert.True(analysis.EndPointIsReachable)
End Sub
<WorkItem(539295, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539295")>
<Fact()>
Public Sub TestReturnStatements03a()
Dim analysis = CompileAndAnalyzeControlFlow(
<compilation name="TestReturnStatements03a">
<file name="a.b">
class C
public sub F(x as integer)
if True then return
[|
if x = 1 then exit sub
|]
if x = 2 then return
end sub
end class
</file>
</compilation>)
Assert.Equal(1, analysis.ExitPoints.Count())
Assert.Equal(0, analysis.EntryPoints.Count())
Assert.False(analysis.StartPointIsReachable)
Assert.False(analysis.EndPointIsReachable)
End Sub
<WorkItem(539295, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539295")>
<Fact()>
Public Sub TestReturnStatements04()
Dim analysis = CompileAndAnalyzeControlFlow(
<compilation name="TestReturnStatements03">
<file name="a.b">
class C
public function F(x as integer) as integer
if x = 0 then return
[|
if x = 1 then exit function
|]
if x = 2 then return
end sub
end class
</file>
</compilation>)
Assert.Equal(1, analysis.ExitPoints.Count())
Assert.Equal(0, analysis.EntryPoints.Count())
Assert.True(analysis.EndPointIsReachable)
End Sub
<Fact()>
Public Sub TestReturnStatement()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestReturnStatement">
<file name="a.b">
module C
sub Main()
dim x as integer = 1, y as integer = x
[|
return
|]
dim z as integer = (y) + 1
end sub
end module
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(1, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal("x, y, z", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub TestReturnStatementWithParenthesizedExpression()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestReturnStatementWithParenthesizedExpression">
<file name="a.b">
module C
function Goo() as integer
dim x as integer = 1, y as integer = x
[|
return (y) + 1
|]
end function
end module
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(1, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
<Fact()>
Public Sub TestReturnStatementWithExpression()
Dim analysisResults = CompileAndAnalyzeControlAndDataFlow(
<compilation name="TestReturnStatementWithExpression">
<file name="a.b">
module C
function Goo() as integer
dim x as integer = 0
[|
x = 1
return x
|]
end function
end module
</file>
</compilation>)
Dim controlFlowAnalysisResults = analysisResults.Item1
Dim dataFlowAnalysisResults = analysisResults.Item2
Assert.Equal(0, controlFlowAnalysisResults.EntryPoints.Count())
Assert.Equal(1, controlFlowAnalysisResults.ExitPoints.Count())
Assert.True(controlFlowAnalysisResults.StartPointIsReachable)
Assert.False(controlFlowAnalysisResults.EndPointIsReachable)
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside))
Assert.Equal(Nothing, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside))
Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside))
End Sub
#End Region
#Region "Yield Return"
#End Region
End Class
End Namespace
|