File: VisualBasicInstructionDecoder.vb
Web Access
Project: src\src\ExpressionEvaluator\VisualBasic\Source\ExpressionCompiler\Microsoft.CodeAnalysis.VisualBasic.ExpressionCompiler.vbproj (Microsoft.CodeAnalysis.VisualBasic.ExpressionCompiler)
' 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.Reflection.Metadata
Imports System.Reflection.Metadata.Ecma335
Imports Microsoft.CodeAnalysis.ExpressionEvaluator
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Imports Microsoft.VisualStudio.Debugger
Imports Microsoft.VisualStudio.Debugger.Clr
Imports System.Text
 
Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
 
    Friend NotInheritable Class VisualBasicInstructionDecoder : Inherits InstructionDecoder(Of VisualBasicCompilation, MethodSymbol, PEModuleSymbol, TypeSymbol, TypeParameterSymbol)
 
        ' These strings were not localized in the old EE.  We'll keep them that way
        ' so as not to break consumers who may have been parsing frame names...
        Private Const s_closureDisplayName As String = "<closure>"
        Private Const s_lambdaDisplayName As String = "<lambda{0}>"
 
        ''' <summary>
        ''' Singleton instance of <see cref="VisualBasicInstructionDecoder"/> (created using default constructor).
        ''' </summary>
        Friend Shared ReadOnly Instance As VisualBasicInstructionDecoder = New VisualBasicInstructionDecoder()
 
        Private Sub New()
        End Sub
 
        Friend Overrides Sub AppendFullName(builder As StringBuilder, method As MethodSymbol)
            Dim parts = method.ToDisplayParts(DisplayFormat)
            Dim numParts = parts.Length
            For i = 0 To numParts - 1
                Dim part = parts(i)
                Dim displayString = part.ToString()
                Select Case part.Kind
                    Case SymbolDisplayPartKind.ClassName
                        If Not displayString.StartsWith(GeneratedNameConstants.DisplayClassPrefix, StringComparison.Ordinal) Then
                            builder.Append(displayString)
                        Else
                            ' Drop any remaining display class name parts and the subsequent dot...
                            Do
                                i += 1
                            Loop While ((i < numParts) AndAlso parts(i).Kind <> SymbolDisplayPartKind.MethodName)
                            i -= 1
                        End If
                    Case SymbolDisplayPartKind.MethodName
                        If displayString.StartsWith(GeneratedNameConstants.LambdaMethodNamePrefix, StringComparison.Ordinal) Then
                            builder.Append(s_closureDisplayName)
                            builder.Append("."c)
                            ' NOTE: The old implementation only appended the first ordinal number.  Since this is not useful
                            ' in uniquely identifying the lambda, we'll append the entire ordinal suffix (which may contain
                            ' multiple numbers, as well as '-' or '_').
                            builder.AppendFormat(s_lambdaDisplayName, displayString.Substring(GeneratedNameConstants.LambdaMethodNamePrefix.Length))
                        Else
                            builder.Append(displayString)
                        End If
                    Case SymbolDisplayPartKind.PropertyName
                        builder.Append(method.Name)
                    Case Else
                        builder.Append(displayString)
                End Select
            Next
        End Sub
 
        Friend Overrides Function ConstructMethod(method As MethodSymbol, typeParameters As ImmutableArray(Of TypeParameterSymbol), typeArguments As ImmutableArray(Of TypeSymbol)) As MethodSymbol
            Dim methodArity = method.Arity
            Dim methodArgumentStartIndex = typeParameters.Length - methodArity
            Dim typeMap = TypeSubstitution.Create(
                method,
                ImmutableArray.Create(typeParameters, 0, methodArgumentStartIndex),
                ImmutableArray.Create(typeArguments, 0, methodArgumentStartIndex))
            Dim substitutedType = typeMap.SubstituteNamedType(method.ContainingType)
            method = method.AsMember(substitutedType)
            If methodArity > 0 Then
                method = method.Construct(ImmutableArray.Create(typeArguments, methodArgumentStartIndex, methodArity))
            End If
            Return method
        End Function
 
        Friend Overrides Function GetAllTypeParameters(method As MethodSymbol) As ImmutableArray(Of TypeParameterSymbol)
            Return method.GetAllTypeParameters()
        End Function
 
        Friend Overrides Function GetCompilation(moduleInstance As DkmClrModuleInstance) As VisualBasicCompilation
            Dim appDomain = moduleInstance.AppDomain
            Dim moduleVersionId = moduleInstance.Mvid
            Dim previous = appDomain.GetMetadataContext(Of VisualBasicMetadataContext)()
            Dim metadataBlocks = moduleInstance.RuntimeInstance.GetMetadataBlocks(appDomain, previous.MetadataBlocks)
 
            Dim kind = GetMakeAssemblyReferencesKind()
            Dim contextId = MetadataContextId.GetContextId(moduleVersionId, kind)
            Dim assemblyContexts = If(previous.Matches(metadataBlocks), previous.AssemblyContexts, ImmutableDictionary(Of MetadataContextId, VisualBasicMetadataContext).Empty)
            Dim previousContext As VisualBasicMetadataContext = Nothing
            assemblyContexts.TryGetValue(contextId, previousContext)
 
            Dim compilation = previousContext.Compilation
            If compilation Is Nothing Then
                compilation = metadataBlocks.ToCompilation(moduleVersionId, kind)
                appDomain.SetMetadataContext(
                    New MetadataContext(Of VisualBasicMetadataContext)(
                        metadataBlocks,
                        assemblyContexts.SetItem(contextId, New VisualBasicMetadataContext(compilation))),
                    report:=kind = MakeAssemblyReferencesKind.AllReferences)
            End If
 
            Return compilation
        End Function
 
        Friend Overrides Function GetMethod(compilation As VisualBasicCompilation, instructionAddress As DkmClrInstructionAddress) As MethodSymbol
            Dim methodHandle = CType(MetadataTokens.Handle(instructionAddress.MethodId.Token), MethodDefinitionHandle)
            Return compilation.GetSourceMethod(instructionAddress.ModuleInstance.Mvid, methodHandle)
        End Function
 
        Friend Overrides Function GetTypeNameDecoder(compilation As VisualBasicCompilation, method As MethodSymbol) As TypeNameDecoder(Of PEModuleSymbol, TypeSymbol)
            Debug.Assert(TypeOf method Is PEMethodSymbol)
            Return New EETypeNameDecoder(compilation, DirectCast(method.ContainingModule, PEModuleSymbol))
        End Function
 
    End Class
 
End Namespace