RetargetingModuleSymbol.vb 11.6 KB
Newer Older
1
' Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
P
Pilchie 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

Imports System.Collections.Concurrent
Imports System.Collections.Generic
Imports System.Collections.Immutable
Imports System.Collections.ObjectModel
Imports System.Runtime.InteropServices
Imports Microsoft.Cci
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports TypeKind = Microsoft.CodeAnalysis.TypeKind
Imports System.Globalization
Imports System.Threading

Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Retargeting

    ''' <summary>
    ''' Represents a primary module of a <see cref="RetargetingAssemblySymbol"/>. Essentially this is a wrapper around 
    ''' another <see cref="SourceModuleSymbol"/> that is responsible for retargeting symbols from one assembly to another. 
    ''' It can retarget symbols for multiple assemblies at the same time.
    ''' 
    ''' Here is how retargeting is implemented in general:
    ''' - Symbols from underlying module are substituted with retargeting symbols.
    ''' - Symbols from referenced assemblies that can be reused as is (i.e. don't have to be retargeted) are
    '''   used as is.
    ''' - Symbols from referenced assemblies that must be retargeted are substituted with result of retargeting.
    ''' </summary>
    Friend NotInheritable Class RetargetingModuleSymbol
        Inherits NonMissingModuleSymbol

        ''' <summary>
        ''' Owning <see cref="RetargetingAssemblySymbol"/>.
        ''' </summary>
36
        Private ReadOnly _retargetingAssembly As RetargetingAssemblySymbol
P
Pilchie 已提交
37 38 39 40

        ''' <summary>
        ''' The underlying <see cref="ModuleSymbol"/>, cannot be another <see cref="RetargetingModuleSymbol"/>.
        ''' </summary>
41
        Private ReadOnly _underlyingModule As SourceModuleSymbol
P
Pilchie 已提交
42 43 44 45 46 47 48

        ''' <summary>
        ''' The map that captures information about what assembly should be retargeted 
        ''' to what assembly. Key is the <see cref="AssemblySymbol"/> referenced by the underlying module,
        ''' value is the corresponding <see cref="AssemblySymbol"/> referenced by this module, and corresponding
        ''' retargeting map for symbols.
        ''' </summary>
49
        Private ReadOnly _retargetingAssemblyMap As New Dictionary(Of AssemblySymbol, DestinationData)()
P
Pilchie 已提交
50 51 52 53 54 55 56 57 58 59 60 61

        Private Structure DestinationData
            Public [To] As AssemblySymbol
            Public SymbolMap As ConcurrentDictionary(Of NamedTypeSymbol, NamedTypeSymbol)
        End Structure


        Friend ReadOnly RetargetingTranslator As RetargetingSymbolTranslator

        ''' <summary>
        ''' Retargeted custom attributes
        ''' </summary>
62
        Private _lazyCustomAttributes As ImmutableArray(Of VisualBasicAttributeData)
P
Pilchie 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

        ''' <summary>
        ''' Constructor.
        ''' </summary>
        ''' <param name="retargetingAssembly">
        ''' Owning assembly.
        ''' </param>
        ''' <param name="underlyingModule">
        ''' Underlying <see cref="ModuleSymbol"/>, cannot be another <see cref="RetargetingModuleSymbol"/>.
        ''' </param>
        ''' <remarks></remarks>
        Public Sub New(retargetingAssembly As RetargetingAssemblySymbol, underlyingModule As SourceModuleSymbol)
            Debug.Assert(retargetingAssembly IsNot Nothing)
            Debug.Assert(underlyingModule IsNot Nothing)

78 79
            _retargetingAssembly = retargetingAssembly
            _underlyingModule = underlyingModule
P
Pilchie 已提交
80 81 82 83 84 85 86 87 88 89 90 91 92
            RetargetingTranslator = New RetargetingSymbolTranslator(Me)

            Me._createRetargetingMethod = AddressOf CreateRetargetingMethod
            Me._createRetargetingNamespace = AddressOf CreateRetargetingNamespace
            Me._createRetargetingNamedType = AddressOf CreateRetargetingNamedType
            Me._createRetargetingField = AddressOf CreateRetargetingField
            Me._createRetargetingTypeParameter = AddressOf CreateRetargetingTypeParameter
            Me._createRetargetingProperty = AddressOf CreateRetargetingProperty
            Me._createRetargetingEvent = AddressOf CreateRetargetingEvent
        End Sub

        Friend Overrides ReadOnly Property Ordinal As Integer
            Get
93
                Debug.Assert(_underlyingModule.Ordinal = 0)
P
Pilchie 已提交
94 95 96 97 98 99
                Return 0
            End Get
        End Property

        Friend Overrides ReadOnly Property Machine As System.Reflection.PortableExecutable.Machine
            Get
100
                Return _underlyingModule.Machine
P
Pilchie 已提交
101 102 103 104 105
            End Get
        End Property

        Friend Overrides ReadOnly Property Bit32Required As Boolean
            Get
106
                Return _underlyingModule.Bit32Required
P
Pilchie 已提交
107 108 109 110 111 112 113 114
            End Get
        End Property

        ''' <summary>
        ''' The underlying <see cref="ModuleSymbol"/>, cannot be another <see cref="RetargetingModuleSymbol"/>.
        ''' </summary>
        Public ReadOnly Property UnderlyingModule As SourceModuleSymbol
            Get
115
                Return _underlyingModule
P
Pilchie 已提交
116 117 118 119 120
            End Get
        End Property

        Public Overrides ReadOnly Property ContainingSymbol As Symbol
            Get
121
                Return _retargetingAssembly
P
Pilchie 已提交
122 123 124 125 126
            End Get
        End Property

        Public Overrides ReadOnly Property ContainingAssembly As AssemblySymbol
            Get
127
                Return _retargetingAssembly
P
Pilchie 已提交
128 129 130 131
            End Get
        End Property

        Public Overloads Overrides Function GetAttributes() As ImmutableArray(Of VisualBasicAttributeData)
132
            Return RetargetingTranslator.GetRetargetedAttributes(_underlyingModule, _lazyCustomAttributes)
P
Pilchie 已提交
133 134 135 136
        End Function

        Public Overrides ReadOnly Property Name As String
            Get
137
                Return _underlyingModule.Name
P
Pilchie 已提交
138 139 140 141 142
            End Get
        End Property

        Public Overrides ReadOnly Property MetadataName As String
            Get
143
                Return _underlyingModule.MetadataName
P
Pilchie 已提交
144 145 146 147 148
            End Get
        End Property

        Public Overrides ReadOnly Property GlobalNamespace As NamespaceSymbol
            Get
149
                Return RetargetingTranslator.Retarget(_underlyingModule.GlobalNamespace)
P
Pilchie 已提交
150 151 152 153 154
            End Get
        End Property

        Public Overrides ReadOnly Property Locations As ImmutableArray(Of Location)
            Get
155
                Return _underlyingModule.Locations
P
Pilchie 已提交
156 157 158 159 160 161 162 163 164 165 166 167 168
            End Get
        End Property

        ''' <summary>
        ''' A helper method for ReferenceManager to set AssemblySymbols for assemblies 
        ''' referenced by this module.
        ''' </summary>
        Friend Overrides Sub SetReferences(
            moduleReferences As ModuleReferences(Of AssemblySymbol),
            Optional originatingSourceAssemblyDebugOnly As SourceAssemblySymbol = Nothing)
            MyBase.SetReferences(moduleReferences, originatingSourceAssemblyDebugOnly)

            ' Build the retargeting map
169
            _retargetingAssemblyMap.Clear()
P
Pilchie 已提交
170

171
            Dim underlyingBoundReferences As ImmutableArray(Of AssemblySymbol) = _underlyingModule.GetReferencedAssemblySymbols()
P
Pilchie 已提交
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
            Dim referencedAssemblySymbols As ImmutableArray(Of AssemblySymbol) = moduleReferences.Symbols
            Dim referencedAssemblies As ImmutableArray(Of AssemblyIdentity) = moduleReferences.Names

            Debug.Assert(referencedAssemblySymbols.Length = referencedAssemblies.Length)
            Debug.Assert(referencedAssemblySymbols.Length <= underlyingBoundReferences.Length) ' Linked references are filtered out.

            Dim i As Integer = -1
            Dim j As Integer = -1

            Do
                i += 1
                j += 1

                If i >= referencedAssemblySymbols.Length Then
                    Exit Do
                End If

                ' Skip linked assemblies for source module
                While underlyingBoundReferences(j).IsLinked
                    j += 1
                End While

#If DEBUG Then
195
                Dim identityComparer = _underlyingModule.DeclaringCompilation.Options.AssemblyIdentityComparer
P
Pilchie 已提交
196 197 198 199 200 201 202 203 204 205 206
                Dim definitionIdentity = If(referencedAssemblySymbols(i) Is originatingSourceAssemblyDebugOnly,
                                            New AssemblyIdentity(name:=originatingSourceAssemblyDebugOnly.Name),
                                            referencedAssemblySymbols(i).Identity)

                Debug.Assert(identityComparer.Compare(referencedAssemblies(i), definitionIdentity) <> AssemblyIdentityComparer.ComparisonResult.NotEquivalent)
                Debug.Assert(identityComparer.Compare(referencedAssemblies(i), underlyingBoundReferences(j).Identity) <> AssemblyIdentityComparer.ComparisonResult.NotEquivalent)
#End If

                If referencedAssemblySymbols(i) IsNot underlyingBoundReferences(j) Then
                    Dim destinationData As DestinationData = Nothing

207
                    If Not _retargetingAssemblyMap.TryGetValue(underlyingBoundReferences(j), destinationData) Then
P
Pilchie 已提交
208 209
                        Dim symbolMap = New ConcurrentDictionary(Of NamedTypeSymbol, NamedTypeSymbol)()

210
                        _retargetingAssemblyMap.Add(underlyingBoundReferences(j),
P
Pilchie 已提交
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
                            New DestinationData With {.To = referencedAssemblySymbols(i), .SymbolMap = symbolMap})
                    Else
                        Debug.Assert(destinationData.To Is referencedAssemblySymbols(i))
                    End If
                End If
            Loop

#If DEBUG Then
            While (j < underlyingBoundReferences.Length AndAlso underlyingBoundReferences(j).IsLinked)
                j += 1
            End While

            Debug.Assert(j = underlyingBoundReferences.Length)
#End If

        End Sub

        Friend Overrides ReadOnly Property TypeNames As ICollection(Of String)
            Get
230
                Return _underlyingModule.TypeNames
P
Pilchie 已提交
231 232 233 234 235
            End Get
        End Property

        Friend Overrides ReadOnly Property NamespaceNames As ICollection(Of String)
            Get
236
                Return _underlyingModule.NamespaceNames
P
Pilchie 已提交
237 238 239 240 241
            End Get
        End Property

        Friend Overrides ReadOnly Property MightContainExtensionMethods As Boolean
            Get
242
                Return _underlyingModule.MightContainExtensionMethods
P
Pilchie 已提交
243 244 245 246 247
            End Get
        End Property

        Friend Overrides ReadOnly Property HasAssemblyCompilationRelaxationsAttribute As Boolean
            Get
248
                Return _underlyingModule.HasAssemblyCompilationRelaxationsAttribute
P
Pilchie 已提交
249 250 251 252 253
            End Get
        End Property

        Friend Overrides ReadOnly Property HasAssemblyRuntimeCompatibilityAttribute As Boolean
            Get
254
                Return _underlyingModule.HasAssemblyRuntimeCompatibilityAttribute
P
Pilchie 已提交
255 256 257 258 259
            End Get
        End Property

        Friend Overrides ReadOnly Property DefaultMarshallingCharSet As CharSet?
            Get
260
                Return _underlyingModule.DefaultMarshallingCharSet
P
Pilchie 已提交
261 262 263 264 265 266
            End Get
        End Property

        ''' <remarks>
        ''' This is for perf, not for correctness.
        ''' </remarks>
A
angocke 已提交
267
        Friend Overrides ReadOnly Property DeclaringCompilation As VisualBasicCompilation
P
Pilchie 已提交
268 269 270 271 272 273
            Get
                Return Nothing
            End Get
        End Property

        Public Overrides Function GetDocumentationCommentXml(Optional preferredCulture As CultureInfo = Nothing, Optional expandIncludes As Boolean = False, Optional cancellationToken As CancellationToken = Nothing) As String
274
            Return _underlyingModule.GetDocumentationCommentXml(preferredCulture, expandIncludes, cancellationToken)
P
Pilchie 已提交
275 276 277
        End Function
    End Class
End Namespace