File: Binding\UsingBlockBinder.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
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
 
Namespace Microsoft.CodeAnalysis.VisualBasic
 
    ''' <summary>
    ''' Binder used to bind using blocks. 
    ''' It hosts the variables declared in the resource list (if they are declared).
    ''' </summary>
    Friend NotInheritable Class UsingBlockBinder
        Inherits BlockBaseBinder
 
        Private ReadOnly _syntax As UsingBlockSyntax
        Private _locals As ImmutableArray(Of LocalSymbol) = Nothing
 
        Public Sub New(enclosing As Binder, syntax As UsingBlockSyntax)
            MyBase.New(enclosing)
 
            Debug.Assert(syntax IsNot Nothing)
            _syntax = syntax
        End Sub
 
        Friend Overrides ReadOnly Property Locals As ImmutableArray(Of LocalSymbol)
            Get
                If _locals.IsDefault Then
                    ImmutableInterlocked.InterlockedCompareExchange(_locals, BuildLocals(), Nothing)
                End If
 
                Return _locals
            End Get
        End Property
 
        ' Build a read only array of all the local variables declared By the Using statement.
        ' there can be none or multiple variable declarators with multiple variable names
        Private Function BuildLocals() As ImmutableArray(Of LocalSymbol)
            Dim variableDeclarators = _syntax.UsingStatement.Variables
 
            If variableDeclarators.Count > 0 Then
                Dim localsBuilder = ArrayBuilder(Of LocalSymbol).GetInstance
 
                For Each variableDeclarator In variableDeclarators
                    Dim isNotAsNewAndHasInitializer = variableDeclarator.Initializer IsNot Nothing AndAlso
                                                      (variableDeclarator.AsClause Is Nothing OrElse variableDeclarator.AsClause.Kind <> SyntaxKind.AsNewClause)
 
                    Dim names = variableDeclarator.Names
                    For i = 0 To names.Count - 1
                        Dim name = names(i)
 
                        ' we'll simply reuse the logic for local variables here (incl. local type inference)
 
                        ' if this is not an AsNew declaration with multiple names and an initializer (error case), then only use
                        ' the initializer for the last variable.
                        localsBuilder.Add(LocalSymbol.Create(Me.ContainingMember, Me,
                                                             name.Identifier, name, variableDeclarator.AsClause,
                                                             If(isNotAsNewAndHasInitializer AndAlso i = names.Count - 1,
                                                                variableDeclarator.Initializer,
                                                                Nothing),
                                                             LocalDeclarationKind.Using))
                    Next
                Next
 
                Return localsBuilder.ToImmutableAndFree
            End If
 
            Return ImmutableArray(Of LocalSymbol).Empty
        End Function
    End Class
End Namespace