| File: Binding\SubOrFunctionBodyBinder.vb | Web Access |
| Project: src\roslyn\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 System.Runtime.InteropServices Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Namespace Microsoft.CodeAnalysis.VisualBasic ''' <summary> ''' A SubOrFunctionBodyBinder provides context for looking up parameters/labels in a body of an executable entity (a method, lambda, or top-level script code), ''' and also for the implementation of ContainingMember, GetLocalForFunctionValue and GetBinder. ''' </summary> Friend MustInherit Class SubOrFunctionBodyBinder Inherits ExecutableCodeBinder Private ReadOnly _methodSymbol As MethodSymbol Protected ReadOnly _parameterMap As Dictionary(Of String, Symbol) Public Sub New(methodOrLambdaSymbol As MethodSymbol, root As SyntaxNode, containingBinder As Binder) MyBase.New(root, containingBinder) _methodSymbol = methodOrLambdaSymbol Dim parameters As ImmutableArray(Of ParameterSymbol) = methodOrLambdaSymbol.Parameters Dim count As Integer = parameters.Length Dim mapSize As Integer = count If Not methodOrLambdaSymbol.IsSub Then mapSize += 1 ' account for possible function return value End If _parameterMap = New Dictionary(Of String, Symbol)(mapSize, CaseInsensitiveComparison.Comparer) For i = 0 To count - 1 Dim parameterSymbol = parameters(i) ' If there are two parameters with the same name, the first takes precedence. ' This is an error condition anyway, but it seems more logical and ' it really doesn't matter which order we use. If Not _parameterMap.ContainsKey(parameterSymbol.Name) Then _parameterMap(parameterSymbol.Name) = parameterSymbol End If Next End Sub Public Overrides ReadOnly Property ContainingMember As Symbol Get Return _methodSymbol End Get End Property Public Overrides ReadOnly Property AdditionalContainingMembers As ImmutableArray(Of Symbol) Get Return ImmutableArray(Of Symbol).Empty End Get End Property Public MustOverride Overrides Function GetLocalForFunctionValue() As LocalSymbol Friend Overrides Sub LookupInSingleBinder(lookupResult As LookupResult, name As String, arity As Integer, options As LookupOptions, originalBinder As Binder, <[In], Out> ByRef useSiteInfo As CompoundUseSiteInfo(Of AssemblySymbol)) Debug.Assert(lookupResult.IsClear) ' Parameters always have arity 0 and are not namespaces or types. If (options And (LookupOptions.NamespacesOrTypesOnly Or LookupOptions.LabelsOnly Or LookupOptions.MustNotBeLocalOrParameter)) = 0 Then Dim parameterSymbol As Symbol = Nothing If _parameterMap.TryGetValue(name, parameterSymbol) Then lookupResult.SetFrom(CheckViability(parameterSymbol, arity, options, Nothing, useSiteInfo)) End If Else MyBase.LookupInSingleBinder(lookupResult, name, arity, options, originalBinder, useSiteInfo) End If End Sub Friend Overrides Sub AddLookupSymbolsInfoInSingleBinder(nameSet As LookupSymbolsInfo, options As LookupOptions, originalBinder As Binder) ' UNDONE: additional filtering based on options? If (options And (LookupOptions.NamespacesOrTypesOnly Or LookupOptions.LabelsOnly)) = 0 Then For Each param In _parameterMap.Values If originalBinder.CanAddLookupSymbolInfo(param, options, nameSet, Nothing) Then nameSet.AddSymbol(param, param.Name, 0) End If Next Else MyBase.AddLookupSymbolsInfoInSingleBinder(nameSet, options, originalBinder) End If End Sub End Class End Namespace