|
' 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.Collections.Generic
Imports System.IO
Imports System.Linq
Imports System.Text
Imports System.Xml.Linq
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Test.Utilities
Imports Xunit
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Emit
Public Class ImplicitVariableTests
Inherits SemanticModelTestBase
<Fact>
Public Sub SimpleImplicitDeclaration()
Dim compilation = CompileAndVerify(
<compilation name="SimpleImplicitDeclaration">
<file name="a.vb">
Option Explicit Off
Option Strict On
Imports System
Module Module1
Sub Main()
x = "Hello"
dim y as string = "world"
i% = 3
While i > 0
Console.WriteLine("{0}, {1}", x, y)
Console.WriteLine(i)
i = i% - 1
End While
End Sub
End Module
</file>
</compilation>,
expectedOutput:=<![CDATA[
Hello, world
3
Hello, world
2
Hello, world
1
]]>)
compilation.VerifyDiagnostics()
End Sub
<WorkItem(547017, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/547017")>
<WorkItem(547018, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/547018")>
<ConditionalFact(GetType(WindowsDesktopOnly), Reason:="https://github.com/dotnet/roslyn/issues/28044")>
Public Sub SimpleImplicitDeclaration2()
Dim compilation = CompileAndVerify(
<compilation>
<file name="a.vb">
Option Strict On
Option Explicit Off
Imports Microsoft.VisualBasic.FileSystem
Module Program
Sub Main(args As String())
If Microsoft.VisualBasic.InStr(CurDir(), "\") <> 0 Then
sep$ = "\"
Else
sep$ = ":"
End If
Dim ResPath As String = CurDir() + sep$
If "" <> "" Then
On Error Resume Next
End If
End Sub
End Module
</file>
</compilation>,
expectedOutput:="")
compilation.VerifyDiagnostics()
End Sub
<Fact>
Public Sub ImplicitDeclarationDataFlow()
Dim compilation = CompileAndVerify(
<compilation name="ImplicitDeclarationDataFlow">
<file name="a.vb">
Option Explicit Off
Option Strict On
Imports System
Module Module1
Sub Main()
Console.WriteLine(x)
x = "Hello, world"
Dim y, z As String
While i% < 4
Console.WriteLine(x)
Console.WriteLine(i)
i = i% + 1
End While
z = "hi"
Console.WriteLine(Y)
Console.WriteLine(z)
End Sub
End Module
</file>
</compilation>,
expectedOutput:=<![CDATA[
Hello, world
0
Hello, world
1
Hello, world
2
Hello, world
3
hi
]]>)
compilation.VerifyDiagnostics(
Diagnostic(ERRID.WRN_DefAsgUseNullRef, "x").WithArguments("x"),
Diagnostic(ERRID.WRN_DefAsgUseNullRef, "Y").WithArguments("y"))
End Sub
<Fact>
Public Sub ImplicitWithReturnValueVariable()
Dim compilation = CompileAndVerify(
<compilation name="ImplicitWithReturnValueVariable">
<file name="a.vb">
Option Explicit Off
Option Strict On
Imports System
Module Module1
Function Goo(q As Integer) As Integer
Goo = 10
bar = Goo + q
Goo = CInt(bar) + 7
End Function
Sub Main()
i% = Goo(3)
While i > 0
Console.Write("{0} ", i)
i = i% - 1
End While
Console.WriteLine()
End Sub
End Module
</file>
</compilation>,
expectedOutput:=<![CDATA[
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
]]>)
compilation.VerifyDiagnostics()
End Sub
<Fact>
Public Sub ImplicitInLambda()
Dim compilation = CompileAndVerify(
<compilation name="ImplicitInLambda">
<file name="a.vb">
Option Explicit Off
Option Strict On
Imports System
Module Module1
Function Z(lam As Func(Of Integer, Integer)) As Integer
r% = r% + 1
Z = lam(4) + lam(1) + r%
End Function
Function Z(lam As Func(Of Long, Long)) As Integer
Return CInt(lam(7) + lam(11))
End Function
Function Goo(p As Integer) As Integer
Return Z(Function(z)
q% = q% + 1
Return z + q%
End Function)
End Function
Sub Main()
Console.WriteLine(Goo(4))
End Sub
End Module
</file>
</compilation>,
expectedOutput:=<![CDATA[
9
]]>)
compilation.VerifyDiagnostics()
End Sub
<Fact>
Public Sub InaccessibleVariable()
Dim compilation = CompileAndVerify(
<compilation name="ImplicitInLambda">
<file name="a.vb">
Option Explicit Off
Option Strict On
Imports System
Module Module1
Sub Main()
Console.WriteLine(New C2().goo("hello"))
End Sub
End Module
Class C1
Private var As Integer
End Class
Class C2
Inherits C1
Public Function goo(x As String) As Object
var = x
Return var
End Function
End Class </file>
</compilation>,
expectedOutput:=<![CDATA[
hello
]]>)
compilation.VerifyDiagnostics()
End Sub
<Fact>
Public Sub NoImplicitDeclInInitializer()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation name="NoImplicitDeclInInitializer">
<file name="a.vb">
Option Explicit Off
Option Strict On
Imports System
Class C1
Private var As Integer = goo
End Class
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<expected>
BC30451: 'goo' is not declared. It may be inaccessible due to its protection level.
Private var As Integer = goo
~~~
</expected>)
End Sub
<Fact>
Public Sub ImplicitInLambda2()
Dim compilation = CompileAndVerify(
<compilation name="ImplicitInLambda2">
<file name="a.vb">
Option Explicit Off
Option Strict On
Option Infer On
Imports System
Module Module1
Sub Main()
Dim y As Integer = DirectCast(Function()
x% = x% + 1
Return x%
End Function, Func(Of Integer)).Invoke() +
DirectCast(Function()
x% = x% + 1
Return x%
End Function, Func(Of Integer)).Invoke()
Console.WriteLine(y)
End Sub
End Module
</file>
</compilation>, expectedOutput:=<![CDATA[
3
]]>)
compilation.VerifyDiagnostics()
End Sub
<Fact>
Public Sub ImplicitInLambdaInInitializer()
Dim compilation = CompileAndVerify(
<compilation name="ImplicitInLambdaInInitializer">
<file name="a.vb">
Option Explicit Off
Option Strict On
Option Infer On
Imports System
Module Module1
Dim y As Integer = InvokeMultiple(Function()
x% = x% + 1
Return x%
End Function, 2) +
InvokeMultiple(Function()
x% = x% + 1
Return x%
End Function, 7)
Function InvokeMultiple(f As Func(Of Integer), times As Integer) As Integer
Dim result As Integer = 0
For i As Integer = 1 To times
result = f()
Next
Return result
End Function
Sub Main()
Console.WriteLine(y)
End Sub
End Module
</file>
</compilation>, expectedOutput:=<![CDATA[
2
]]>)
compilation.VerifyDiagnostics()
End Sub
<Fact>
Public Sub ImplicitInLambdaInInitializer2()
Dim compilation = CompileAndVerify(
<compilation name="ImplicitInLambdaInInitializer">
<file name="a.vb">
Option Explicit Off
Option Strict On
Option Infer On
Imports System
Module Module1
Dim y As Integer = InvokeMultiple(Function()
dim a As Integer
x% = x% + 1
a = 5
a = a + 1
Console.WriteLine(x%)
Console.WriteLine(a)
Return x%
End Function, 2)
Function InvokeMultiple(f As Func(Of Integer), times As Integer) As Integer
Dim result As Integer = 0
For i As Integer = 1 To times
result = f()
Next
Return result
End Function
Sub Main()
Console.WriteLine(y)
End Sub
End Module
</file>
</compilation>, expectedOutput:=<![CDATA[
1
6
1
6
1
]]>)
compilation.VerifyDiagnostics()
End Sub
<Fact>
Public Sub ImplicitInSingleLineLambdaInInitializer()
' Note DEV10 does not alloc implicit variable declaration in Single line function lambda.
' This restriction is relaxed in Roslyn.
Dim compilation = CompileAndVerify(
<compilation name="ImplicitInSingleLineLambdaInInitializer">
<file name="a.vb">
Option Explicit Off
Option Strict On
Option Infer On
Imports System
Module Module1
Dim y As Integer = InvokeMultiple(Function() Increment(x%), 2) +
InvokeMultiple(Function() Increment(x%), 7)
Function Increment(ByRef a As Integer) As Integer
a = a + 1
Return a
End Function
Function InvokeMultiple(f As Func(Of Integer), times As Integer) As Integer
Dim result As Integer = 0
For i As Integer = 1 To times
result = f()
Next
Return result
End Function
Sub Main()
Console.WriteLine(y)
End Sub
End Module
</file>
</compilation>, expectedOutput:=<![CDATA[
2
]]>)
compilation.VerifyDiagnostics()
End Sub
<Fact>
Public Sub NoImplicitDeclInAttribute()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation name="NoImplicitDeclInInitializer">
<file name="a.vb">
<![CDATA[
Option Explicit Off
Option Strict On
Imports System
Class C1
<Obsolete(zack)>
Private var As Integer
End Class
]]>
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<expected>
<![CDATA[
BC30451: 'zack' is not declared. It may be inaccessible due to its protection level.
<Obsolete(zack)>
~~~~
]]></expected>)
End Sub
<Fact>
Public Sub NoImplicitDeclLeftOfDot()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation name="NoImplicitDeclLeftOfDot">
<file name="a.vb">
<![CDATA[
Option Explicit Off
Option Strict On
Imports System
Class C1
Sub Goo()
Dim x As String = y.ToString()
End Sub
End Class
]]>
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<expected>
<![CDATA[
BC30451: 'y' is not declared. It may be inaccessible due to its protection level.
Dim x As String = y.ToString()
~
]]></expected>)
End Sub
<Fact>
Public Sub NoImplicitDeclInvocation()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation name="NoImplicitDeclInvocation">
<file name="a.vb">
<![CDATA[
Option Explicit Off
Option Strict On
Imports System
Class C1
Sub Goo()
Dim x As String = y()
End Sub
End Class
]]>
</file>
</compilation>)
CompilationUtils.AssertTheseDiagnostics(compilation,
<expected>
<![CDATA[
BC30451: 'y' is not declared. It may be inaccessible due to its protection level.
Dim x As String = y()
~
]]></expected>)
End Sub
<Fact()>
Public Sub ImplicitInFor()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation name="ImplicitInFor">
<file name="a.vb">
<![CDATA[
Option Explicit Off
Option Strict On
Option Infer On
Imports System
Class C1
Sub Goo()
For x = 1 To 10
x.GetTypeCode()
Next
End Sub
End Class
]]>
</file>
</compilation>)
' Inference in For should infer "integer" for x, even with option explicit off.
CompilationUtils.AssertNoErrors(compilation)
End Sub
<Fact>
Public Sub HidingEnclosingBlock1()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation name="HidingEnclosingBlock1">
<file name="a.vb">
<![CDATA[
Option Explicit Off
Option Strict On
Option Infer On
Imports System
Module Module1
Sub Main()
x% = 10
Dim y% = 0
While y% < 10
Dim x As String
x = "hi"
y% = y% + 1
End While
End Sub
End Module
]]>
</file>
</compilation>)
' Simple case -- implicit variable declared before enclosed block
CompilationUtils.AssertTheseDiagnostics(compilation,
<expected>
<![CDATA[
BC30616: Variable 'x' hides a variable in an enclosing block.
Dim x As String
~
]]></expected>)
End Sub
<Fact>
Public Sub HidingEnclosingBlock2()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation name="HidingEnclosingBlock2">
<file name="a.vb">
<![CDATA[
Option Explicit Off
Option Strict On
Option Infer On
Imports System
Module Module1
Sub Main()
Dim y% = 0
While y% < 10
Dim X As String
x = "hi"
y% = y% + 1
End While
x% = 10
End Sub
End Module
]]>
</file>
</compilation>)
' Tricky case -- implicit variable declared AFTER enclosed block
CompilationUtils.AssertTheseDiagnostics(compilation,
<expected>
<![CDATA[
BC30616: Variable 'X' hides a variable in an enclosing block.
Dim X As String
~
]]></expected>)
End Sub
<Fact>
Public Sub HidingEnclosingBlock3()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation name="HidingEnclosingBlock3">
<file name="a.vb">
<![CDATA[
Option Explicit Off
Option Strict On
Option Infer On
Imports System
Module Module1
Sub Main()
x% = 10
y% = 0
While y% < 10
Dim q As Action(Of Integer) = Sub(x)
Dim y As Integer = 4
y = y + 1
End Sub
End While
End Sub
End Module
]]>
</file>
</compilation>)
' Simple case -- implicit variable declared before enclosed block
CompilationUtils.AssertTheseDiagnostics(compilation,
<expected>
<![CDATA[
BC36641: Lambda parameter 'x' hides a variable in an enclosing block, a previously defined range variable, or an implicitly declared variable in a query expression.
Dim q As Action(Of Integer) = Sub(x)
~
BC30616: Variable 'y' hides a variable in an enclosing block.
Dim y As Integer = 4
~
]]></expected>)
End Sub
<Fact>
Public Sub HidingEnclosingBlock4()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation name="HidingEnclosingBlock4">
<file name="a.vb">
<![CDATA[
Option Explicit Off
Option Strict On
Option Infer On
Imports System
Module Module1
Sub Main()
While y% < 10
Dim q As Action(Of Integer) = Sub(x)
Dim y As Integer = 4
y = y + 1
End Sub
End While
x% = 10
y% = 0
End Sub
End Module
]]>
</file>
</compilation>)
' Trick case -- implicit variable declared after enclosed block
CompilationUtils.AssertTheseDiagnostics(compilation,
<expected>
<![CDATA[
BC36641: Lambda parameter 'x' hides a variable in an enclosing block, a previously defined range variable, or an implicitly declared variable in a query expression.
Dim q As Action(Of Integer) = Sub(x)
~
BC30616: Variable 'y' hides a variable in an enclosing block.
Dim y As Integer = 4
~
]]></expected>)
End Sub
<Fact>
Public Sub ReservedNames()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation name="HidingEnclosingBlock4">
<file name="a.vb">
<![CDATA[
Option Explicit Off
Option Strict On
Imports System
Module Module1
Sub Main()
x = Null
y = Rnd()
z = Empty
q = r
End Sub
End Module
]]>
</file>
</compilation>)
' Dev10 disallows implicit variable creation for certain names.
CompilationUtils.AssertTheseDiagnostics(compilation,
<expected>
<![CDATA[
BC30451: 'Null' is not declared. It may be inaccessible due to its protection level.
x = Null
~~~~
BC30451: 'Rnd' is not declared. It may be inaccessible due to its protection level.
y = Rnd()
~~~
BC30389: 'System.Empty' is not accessible in this context because it is 'Friend'.
z = Empty
~~~~~
BC42104: Variable 'r' is used before it has been assigned a value. A null reference exception could result at runtime.
q = r
~
]]></expected>)
End Sub
<WorkItem(542455, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542455")>
<Fact>
Public Sub VariableAcrossIfParts()
CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation>
<file name="a.vb">
<![CDATA[
Option Explicit Off
Option Strict Off
Module Module1
Sub Main()
If y > 10 Then
y = ">10" + x
ElseIf y < 10 Then
y = "<10" + x
End If
End Sub
End Module]]>
</file>
</compilation>).VerifyDiagnostics(
Diagnostic(ERRID.WRN_DefAsgUseNullRef, "y").WithArguments("y"),
Diagnostic(ERRID.WRN_DefAsgUseNullRef, "x").WithArguments("x"))
End Sub
<WorkItem(542455, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542455")>
<Fact>
Public Sub VariableAcrossIfParts2()
CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(
<compilation>
<file name="a.vb">
<![CDATA[
Option Explicit Off
Option Strict Off
Module Module1
Sub Main()
If y > 10 Then
a = ">10" + x
ElseIf z < 10 Then
b = "<10" + x
End If
End Sub
End Module]]>
</file>
</compilation>).VerifyDiagnostics(
Diagnostic(ERRID.WRN_DefAsgUseNullRef, "y").WithArguments("y"),
Diagnostic(ERRID.WRN_DefAsgUseNullRef, "x").WithArguments("x"),
Diagnostic(ERRID.WRN_DefAsgUseNullRef, "z").WithArguments("z"))
End Sub
<WorkItem(542530, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542530")>
<Fact>
Public Sub LambdaBindingOrder()
Dim compilation = CompileAndVerify(
<compilation name="SimpleImplicitDeclaration">
<file name="a.vb">
Option Explicit Off
Option Strict On
Imports System
Module Module1
Sub f(x As Integer, y As Integer)
Console.WriteLine("hello")
End Sub
Sub g(x As Func(Of Integer), y As Integer)
Console.WriteLine("world")
End Sub
Sub Main()
f(a%, a)
g(Function() b + c%, b%) ' this should be error, but isn't
Console.WriteLine("done")
End Sub
End Module
</file>
</compilation>,
expectedOutput:=<![CDATA[
hello
world
done
]]>)
' This should be an error (because b is declared implicitly without a type character
' first), but isn't in both Dev10 and Roslyn.
compilation.VerifyDiagnostics()
End Sub
#Region "GetSemanticInfo Tests"
<Fact>
Public Sub BindImplicitVariableAsLeftHandSideOfAssignment()
VerifyImplicitDeclarationSemanticInfo(<![CDATA[
x = 1'BIND:"x"
]]>)
End Sub
<Fact>
Public Sub BindImplicitVariableAsRightHandSideOfAssignment()
VerifyImplicitDeclarationSemanticInfo(<![CDATA[
y = x'BIND:"x"
]]>)
End Sub
<Fact>
Public Sub BindImplicitVariableInExpression()
VerifyImplicitDeclarationSemanticInfo(<![CDATA[
y = y Is x'BIND:"x"
]]>)
End Sub
<Fact>
Public Sub BindImplicitVariableAsMethodArgument()
VerifyImplicitDeclarationSemanticInfo(<![CDATA[
System.Console.WriteLine(x)'BIND:"x"
]]>)
End Sub
<Fact>
Public Sub BindImplicitVariableInSingleLineLambda()
VerifyImplicitDeclarationSemanticInfo(<![CDATA[
Dim f As Func(Of Object) = Function() x'BIND:"x"
]]>)
End Sub
<Fact>
Public Sub BindImplicitVariableInMultiLineLambda()
VerifyImplicitDeclarationSemanticInfo(<![CDATA[
Dim f As Func(Of Object) = Function()
Return x'BIND:"x"
End Function
]]>)
End Sub
<Fact>
Public Sub BindImplicitVariableWhenConflictsWithExplicitVariable()
VerifyImplicitDeclarationSemanticInfo(<![CDATA[
If True Then
Dim x = 1
End If
x = 1'BIND:"x"
]]>)
End Sub
#End Region
#Region "BindExpression Tests"
<Fact(), WorkItem(546396, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546396")>
Public Sub SpeculativeBindImplicitVariableAsLeftHandSideOfOfAssignment()
VerifyImplicitDeclarationBindExpression(<![CDATA[
'BIND
]]>,
expression:="x",
expectedTypeName:="System.Object",
symbolKind:=SymbolKind.Local)
End Sub
<Fact(), WorkItem(546396, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546396")>
Public Sub SpeculativeBindImplicitVariableAsMethodArgument()
VerifyImplicitDeclarationBindExpression(<![CDATA[
'BIND
]]>,
expression:="System.Console.WriteLine(x)",
expectedTypeName:="System.Void",
symbolKind:=SymbolKind.Method)
End Sub
<Fact>
Public Sub SpeculativeBindImplicitVariableInSingleLineLambda()
VerifyImplicitDeclarationBindExpression(<![CDATA[
Dim f As Func(Of Object) = Function() x'BIND
]]>,
expression:="y Is x",
expectedTypeName:="System.Boolean")
End Sub
<Fact>
Public Sub SpeculativeBindImplicitVariableWhenConflictsWithExplicitVariable()
VerifyImplicitDeclarationBindExpression(<![CDATA[
If True Then
Dim x = 1
End If
'BIND
]]>,
expression:="x = 1",
expectedTypeName:="System.Object",
symbolKind:=SymbolKind.Method,
expectedSymbol:="Function System.Object.op_Equality(left As System.Object, right As System.Object) As System.Object")
End Sub
<Fact>
Public Sub SpeculativeBindImplicitVariableDeclarationInOuterScope()
VerifyImplicitDeclarationBindExpression(<![CDATA[
If True Then
x% = 1
End If
'BIND
]]>,
expression:="x + 1",
expectedTypeName:="System.Int32",
symbolKind:=SymbolKind.Method,
expectedSymbol:="Function System.Int32.op_CheckedAddition(left As System.Int32, right As System.Int32) As System.Int32")
End Sub
#End Region
#Region "LookupSymbols Tests"
<Fact>
Public Sub LookupImplicitVariableOnRightHandSideOfAssignment()
VerifyImplicitDeclarationLookupSymbols(<![CDATA[
x =
1'BIND:"1"
]]>,
expected:={"x"})
End Sub
<Fact>
Public Sub LookupImplicitVariableInExpression()
VerifyImplicitDeclarationLookupSymbols(<![CDATA[
x = y Is
o'BIND:"o"
]]>,
expected:={"x", "y"})
End Sub
<Fact>
Public Sub LookupImplicitVariableInSingleLineLambda()
VerifyImplicitDeclarationLookupSymbols(<![CDATA[
Dim f As Func(Of Object) = Function() 1'BIND:"1"
x = 1
]]>,
expected:={"x"})
End Sub
<Fact>
Public Sub LookupImplicitVariableDeclaredInInnerScope()
VerifyImplicitDeclarationLookupSymbols(<![CDATA[
If True Then
x = 1
End If
y = 1'BIND:"y"
]]>,
expected:={"x"})
End Sub
<Fact>
Public Sub LookupImplicitVariableDeclaredInOuterScope()
VerifyImplicitDeclarationLookupSymbols(<![CDATA[
If True Then
y = y'BIND:"y"
End If
x = 1
]]>,
expected:={"x"})
End Sub
<WorkItem(1036381, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1036381")>
<Fact>
Public Sub Bug1036381_01()
Dim source =
<compilation>
<file name="a.vb">
Option Explicit Off
Module Program
Sub Main(args As String())
x = 1
Console.WriteLine(x)
End Sub
End Module
</file>
</compilation>
Dim compilation1 = CreateCompilationWithMscorlib40AndVBRuntime(source)
Dim tree = compilation1.SyntaxTrees.Single()
Dim model = compilation1.GetSemanticModel(tree)
Dim main1 = tree.GetRoot().DescendantNodes().OfType(Of MethodBlockBaseSyntax)().Single()
Dim position = main1.Statements.First.SpanStart
Dim compilation2 = CreateCompilationWithMscorlib40AndVBRuntime(source)
Dim main2 = compilation2.SyntaxTrees.Single().GetRoot().DescendantNodes().OfType(Of MethodBlockBaseSyntax)().Single()
Dim speculative As SemanticModel = Nothing
Assert.True(model.TryGetSpeculativeSemanticModelForMethodBody(position, main2, speculative))
Dim l1 = speculative.LookupSymbols(position, name:="x").Single()
Assert.NotNull(l1)
Assert.Equal(SymbolKind.Local, l1.Kind)
Dim l2 = model.LookupSymbols(position, name:="x").Single()
Assert.NotNull(l2)
Assert.Equal(SymbolKind.Local, l2.Kind)
Assert.NotEqual(l1, l2)
End Sub
<WorkItem(1036381, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1036381")>
<Fact>
Public Sub Bug1036381_02()
Dim source =
<compilation>
<file name="a.vb">
Option Explicit Off
Module Program
Sub Main(args As String())
x = 1
Console.WriteLine(x)
End Sub
End Module
</file>
</compilation>
Dim compilation1 = CreateCompilationWithMscorlib40AndVBRuntime(source)
Dim tree = compilation1.SyntaxTrees.Single()
Dim model = compilation1.GetSemanticModel(tree)
Dim main1 = tree.GetRoot().DescendantNodes().OfType(Of MethodBlockBaseSyntax)().Single()
Dim position = main1.Statements.First.SpanStart
Dim compilation2 = CreateCompilationWithMscorlib40AndVBRuntime(source)
Dim main2 = compilation2.SyntaxTrees.Single().GetRoot().DescendantNodes().OfType(Of MethodBlockBaseSyntax)().Single()
Dim speculative As SemanticModel = Nothing
Assert.True(model.TryGetSpeculativeSemanticModelForMethodBody(position, main2, speculative))
Dim l2 = model.LookupSymbols(position, name:="x").Single()
Assert.NotNull(l2)
Assert.Equal(SymbolKind.Local, l2.Kind)
Dim l1 = speculative.LookupSymbols(position, name:="x").Single()
Assert.NotNull(l1)
Assert.Equal(SymbolKind.Local, l1.Kind)
Assert.NotEqual(l1, l2)
End Sub
#End Region
#Region "Tuples"
<WorkItem(14292, "https://github.com/dotnet/roslyn/issues/14292")>
<Fact>
Public Sub NotDeclaredTupleDeconstructionsAreConsideredObjects_ExplicitOff()
Dim compilation = CreateCompilationWithMscorlib40AndVBRuntime(
<compilation><file name="a.vb">
Option Explicit Off
Module TestModule
Sub Main()
Dim tuple = (member1, member2)
System.Console.WriteLine(tuple) 'BIND1:"tuple"
End Sub
End Module
</file></compilation>,
additionalRefs:={ValueTupleRef, SystemRuntimeFacadeRef},
options:=New VisualBasicCompilationOptions(OutputKind.ConsoleApplication))
CompilationUtils.AssertTheseDiagnostics(compilation,
<expected>
<![CDATA[
BC42104: Variable 'member1' is used before it has been assigned a value. A null reference exception could result at runtime.
Dim tuple = (member1, member2)
~~~~~~~
BC42104: Variable 'member2' is used before it has been assigned a value. A null reference exception could result at runtime.
Dim tuple = (member1, member2)
~~~~~~~
]]></expected>)
Dim model = GetSemanticModel(compilation, "a.vb")
Dim tupleSyntax = CompilationUtils.FindBindingText(Of IdentifierNameSyntax)(compilation, "a.vb", 1)
Dim tupleSymbolInfo = model.GetSymbolInfo(tupleSyntax)
Assert.NotNull(tupleSymbolInfo.Symbol)
Dim tupleSymbol = TryCast(tupleSymbolInfo.Symbol, LocalSymbol)
Assert.NotNull(tupleSymbol)
Assert.Equal("tuple", tupleSymbol.Name)
Assert.Equal(2, tupleSymbol.Type.TupleElementTypes.Length)
Assert.Equal("Object", tupleSymbol.Type.TupleElementTypes(0).Name)
Assert.Equal("Object", tupleSymbol.Type.TupleElementTypes(1).Name)
End Sub
<WorkItem(14292, "https://github.com/dotnet/roslyn/issues/14292")>
<Fact>
Public Sub NotDeclaredTupleDeconstructionsProduceErrors_ExplicitOn()
Dim compilation = CreateCompilationWithMscorlib40AndVBRuntime(
<compilation><file name="a.vb">
Option Explicit On
Module TestModule
Sub Main()
Dim tuple = (member1, member2)
System.Console.WriteLine(tuple)
End Sub
End Module
</file></compilation>,
additionalRefs:={ValueTupleRef, SystemRuntimeFacadeRef},
options:=New VisualBasicCompilationOptions(OutputKind.ConsoleApplication))
CompilationUtils.AssertTheseDiagnostics(compilation,
<expected>
<![CDATA[
BC30451: 'member1' is not declared. It may be inaccessible due to its protection level.
Dim tuple = (member1, member2)
~~~~~~~
BC30451: 'member2' is not declared. It may be inaccessible due to its protection level.
Dim tuple = (member1, member2)
~~~~~~~
]]></expected>)
End Sub
<WorkItem(14292, "https://github.com/dotnet/roslyn/issues/14292")>
<Fact>
Public Sub DeclaringImplicitlyDeclaredTupleArgumentsAgainInSameScopeErrorsOut()
Dim compilation = CreateCompilationWithMscorlib40AndVBRuntime(
<compilation><file name="a.vb">
Option Explicit Off
Module TestModule
Sub Main()
Dim tuple = (notDeclaredYet, 0)
Dim notDeclaredYet = 0
End Sub
End Module
</file></compilation>,
additionalRefs:={ValueTupleRef, SystemRuntimeFacadeRef},
options:=New VisualBasicCompilationOptions(OutputKind.ConsoleApplication))
CompilationUtils.AssertTheseDiagnostics(compilation,
<expected>
<![CDATA[
BC32000: Local variable 'notDeclaredYet' cannot be referred to before it is declared.
Dim tuple = (notDeclaredYet, 0)
~~~~~~~~~~~~~~
]]></expected>)
End Sub
<WorkItem(14292, "https://github.com/dotnet/roslyn/issues/14292")>
<Fact>
Public Sub DeclaringImplicitlyDeclaredTupleArgumentsAgainInAnotherScopeErrorsOut()
Dim compilation = CreateCompilationWithMscorlib40AndVBRuntime(
<compilation><file name="a.vb">
Option Explicit Off
Module TestModule
Sub Main()
Dim tuple As (Integer, Integer)
If False Then
tuple = (notDefinedYet1, notDefinedYet2)
End If
Dim notDefinedYet2 = 0
End Sub
End Module
</file></compilation>,
additionalRefs:={ValueTupleRef, SystemRuntimeFacadeRef},
options:=New VisualBasicCompilationOptions(OutputKind.ConsoleApplication))
CompilationUtils.AssertTheseDiagnostics(compilation,
<expected>
<![CDATA[
BC42104: Variable 'notDefinedYet1' is used before it has been assigned a value. A null reference exception could result at runtime.
tuple = (notDefinedYet1, notDefinedYet2)
~~~~~~~~~~~~~~
BC32000: Local variable 'notDefinedYet2' cannot be referred to before it is declared.
tuple = (notDefinedYet1, notDefinedYet2)
~~~~~~~~~~~~~~
]]></expected>)
End Sub
<WorkItem(14292, "https://github.com/dotnet/roslyn/issues/14292")>
<Fact>
Public Sub TupleArgumentsAreNotConsideredAsImplicitVariables()
VerifyImplicitDeclarationLookupSymbols(<![CDATA[
Dim tuple = (a: a, b: 0) 'BIND:"a"
]]>,
expected:={"a"}) ' No "b" there
End Sub
#End Region
#Region "Helpers"
Friend Shared Function GetSourceXElementFromTemplate(code As XCData) As XElement
Return <compilation>
<file name="a.vb">
Option Infer On
Option Explicit Off
Option Strict On
Imports System
Imports System.Collections.Generic
Imports System.Linq
Module Module1
Sub Main()
<%= code.Value %>
End Sub
End Module
</file>
</compilation>
End Function
Private Sub VerifySemanticInfo(semanticInfo As SemanticInfoSummary, expectedType As TypeSymbol, symbolKind? As SymbolKind, expectedSymbol As String)
Assert.Equal(CandidateReason.None, semanticInfo.CandidateReason)
Assert.Equal(0, semanticInfo.CandidateSymbols.Length)
Assert.Equal(expectedType, semanticInfo.ConvertedType)
Assert.Equal(ConversionKind.Identity, semanticInfo.ImplicitConversion.Kind)
Assert.False(semanticInfo.ConstantValue.HasValue)
Assert.Equal(0, semanticInfo.MemberGroup.Length)
If symbolKind.HasValue Then
Assert.Equal(symbolKind, semanticInfo.Symbol.Kind)
If expectedSymbol IsNot Nothing Then
Assert.Equal(expectedSymbol, semanticInfo.Symbol.ToTestDisplayString())
End If
Else
Assert.Null(semanticInfo.Symbol)
End If
Assert.Equal(expectedType, semanticInfo.Type)
End Sub
Private Sub VerifySemanticInfoSummary(semanticInfo As SemanticInfoSummary, expectedType As TypeSymbol, symbolKind? As SymbolKind)
Assert.Equal(CandidateReason.None, semanticInfo.CandidateReason)
Assert.Equal(0, semanticInfo.CandidateSymbols.Length)
Assert.Equal(expectedType, semanticInfo.ConvertedType)
Assert.Equal(ConversionKind.Identity, semanticInfo.ImplicitConversion.Kind)
Assert.False(semanticInfo.ConstantValue.HasValue)
Assert.Equal(0, semanticInfo.MemberGroup.Length)
If symbolKind.HasValue Then
Assert.Equal(symbolKind, semanticInfo.Symbol.Kind)
Else
Assert.Null(semanticInfo.Symbol)
End If
Assert.Equal(expectedType, semanticInfo.Type)
End Sub
Private Sub VerifyImplicitDeclarationSemanticInfo(code As XCData)
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(GetSourceXElementFromTemplate(code))
Dim semanticInfo = CompilationUtils.GetSemanticInfoSummary(Of IdentifierNameSyntax)(compilation, "a.vb")
Dim objectSymbol = compilation.GetTypeByMetadataName("System.Object")
VerifySemanticInfoSummary(semanticInfo, objectSymbol, SymbolKind.Local)
End Sub
Private Sub VerifyImplicitDeclarationBindExpression(code As XCData, expression As String, expectedTypeName As String, Optional symbolKind? As SymbolKind = Nothing, Optional expectedSymbol As String = Nothing)
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(GetSourceXElementFromTemplate(code))
Dim tree = compilation.SyntaxTrees.Where(Function(t) t.FilePath = "a.vb").Single()
Dim semanticModel = compilation.GetSemanticModel(tree)
Dim position = CompilationUtils.FindPositionFromText(tree, "'BIND")
Dim semanticInfo As SemanticInfoSummary = semanticModel.GetSpeculativeSemanticInfoSummary(position, SyntaxFactory.ParseExpression(expression), SpeculativeBindingOption.BindAsExpression)
VerifySemanticInfo(semanticInfo, compilation.GetTypeByMetadataName(expectedTypeName), symbolKind, expectedSymbol)
End Sub
Private Sub VerifyImplicitDeclarationLookupSymbols(code As XCData, Optional expected() As String = Nothing, Optional notExpected() As String = Nothing)
If expected Is Nothing AndAlso notExpected Is Nothing Then
Throw New ArgumentException("Must specify a value for either 'expected' or 'notExpected'")
End If
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(GetSourceXElementFromTemplate(code))
Dim actual = GetLookupSymbols(compilation, "a.vb").Select(Function(s) s.Name)
For Each s In If(expected, {})
Assert.Contains(s, actual)
Next
For Each s In If(notExpected, {})
Assert.DoesNotContain(s, actual)
Next
End Sub
#End Region
End Class
End Namespace
|