File: Declarations\MergedNamespaceDeclaration.vb
Web Access
Project: src\src\Compilers\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.vbproj (Microsoft.CodeAnalysis.VisualBasic)
' 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.Collections.Immutable
Imports Microsoft.CodeAnalysis.PooledObjects
 
Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
    ' An invariant of a merged declaration is that all of its children
    ' are also merged declarations.
    Friend NotInheritable Class MergedNamespaceDeclaration
        Inherits MergedNamespaceOrTypeDeclaration
 
        Private ReadOnly _declarations As ImmutableArray(Of SingleNamespaceDeclaration)
        Private ReadOnly _multipleSpellings As Boolean  ' true if the namespace is spelling with multiple different case-insensitive spellings ("Namespace GOO" and "Namespace goo")
        Private _children As ImmutableArray(Of MergedNamespaceOrTypeDeclaration)
 
        Private Sub New(declarations As ImmutableArray(Of SingleNamespaceDeclaration))
            MyBase.New(String.Empty)
            If declarations.Any() Then
                Me.Name = SingleNamespaceDeclaration.BestName(Of SingleNamespaceDeclaration)(declarations, _multipleSpellings)
            End If
 
            Me._declarations = declarations
        End Sub
 
        Public Shared Function Create(declarations As IEnumerable(Of SingleNamespaceDeclaration)) As MergedNamespaceDeclaration
            Return New MergedNamespaceDeclaration(ImmutableArray.CreateRange(Of SingleNamespaceDeclaration)(declarations))
        End Function
 
        Public Shared Function Create(ParamArray declarations As SingleNamespaceDeclaration()) As MergedNamespaceDeclaration
            Return New MergedNamespaceDeclaration(declarations.AsImmutableOrNull)
        End Function
 
        Public Overrides ReadOnly Property Kind As DeclarationKind
            Get
                Return DeclarationKind.Namespace
            End Get
        End Property
 
        Public ReadOnly Property Declarations As ImmutableArray(Of SingleNamespaceDeclaration)
            Get
                Return _declarations
            End Get
        End Property
 
        Public Function GetLexicalSortKey(compilation As VisualBasicCompilation) As LexicalSortKey
            ' Return first sort key from all declarations.
            Dim sortKey As LexicalSortKey = New LexicalSortKey(_declarations(0).NameLocation, compilation)
            For i = 1 To _declarations.Length - 1
                sortKey = LexicalSortKey.First(sortKey, New LexicalSortKey(_declarations(i).NameLocation, compilation))
            Next
            Return sortKey
        End Function
 
        Public ReadOnly Property NameLocations As ImmutableArray(Of Location)
            Get
                If _declarations.Length = 1 Then
                    Dim loc = _declarations(0).NameLocation
                    If loc Is Nothing Then
                        Return ImmutableArray(Of Location).Empty
                    End If
                    Return ImmutableArray.Create(loc)
                End If
 
                Dim builder = ArrayBuilder(Of Location).GetInstance()
 
                For Each decl In _declarations
                    Dim loc = decl.NameLocation
                    If loc IsNot Nothing Then
                        builder.Add(loc)
                    End If
                Next
 
                Return builder.ToImmutableAndFree()
            End Get
        End Property
 
        Public ReadOnly Property SyntaxReferences As ImmutableArray(Of SyntaxReference)
            Get
                Dim references = ArrayBuilder(Of SyntaxReference).GetInstance()
 
                For Each decl In _declarations
                    If decl.SyntaxReference IsNot Nothing Then
                        references.Add(decl.SyntaxReference)
                    End If
                Next
 
                Return references.ToImmutableAndFree()
            End Get
        End Property
 
        Protected Overrides Function GetDeclarationChildren() As ImmutableArray(Of Declaration)
            Return StaticCast(Of Declaration).From(Me.Children)
        End Function
 
        Private Function MakeChildren() As ImmutableArray(Of MergedNamespaceOrTypeDeclaration)
 
            Dim childNamespaces = ArrayBuilder(Of SingleNamespaceDeclaration).GetInstance()
            Dim singleTypeDeclarations = ArrayBuilder(Of SingleTypeDeclaration).GetInstance()
 
            ' Distribute declarations into the two lists
            For Each d As SingleNamespaceDeclaration In _declarations
                For Each child As SingleNamespaceOrTypeDeclaration In d.Children
                    Dim singleNamespaceDeclaration As SingleNamespaceDeclaration = TryCast(child, SingleNamespaceDeclaration)
                    If singleNamespaceDeclaration IsNot Nothing Then
                        childNamespaces.Add(singleNamespaceDeclaration)
                    Else
                        singleTypeDeclarations.Add(DirectCast(child, SingleTypeDeclaration))
                    End If
                Next
            Next
 
            Dim result As ArrayBuilder(Of MergedNamespaceOrTypeDeclaration) = ArrayBuilder(Of MergedNamespaceOrTypeDeclaration).GetInstance()
 
            ' Merge and add the namespaces
            Select Case childNamespaces.Count
                Case 0
                    ' Do nothing
                Case 1
                    ' Add a single element
                    result.Add(MergedNamespaceDeclaration.Create(childNamespaces))
                Case 2
                    ' Could be one group or two
                    If SingleNamespaceDeclaration.EqualityComparer.Equals(childNamespaces(0), childNamespaces(1)) Then
                        result.Add(MergedNamespaceDeclaration.Create(childNamespaces))
                    Else
                        result.Add(MergedNamespaceDeclaration.Create(childNamespaces(0)))
                        result.Add(MergedNamespaceDeclaration.Create(childNamespaces(1)))
                    End If
                Case Else
                    ' Three or more. Use GroupBy to add by groups.
                    For Each group In childNamespaces.GroupBy(Function(n) n, SingleNamespaceDeclaration.EqualityComparer)
                        result.Add(MergedNamespaceDeclaration.Create(group))
                    Next
            End Select
 
            childNamespaces.Free()
 
            ' Merge and add the types
            If singleTypeDeclarations.Count <> 0 Then
                result.AddRange(MergedTypeDeclaration.MakeMergedTypes(singleTypeDeclarations))
            End If
 
            singleTypeDeclarations.Free()
 
            Return result.ToImmutableAndFree()
 
        End Function
 
        Public Overloads ReadOnly Property Children As ImmutableArray(Of MergedNamespaceOrTypeDeclaration)
            Get
                If Me._children.IsDefault Then
                    ImmutableInterlocked.InterlockedInitialize(Me._children, MakeChildren())
                End If
 
                Return Me._children
            End Get
        End Property
 
        ' Is this declaration merged from declarations with different case-sensitive spellings
        ' (i.e., "Namespace GOO" and "Namespace goo".
        Public ReadOnly Property HasMultipleSpellings As Boolean
            Get
                Return _multipleSpellings
            End Get
        End Property
    End Class
End Namespace