|
' 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.Globalization
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 Microsoft.CodeAnalysis.VisualBasic.UnitTests.Symbols
Imports Roslyn.Test.Utilities
Imports System.Collections.Immutable
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
Public Class ContainerTests
Inherits BasicTestBase
' Check that "basRootNS" is actually a bad root namespace
Private Sub BadDefaultNS(badRootNS As String)
AssertTheseDiagnostics(New VisualBasicCompilationOptions(OutputKind.ConsoleApplication).WithRootNamespace(badRootNS).Errors,
<expected>
BC2014: the value '<%= badRootNS %>' is invalid for option 'RootNamespace'
</expected>)
End Sub
<Fact>
Public Sub SimpleAssembly()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="Banana">
<file name="b.vb">
Namespace NS
Public Class Goo
End Class
End Namespace
</file>
</compilation>)
Dim sym = compilation.Assembly
Assert.Equal("Banana", sym.Name)
Assert.Equal("Banana, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", sym.ToTestDisplayString())
Assert.Equal(String.Empty, sym.GlobalNamespace.Name)
Assert.Equal(SymbolKind.Assembly, sym.Kind)
Assert.Equal(Accessibility.NotApplicable, sym.DeclaredAccessibility)
Assert.False(sym.IsShared)
Assert.False(sym.IsOverridable)
Assert.False(sym.IsOverrides)
Assert.False(sym.IsMustOverride)
Assert.False(sym.IsNotOverridable)
Assert.Null(sym.ContainingAssembly)
Assert.Null(sym.ContainingSymbol)
End Sub
<WorkItem(537302, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537302")>
<Fact>
Public Sub SourceModule()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="Banana">
<file name="m.vb">
Namespace NS
Public Class Goo
End Class
End Namespace
</file>
</compilation>)
Dim sym = compilation.SourceModule
Assert.Equal("Banana.dll", sym.Name)
Assert.Equal(String.Empty, sym.GlobalNamespace.Name)
Assert.Equal(SymbolKind.NetModule, sym.Kind)
Assert.Equal(Accessibility.NotApplicable, sym.DeclaredAccessibility)
Assert.False(sym.IsShared)
Assert.False(sym.IsOverridable)
Assert.False(sym.IsOverrides)
Assert.False(sym.IsMustOverride)
Assert.False(sym.IsNotOverridable)
Assert.Equal("Banana", sym.ContainingAssembly.Name)
Assert.Equal("Banana", sym.ContainingSymbol.Name)
End Sub
<WorkItem(537421, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537421")>
<Fact>
Public Sub StandardModule()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="Banana">
<file name="m.vb">
Namespace NS
Module MGoo
Dim A As Integer
Sub MySub()
End Sub
Function Func(x As Long) As Long
Return x
End Function
End Module
End Namespace
</file>
</compilation>)
Dim ns As NamespaceSymbol = DirectCast(compilation.SourceModule.GlobalNamespace.GetMembers("NS").Single(), NamespaceSymbol)
Dim sym1 = ns.GetMembers("MGoo").Single()
Assert.Equal("MGoo", sym1.Name)
Assert.Equal("NS.MGoo", sym1.ToTestDisplayString())
Assert.Equal(SymbolKind.NamedType, sym1.Kind)
' default - Friend
Assert.Equal(Accessibility.Friend, sym1.DeclaredAccessibility)
Assert.False(sym1.IsShared)
Assert.False(sym1.IsOverridable)
Assert.False(sym1.IsOverrides)
Assert.False(sym1.IsMustOverride)
Assert.False(sym1.IsNotOverridable)
Assert.Equal("Banana", sym1.ContainingAssembly.Name)
Assert.Equal("NS", sym1.ContainingSymbol.Name)
' module member
Dim smod = DirectCast(sym1, NamedTypeSymbol)
Dim sym2 = DirectCast(smod.GetMembers("A").Single(), FieldSymbol)
' default - Private
Assert.Equal(Accessibility.Private, sym2.DeclaredAccessibility)
Assert.True(sym2.IsShared)
Dim sym3 = DirectCast(smod.GetMembers("MySub").Single(), MethodSymbol)
Dim sym4 = DirectCast(smod.GetMembers("Func").Single(), MethodSymbol)
' default - Public
Assert.Equal(Accessibility.Public, sym3.DeclaredAccessibility)
Assert.Equal(Accessibility.Public, sym4.DeclaredAccessibility)
Assert.True(sym3.IsShared)
Assert.True(sym4.IsShared)
' shared cctor
'sym4 = DirectCast(smod.GetMembers(WellKnownMemberNames.StaticConstructorName).Single(), MethodSymbol)
End Sub
' Check that we disallow certain kids of bad root namespaces
<Fact>
Public Sub BadDefaultNSTest()
BadDefaultNS("Goo.7")
BadDefaultNS("Goo..Bar")
BadDefaultNS(".X")
BadDefaultNS("$")
End Sub
' Check that parse errors are reported
<Fact>
Public Sub NamespaceParseErrors()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="Banana">
<file name="a.vb">
Imports System.7
</file>
<file name="b.vb">
Namespace Goo
End Class
</file>
</compilation>)
Dim expectedErrors = <errors>
BC30205: End of statement expected.
Imports System.7
~~
BC30626: 'Namespace' statement must end with a matching 'End Namespace'.
Namespace Goo
~~~~~~~~~~~~~
BC30460: 'End Class' must be preceded by a matching 'Class'.
End Class
~~~~~~~~~
</errors>
CompilationUtils.AssertTheseParseDiagnostics(compilation, expectedErrors)
End Sub
' Check namespace symbols
<Fact>
Public Sub NSSym()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="C">
<file name="a.vb">
Namespace A
End Namespace
Namespace C
End Namespace
</file>
<file name="b.vb">
Namespace A.B
End Namespace
Namespace a.B
End Namespace
Namespace e
End Namespace
</file>
<file name="c.vb">
Namespace A.b.D
End Namespace
</file>
</compilation>)
Dim globalNS = compilation.SourceModule.GlobalNamespace
Assert.Equal("", globalNS.Name)
Assert.Equal(SymbolKind.Namespace, globalNS.Kind)
Assert.Equal(3, globalNS.GetMembers().Length())
Dim members = globalNS.GetMembers().AsEnumerable().OrderBy(Function(s) s.Name, IdentifierComparison.Comparer).ToArray()
Dim membersA = globalNS.GetMembers("a")
Dim membersC = globalNS.GetMembers("c")
Dim membersE = globalNS.GetMembers("E")
Assert.Equal(3, members.Length)
Assert.Equal(1, membersA.Length)
Assert.Equal(1, membersC.Length)
Assert.Equal(1, membersE.Length)
Assert.True(members.SequenceEqual(membersA.Concat(membersC).Concat(membersE).AsEnumerable()))
Assert.Equal("a", membersA.First().Name, IdentifierComparison.Comparer)
Assert.Equal("C", membersC.First().Name, IdentifierComparison.Comparer)
Assert.Equal("E", membersE.First().Name, IdentifierComparison.Comparer)
Dim nsA As NamespaceSymbol = DirectCast(membersA.First(), NamespaceSymbol)
Assert.Equal("A", nsA.Name, IdentifierComparison.Comparer)
Assert.Equal(SymbolKind.Namespace, nsA.Kind)
Assert.Equal(1, nsA.GetMembers().Length())
Dim nsB As NamespaceSymbol = DirectCast(nsA.GetMembers().First(), NamespaceSymbol)
Assert.Equal("B", nsB.Name, IdentifierComparison.Comparer)
Assert.Equal(SymbolKind.Namespace, nsB.Kind)
Assert.Equal(1, nsB.GetMembers().Length())
Dim nsD As NamespaceSymbol = DirectCast(nsB.GetMembers().First(), NamespaceSymbol)
Assert.Equal("D", nsD.Name)
Assert.Equal(SymbolKind.Namespace, nsD.Kind)
Assert.Equal(0, nsD.GetMembers().Length())
AssertTheseDeclarationDiagnostics(compilation,
<expected>
BC40055: Casing of namespace name 'a' does not match casing of namespace name 'A' in 'a.vb'.
Namespace a.B
~
BC40055: Casing of namespace name 'b' does not match casing of namespace name 'B' in 'b.vb'.
Namespace A.b.D
~
</expected>)
End Sub
' Check namespace symbols in the presence of a root namespace
<Fact>
Public Sub NSSymWithRootNamespace()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="C">
<file name="a.vb">
Namespace A
End Namespace
Namespace E
End Namespace
</file>
<file name="b.vb">
Namespace A.B
End Namespace
Namespace C
End Namespace
</file>
</compilation>, options:=TestOptions.ReleaseExe.WithRootNamespace("Goo.Bar"))
Dim globalNS = compilation.SourceModule.GlobalNamespace
Assert.Equal("", globalNS.Name)
Assert.Equal(SymbolKind.Namespace, globalNS.Kind)
Assert.Equal(1, globalNS.GetMembers().Length())
Dim members = globalNS.GetMembers()
Dim nsGoo As NamespaceSymbol = DirectCast(members.First(), NamespaceSymbol)
Assert.Equal("Goo", nsGoo.Name, IdentifierComparison.Comparer)
Assert.Equal(SymbolKind.Namespace, nsGoo.Kind)
Assert.Equal(1, nsGoo.GetMembers().Length())
Dim membersGoo = nsGoo.GetMembers()
Dim nsBar As NamespaceSymbol = DirectCast(membersGoo.First(), NamespaceSymbol)
Assert.Equal("Bar", nsBar.Name, IdentifierComparison.Comparer)
Assert.Equal(SymbolKind.Namespace, nsBar.Kind)
Assert.Equal(3, nsBar.GetMembers().Length())
Dim membersBar = nsBar.GetMembers().AsEnumerable().OrderBy(Function(s) s.Name, IdentifierComparison.Comparer).ToArray()
Dim membersA = nsBar.GetMembers("a")
Dim membersC = nsBar.GetMembers("c")
Dim membersE = nsBar.GetMembers("E")
Assert.Equal(3, membersBar.Length)
Assert.Equal(1, membersA.Length)
Assert.Equal(1, membersC.Length)
Assert.Equal(1, membersE.Length)
Assert.True(membersBar.SequenceEqual(membersA.Concat(membersC).Concat(membersE).AsEnumerable()))
Assert.Equal("a", membersA.First().Name, IdentifierComparison.Comparer)
Assert.Equal("C", membersC.First().Name, IdentifierComparison.Comparer)
Assert.Equal("E", membersE.First().Name, IdentifierComparison.Comparer)
Dim nsA As NamespaceSymbol = DirectCast(membersA.First(), NamespaceSymbol)
Assert.Equal("A", nsA.Name, IdentifierComparison.Comparer)
Assert.Equal(SymbolKind.Namespace, nsA.Kind)
Assert.Equal(1, nsA.GetMembers().Length())
Dim nsB As NamespaceSymbol = DirectCast(nsA.GetMembers().First(), NamespaceSymbol)
Assert.Equal("B", nsB.Name, IdentifierComparison.Comparer)
Assert.Equal(SymbolKind.Namespace, nsB.Kind)
Assert.Equal(0, nsB.GetMembers().Length())
CompilationUtils.AssertNoDeclarationDiagnostics(compilation)
End Sub
' Check namespace symbol containers in the presence of a root namespace
<Fact>
Public Sub NSContainersWithRootNamespace()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="C">
<file name="a.vb">
Class Type1
End Class
</file>
</compilation>, options:=TestOptions.ReleaseExe.WithRootNamespace("Goo.Bar"))
Dim globalNS = compilation.SourceModule.GlobalNamespace
Dim members = globalNS.GetMembers()
Dim nsGoo As NamespaceSymbol = DirectCast(members.First(), NamespaceSymbol)
Dim membersGoo = nsGoo.GetMembers()
Dim nsBar As NamespaceSymbol = DirectCast(membersGoo.First(), NamespaceSymbol)
Dim type1Sym = nsBar.GetMembers("Type1").Single()
Assert.Same(nsBar, type1Sym.ContainingSymbol)
Assert.Same(nsGoo, nsBar.ContainingSymbol)
Assert.Same(globalNS, nsGoo.ContainingSymbol)
Assert.Same(compilation.SourceModule, globalNS.ContainingSymbol)
End Sub
' Check namespace symbol containers in the presence of a root namespace
<Fact>
Public Sub NSContainersWithoutRootNamespace()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="C">
<file name="a.vb">
Class Type1
End Class
</file>
</compilation>)
Dim globalNS = compilation.SourceModule.GlobalNamespace
Dim type1Sym = globalNS.GetMembers("Type1").Single()
Assert.Same(globalNS, type1Sym.ContainingSymbol)
Assert.Same(compilation.SourceModule, globalNS.ContainingSymbol)
End Sub
<Fact>
Public Sub ImportsAlias01()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="Test">
<file name="a.vb">
Imports ALS = N1.N2
Namespace N1
Namespace N2
Public Class A
Sub S()
End Sub
End Class
End Namespace
End Namespace
Namespace N3
Public Class B
Inherits ALS.A
End Class
End Namespace
</file>
<file name="b.vb">
Imports ANO = N3
Namespace N1.N2
Class C
Inherits ANO.B
End Class
End Namespace
</file>
</compilation>)
Dim globalNS = compilation.SourceModule.GlobalNamespace
Dim n3 = DirectCast(globalNS.GetMembers("N3").Single(), NamespaceSymbol)
Dim mem1 = DirectCast(n3.GetTypeMembers("B").Single(), NamedTypeSymbol)
Assert.Equal("A", mem1.BaseType.Name)
Assert.Equal("N1.N2.A", mem1.BaseType.ToTestDisplayString())
Dim n1 = DirectCast(globalNS.GetMembers("N1").Single(), NamespaceSymbol)
Dim n2 = DirectCast(n1.GetMembers("N2").Single(), NamespaceSymbol)
Dim mem2 = DirectCast(n2.GetTypeMembers("C").Single(), NamedTypeSymbol)
Assert.Equal("B", mem2.BaseType.Name)
Assert.Equal("N3.B", mem2.BaseType.ToTestDisplayString())
CompilationUtils.AssertNoDeclarationDiagnostics(compilation)
End Sub
<Fact, WorkItem(544009, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544009")>
Public Sub MultiModulesNamespace()
Dim text3 = <![CDATA[
Namespace N1
Structure SGoo
End Structure
End Namespace
]]>.Value
Dim comp1 = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="Test1">
<file name="a.vb">
Namespace N1
Class CGoo
End Class
End Namespace
</file>
</compilation>)
Dim comp2 = CompilationUtils.CreateCompilationWithMscorlib40(
<compilation name="Test2">
<file name="b.vb">
Namespace N1
Interface IGoo
End Interface
End Namespace
</file>
</compilation>)
Dim compRef1 = New VisualBasicCompilationReference(comp1)
Dim compRef2 = New VisualBasicCompilationReference(comp2)
Dim comp = VisualBasicCompilation.Create("Test3", {VisualBasicSyntaxTree.ParseText(text3)}, {MscorlibRef, compRef1, compRef2})
Dim globalNS = comp.GlobalNamespace
Dim ns = DirectCast(globalNS.GetMembers("N1").Single(), NamespaceSymbol)
Assert.Equal(3, ns.GetTypeMembers().Length())
Dim ext = ns.Extent
Assert.Equal(NamespaceKind.Compilation, ext.Kind)
Assert.Equal("Compilation: " & GetType(VisualBasicCompilation).FullName, ext.ToString())
Dim constituents = ns.ConstituentNamespaces
Assert.Equal(3, constituents.Length)
Assert.True(constituents.Contains(TryCast(comp.SourceAssembly.GlobalNamespace.GetMembers("N1").Single(), NamespaceSymbol)))
Assert.True(constituents.Contains(TryCast(comp.GetReferencedAssemblySymbol(compRef1).GlobalNamespace.GetMembers("N1").Single(), NamespaceSymbol)))
Assert.True(constituents.Contains(TryCast(comp.GetReferencedAssemblySymbol(compRef2).GlobalNamespace.GetMembers("N1").Single(), NamespaceSymbol)))
For Each constituentNs In constituents
Assert.Equal(NamespaceKind.Module, constituentNs.Extent.Kind)
Assert.Equal(ns.ToTestDisplayString(), constituentNs.ToTestDisplayString())
Next
End Sub
<WorkItem(537310, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537310")>
<Fact>
Public Sub MultiModulesNamespaceCorLibraries()
Dim text1 = <![CDATA[
Namespace N1
Class CGoo
End Class
End Namespace
]]>.Value
Dim text2 = <![CDATA[
Namespace N1
Interface IGoo
End Interface
End Namespace
]]>.Value
Dim text3 = <![CDATA[
Namespace N1
Structure SGoo
End Structure
End Namespace
]]>.Value
Dim comp1 = VisualBasicCompilation.Create("Test1", syntaxTrees:={VisualBasicSyntaxTree.ParseText(text1)})
Dim comp2 = VisualBasicCompilation.Create("Test2", syntaxTrees:={VisualBasicSyntaxTree.ParseText(text2)})
Dim compRef1 = New VisualBasicCompilationReference(comp1)
Dim compRef2 = New VisualBasicCompilationReference(comp2)
Dim comp = VisualBasicCompilation.Create("Test3", {VisualBasicSyntaxTree.ParseText(text3)}, {compRef1, compRef2})
Dim globalNS = comp.GlobalNamespace
Dim ns = DirectCast(globalNS.GetMembers("N1").Single(), NamespaceSymbol)
Assert.Equal(3, ns.GetTypeMembers().Length())
Assert.Equal(NamespaceKind.Compilation, ns.Extent.Kind)
Dim constituents = ns.ConstituentNamespaces
Assert.Equal(3, constituents.Length)
Assert.True(constituents.Contains(TryCast(comp.SourceAssembly.GlobalNamespace.GetMembers("N1").Single(), NamespaceSymbol)))
Assert.True(constituents.Contains(TryCast(comp.GetReferencedAssemblySymbol(compRef1).GlobalNamespace.GetMembers("N1").Single(), NamespaceSymbol)))
Assert.True(constituents.Contains(TryCast(comp.GetReferencedAssemblySymbol(compRef2).GlobalNamespace.GetMembers("N1").Single(), NamespaceSymbol)))
For Each constituentNs In constituents
Assert.Equal(NamespaceKind.Module, constituentNs.Extent.Kind)
Assert.Equal(ns.ToTestDisplayString(), constituentNs.ToTestDisplayString())
Next
End Sub
<WorkItem(690871, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/690871")>
<Fact>
Public Sub SpecialTypesAndAliases()
Dim source =
<compilation name="C">
<file>
Public Class C
End Class
</file>
</compilation>
Dim aliasedCorlib = NetFramework.mscorlib.WithAliases(ImmutableArray.Create("Goo"))
Dim comp = CreateEmptyCompilationWithReferences(source, {aliasedCorlib})
' NOTE: this doesn't compile in dev11 - it reports that it cannot find System.Object.
' However, we've already changed how special type lookup works, so this is not a major issue.
comp.AssertNoDiagnostics()
Dim objectType = comp.GetSpecialType(SpecialType.System_Object)
Assert.Equal(TypeKind.Class, objectType.TypeKind)
Assert.Equal("System.Object", objectType.ToTestDisplayString())
Assert.Equal(objectType, comp.Assembly.GetSpecialType(SpecialType.System_Object))
Assert.Equal(objectType, comp.Assembly.CorLibrary.GetSpecialType(SpecialType.System_Object))
End Sub
<WorkItem(690871, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/690871")>
<Fact>
Public Sub WellKnownTypesAndAliases()
Dim [lib] =
<compilation name="lib">
<file>
Namespace System.Threading.Tasks
Public Class Task
Public Status As Integer
End Class
End Namespace
</file>
</compilation>
Dim source =
<compilation name="test">
<file>
Imports System.Threading.Tasks
Public Class App
Public T as Task
End Class
</file>
</compilation>
Dim libComp = CreateEmptyCompilationWithReferences([lib], {MscorlibRef_v4_0_30316_17626})
Dim libRef = libComp.EmitToImageReference(aliases:=ImmutableArray.Create("myTask"))
Dim comp = CreateEmptyCompilationWithReferences(source, {libRef, MscorlibRef_v4_0_30316_17626, MsvbRef_v4_0_30319_17929})
' NOTE: Unlike in C#, aliases on metadata references are ignored, so the
' reference to System.Threading.Tasks is ambiguous.
comp.AssertTheseDiagnostics(
<expected>
BC30560: 'Task' is ambiguous in the namespace 'System.Threading.Tasks'.
Public T as Task
~~~~
</expected>)
End Sub
<Fact, WorkItem(54836, "https://github.com/dotnet/roslyn/issues/54836")>
Public Sub RetargetableAttributeIsRespectedInSource()
Dim code = <![CDATA[
Imports System.Reflection
<Assembly: AssemblyFlags(AssemblyNameFlags.Retargetable)>
]]>
Dim comp = CreateCompilation(code.Value)
Assert.True(comp.Assembly.Identity.IsRetargetable)
AssertTheseEmitDiagnostics(comp)
End Sub
End Class
End Namespace
|