|
' 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
Imports System.Collections.Generic
Imports System.Collections.Immutable
Imports System.Globalization
Imports System.Runtime.InteropServices
Imports System.Threading
Imports Microsoft.CodeAnalysis.Collections
Imports Microsoft.CodeAnalysis.PooledObjects
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Emit
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports TypeKind = Microsoft.CodeAnalysis.TypeKind
Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Retargeting
''' <summary>
''' Represents a type of a RetargetingModuleSymbol. Essentially this is a wrapper around
''' another NamedTypeSymbol that is responsible for retargeting referenced symbols from one assembly to another.
''' It can retarget symbols for multiple assemblies at the same time.
''' </summary>
Friend NotInheritable Class RetargetingNamedTypeSymbol
Inherits InstanceTypeSymbol
''' <summary>
''' Owning RetargetingModuleSymbol.
''' </summary>
Private ReadOnly _retargetingModule As RetargetingModuleSymbol
''' <summary>
''' The underlying NamedTypeSymbol, cannot be another RetargetingNamedTypeSymbol.
''' </summary>
Private ReadOnly _underlyingType As NamedTypeSymbol
Private _lazyTypeParameters As ImmutableArray(Of TypeParameterSymbol)
Private _lazyCoClass As TypeSymbol = ErrorTypeSymbol.UnknownResultType
''' <summary>
''' Retargeted custom attributes
''' </summary>
Private _lazyCustomAttributes As ImmutableArray(Of VisualBasicAttributeData)
Private _lazyCachedUseSiteInfo As CachedUseSiteInfo(Of AssemblySymbol) = CachedUseSiteInfo(Of AssemblySymbol).Uninitialized ' Indicates unknown state.
Public Sub New(retargetingModule As RetargetingModuleSymbol, underlyingType As NamedTypeSymbol)
Debug.Assert(retargetingModule IsNot Nothing)
Debug.Assert(underlyingType IsNot Nothing)
If TypeOf underlyingType Is RetargetingNamedTypeSymbol Then
Throw New ArgumentException()
End If
_retargetingModule = retargetingModule
_underlyingType = underlyingType
End Sub
Private ReadOnly Property RetargetingTranslator As RetargetingModuleSymbol.RetargetingSymbolTranslator
Get
Return _retargetingModule.RetargetingTranslator
End Get
End Property
Public ReadOnly Property UnderlyingNamedType As NamedTypeSymbol
Get
Return _underlyingType
End Get
End Property
Public Overrides ReadOnly Property IsImplicitlyDeclared As Boolean
Get
Return _underlyingType.IsImplicitlyDeclared
End Get
End Property
Public Overrides ReadOnly Property Arity As Integer
Get
Return _underlyingType.Arity
End Get
End Property
Public Overrides ReadOnly Property TypeParameters As ImmutableArray(Of TypeParameterSymbol)
Get
If _lazyTypeParameters.IsDefault Then
If Me.Arity = 0 Then
_lazyTypeParameters = ImmutableArray(Of TypeParameterSymbol).Empty
Else
ImmutableInterlocked.InterlockedCompareExchange(_lazyTypeParameters,
RetargetingTranslator.Retarget(_underlyingType.TypeParameters), Nothing)
End If
End If
Return _lazyTypeParameters
End Get
End Property
Public Overrides ReadOnly Property ConstructedFrom As NamedTypeSymbol
Get
Return Me
End Get
End Property
Public Overrides ReadOnly Property EnumUnderlyingType As NamedTypeSymbol
Get
Dim underlying = _underlyingType.EnumUnderlyingType
Return If(underlying Is Nothing, Nothing, RetargetingTranslator.Retarget(underlying, RetargetOptions.RetargetPrimitiveTypesByTypeCode)) ' comes from field's signature.
End Get
End Property
Public Overrides ReadOnly Property MightContainExtensionMethods As Boolean
Get
Return _underlyingType.MightContainExtensionMethods
End Get
End Property
Friend Overrides ReadOnly Property HasCodeAnalysisEmbeddedAttribute As Boolean
Get
Return _underlyingType.HasCodeAnalysisEmbeddedAttribute
End Get
End Property
Friend Overrides ReadOnly Property HasVisualBasicEmbeddedAttribute As Boolean
Get
Return _underlyingType.HasVisualBasicEmbeddedAttribute
End Get
End Property
Friend Overrides ReadOnly Property IsExtensibleInterfaceNoUseSiteDiagnostics As Boolean
Get
Return _underlyingType.IsExtensibleInterfaceNoUseSiteDiagnostics
End Get
End Property
Friend Overrides ReadOnly Property IsWindowsRuntimeImport As Boolean
Get
Return _underlyingType.IsWindowsRuntimeImport
End Get
End Property
Friend Overrides ReadOnly Property ShouldAddWinRTMembers As Boolean
Get
Return _underlyingType.ShouldAddWinRTMembers
End Get
End Property
Friend Overrides ReadOnly Property IsComImport As Boolean
Get
Return _underlyingType.IsComImport
End Get
End Property
Friend Overrides ReadOnly Property CoClassType As TypeSymbol
Get
If _lazyCoClass Is ErrorTypeSymbol.UnknownResultType Then
Dim coClass As TypeSymbol = _underlyingType.CoClassType
If coClass IsNot Nothing Then
coClass = RetargetingTranslator.Retarget(coClass, RetargetOptions.RetargetPrimitiveTypesByName)
End If
Interlocked.CompareExchange(_lazyCoClass, coClass, DirectCast(ErrorTypeSymbol.UnknownResultType, TypeSymbol))
End If
Return _lazyCoClass
End Get
End Property
Friend Overrides Function GetAppliedConditionalSymbols() As ImmutableArray(Of String)
Return _underlyingType.GetAppliedConditionalSymbols()
End Function
Friend Overrides Function GetAttributeUsageInfo() As AttributeUsageInfo
Return _underlyingType.GetAttributeUsageInfo()
End Function
Friend Overrides ReadOnly Property HasDeclarativeSecurity As Boolean
Get
Return _underlyingType.HasDeclarativeSecurity
End Get
End Property
Friend Overrides Function GetSecurityInformation() As IEnumerable(Of Microsoft.Cci.SecurityAttribute)
Return _underlyingType.GetSecurityInformation()
End Function
''' <summary>
''' This method is called directly by a Binder when it uses this type.
''' </summary>
Friend Overrides Sub AppendProbableExtensionMethods(name As String, methods As ArrayBuilder(Of MethodSymbol))
Dim oldCount As Integer = methods.Count
' Delegate work to the underlying type.
_underlyingType.AppendProbableExtensionMethods(name, methods)
' Retarget all method symbols appended by the underlying type.
For i As Integer = oldCount To methods.Count - 1
methods(i) = RetargetingTranslator.Retarget(methods(i))
Next
End Sub
Friend Overrides Sub BuildExtensionMethodsMap(
map As Dictionary(Of String, ArrayBuilder(Of MethodSymbol)),
appendThrough As NamespaceSymbol
)
Throw ExceptionUtilities.Unreachable
End Sub
Friend Overrides Sub GetExtensionMethods(methods As ArrayBuilder(Of MethodSymbol), appendThrough As NamespaceSymbol, Name As String)
Throw ExceptionUtilities.Unreachable
End Sub
''' <summary>
''' This method is called directly by a Binder when it uses this type.
''' </summary>
Friend Overrides Sub AddExtensionMethodLookupSymbolsInfo(nameSet As LookupSymbolsInfo,
options As LookupOptions,
originalBinder As Binder)
_underlyingType.AddExtensionMethodLookupSymbolsInfo(nameSet, options, originalBinder, appendThrough:=Me)
End Sub
''' <summary>
''' Make sure we retarget methods when underlying type checks their viability.
''' </summary>
Friend Overrides Function AddExtensionMethodLookupSymbolsInfoViabilityCheck(method As MethodSymbol, options As LookupOptions, nameSet As LookupSymbolsInfo, originalBinder As Binder) As Boolean
Return MyBase.AddExtensionMethodLookupSymbolsInfoViabilityCheck(RetargetingTranslator.Retarget(method), options, nameSet, originalBinder)
End Function
Friend Overrides Sub AddExtensionMethodLookupSymbolsInfo(nameSet As LookupSymbolsInfo,
options As LookupOptions,
originalBinder As Binder,
appendThrough As NamedTypeSymbol)
Throw ExceptionUtilities.Unreachable
End Sub
Public Overrides ReadOnly Property Name As String
Get
Return _underlyingType.Name
End Get
End Property
Public Overrides ReadOnly Property MetadataName As String
Get
Return _underlyingType.MetadataName
End Get
End Property
Friend Overrides ReadOnly Property MangleName As Boolean
Get
Return _underlyingType.MangleName
End Get
End Property
Friend Overrides ReadOnly Property HasSpecialName As Boolean
Get
Return _underlyingType.HasSpecialName
End Get
End Property
Public Overrides ReadOnly Property IsSerializable As Boolean
Get
Return _underlyingType.IsSerializable
End Get
End Property
Friend Overrides ReadOnly Property Layout As TypeLayout
Get
Return _underlyingType.Layout
End Get
End Property
Friend Overrides ReadOnly Property MarshallingCharSet As CharSet
Get
Return _underlyingType.MarshallingCharSet
End Get
End Property
Friend Overrides Function GetEmittedNamespaceName() As String
Return _underlyingType.GetEmittedNamespaceName()
End Function
Public Overrides ReadOnly Property MemberNames As IEnumerable(Of String)
Get
Return _underlyingType.MemberNames
End Get
End Property
Public Overrides Function GetMembers() As ImmutableArray(Of Symbol)
Return RetargetingTranslator.Retarget(_underlyingType.GetMembers())
End Function
Friend Overrides Function GetMembersUnordered() As ImmutableArray(Of Symbol)
Return RetargetingTranslator.Retarget(_underlyingType.GetMembersUnordered())
End Function
Public Overrides Function GetMembers(name As String) As ImmutableArray(Of Symbol)
Return RetargetingTranslator.Retarget(_underlyingType.GetMembers(name))
End Function
Friend Overrides Iterator Function GetFieldsToEmit() As IEnumerable(Of FieldSymbol)
For Each field In _underlyingType.GetFieldsToEmit()
Yield RetargetingTranslator.Retarget(field)
Next
End Function
Friend Overrides Iterator Function GetMethodsToEmit() As IEnumerable(Of MethodSymbol)
Dim isInterface = _underlyingType.IsInterfaceType()
For Each method In _underlyingType.GetMethodsToEmit()
Debug.Assert(method IsNot Nothing)
Dim gapSize = If(isInterface, Microsoft.CodeAnalysis.ModuleExtensions.GetVTableGapSize(method.MetadataName), 0)
If gapSize > 0 Then
Do
Yield Nothing
gapSize -= 1
Loop While gapSize > 0
Else
Yield RetargetingTranslator.Retarget(method)
End If
Next
End Function
Friend Overrides Iterator Function GetPropertiesToEmit() As IEnumerable(Of PropertySymbol)
For Each [property] In _underlyingType.GetPropertiesToEmit()
Yield RetargetingTranslator.Retarget([property])
Next
End Function
Friend Overrides Iterator Function GetEventsToEmit() As IEnumerable(Of EventSymbol)
For Each [event] In _underlyingType.GetEventsToEmit()
Yield RetargetingTranslator.Retarget([event])
Next
End Function
Friend Overrides Function GetTypeMembersUnordered() As ImmutableArray(Of NamedTypeSymbol)
Return RetargetingTranslator.Retarget(_underlyingType.GetTypeMembersUnordered())
End Function
Public Overrides Function GetTypeMembers() As ImmutableArray(Of NamedTypeSymbol)
Return RetargetingTranslator.Retarget(_underlyingType.GetTypeMembers())
End Function
Public Overrides Function GetTypeMembers(name As String) As ImmutableArray(Of NamedTypeSymbol)
Return RetargetingTranslator.Retarget(_underlyingType.GetTypeMembers(name))
End Function
Public Overrides Function GetTypeMembers(name As String, arity As Integer) As ImmutableArray(Of NamedTypeSymbol)
Return RetargetingTranslator.Retarget(_underlyingType.GetTypeMembers(name, arity))
End Function
Public Overrides ReadOnly Property DeclaredAccessibility As Accessibility
Get
Return _underlyingType.DeclaredAccessibility
End Get
End Property
Friend Overrides Function MakeDeclaredBase(basesBeingResolved As BasesBeingResolved, diagnostics As BindingDiagnosticBag) As NamedTypeSymbol
Dim underlyingBase = _underlyingType.GetDeclaredBase(basesBeingResolved)
Return If(underlyingBase IsNot Nothing,
RetargetingTranslator.Retarget(underlyingBase, RetargetOptions.RetargetPrimitiveTypesByName),
Nothing)
End Function
Friend Overrides Function GetInterfacesToEmit() As IEnumerable(Of NamedTypeSymbol)
Return RetargetingTranslator.Retarget(_underlyingType.GetInterfacesToEmit())
End Function
Friend Overrides Function MakeDeclaredInterfaces(basesBeingResolved As BasesBeingResolved, diagnostics As BindingDiagnosticBag) As ImmutableArray(Of NamedTypeSymbol)
Dim underlyingBaseInterfaces = _underlyingType.GetDeclaredInterfacesNoUseSiteDiagnostics(basesBeingResolved)
Return RetargetingTranslator.Retarget(underlyingBaseInterfaces)
End Function
Private Shared Function CyclicInheritanceError(diag As DiagnosticInfo) As ErrorTypeSymbol
Return New ExtendedErrorTypeSymbol(diag, True)
End Function
Friend Overrides Function MakeAcyclicBaseType(diagnostics As BindingDiagnosticBag) As NamedTypeSymbol
Dim diag = BaseTypeAnalysis.GetDependencyDiagnosticsForImportedClass(Me)
If diag IsNot Nothing Then
Return CyclicInheritanceError(diag)
End If
Dim acyclicBase = GetDeclaredBase(Nothing)
If acyclicBase Is Nothing Then
' if base was not declared, get it from BaseType that should set it to some default
Dim underlyingBase = _underlyingType.BaseTypeNoUseSiteDiagnostics
If underlyingBase IsNot Nothing Then
acyclicBase = RetargetingTranslator.Retarget(underlyingBase, RetargetOptions.RetargetPrimitiveTypesByName)
End If
End If
Return acyclicBase
End Function
Friend Overrides Function MakeAcyclicInterfaces(diagnostics As BindingDiagnosticBag) As ImmutableArray(Of NamedTypeSymbol)
Dim declaredInterfaces As ImmutableArray(Of NamedTypeSymbol) = GetDeclaredInterfacesNoUseSiteDiagnostics(Nothing)
If (Not Me.IsInterface) Then
' only interfaces needs to check for inheritance cycles via interfaces.
Return declaredInterfaces
End If
Return (From t In declaredInterfaces
Let diag = BaseTypeAnalysis.GetDependencyDiagnosticsForImportedBaseInterface(Me, t)
Select If(diag Is Nothing, t, CyclicInheritanceError(diag))).AsImmutable
End Function
Public Overrides ReadOnly Property TypeKind As TypeKind
Get
Return _underlyingType.TypeKind
End Get
End Property
Friend Overrides ReadOnly Property IsInterface As Boolean
Get
Return _underlyingType.IsInterface
End Get
End Property
Public Overrides ReadOnly Property ContainingSymbol As Symbol
Get
Return RetargetingTranslator.Retarget(_underlyingType.ContainingSymbol)
End Get
End Property
Public Overrides ReadOnly Property Locations As ImmutableArray(Of Location)
Get
Return _underlyingType.Locations
End Get
End Property
Public Overrides ReadOnly Property DeclaringSyntaxReferences As ImmutableArray(Of SyntaxReference)
Get
Return _underlyingType.DeclaringSyntaxReferences
End Get
End Property
Public Overrides ReadOnly Property IsMustInherit As Boolean
Get
Return _underlyingType.IsMustInherit
End Get
End Property
Friend Overrides ReadOnly Property IsMetadataAbstract As Boolean
Get
Return _underlyingType.IsMetadataAbstract
End Get
End Property
Public Overrides ReadOnly Property IsNotInheritable As Boolean
Get
Return _underlyingType.IsNotInheritable
End Get
End Property
Friend Overrides ReadOnly Property IsMetadataSealed As Boolean
Get
Return _underlyingType.IsMetadataSealed
End Get
End Property
Friend Overrides ReadOnly Property ObsoleteAttributeData As ObsoleteAttributeData
Get
Return _underlyingType.ObsoleteAttributeData
End Get
End Property
Public Overrides Function GetAttributes() As ImmutableArray(Of VisualBasicAttributeData)
Return RetargetingTranslator.GetRetargetedAttributes(_underlyingType, _lazyCustomAttributes)
End Function
Friend Overrides Function GetCustomAttributesToEmit(moduleBuilder As PEModuleBuilder) As IEnumerable(Of VisualBasicAttributeData)
Return RetargetingTranslator.RetargetAttributes(_underlyingType.GetCustomAttributesToEmit(moduleBuilder))
End Function
Public Overrides ReadOnly Property ContainingAssembly As AssemblySymbol
Get
Return _retargetingModule.ContainingAssembly
End Get
End Property
Public Overrides ReadOnly Property ContainingModule As ModuleSymbol
Get
Return _retargetingModule
End Get
End Property
Friend Overrides Function LookupMetadataType(ByRef emittedTypeName As MetadataTypeName) As NamedTypeSymbol
Dim underlying As NamedTypeSymbol = _underlyingType.LookupMetadataType(emittedTypeName)
If underlying Is Nothing Then
Return Nothing
End If
Debug.Assert(Not underlying.IsErrorType())
Return RetargetingTranslator.Retarget(underlying, RetargetOptions.RetargetPrimitiveTypesByName)
End Function
Friend Overrides Function GetUseSiteInfo() As UseSiteInfo(Of AssemblySymbol)
Dim primaryDependency As AssemblySymbol = Me.PrimaryDependency
If Not _lazyCachedUseSiteInfo.IsInitialized Then
_lazyCachedUseSiteInfo.Initialize(primaryDependency, CalculateUseSiteInfo())
End If
Return _lazyCachedUseSiteInfo.ToUseSiteInfo(primaryDependency)
End Function
Friend Overrides ReadOnly Property DefaultPropertyName As String
Get
Return _underlyingType.DefaultPropertyName
End Get
End Property
''' <summary>
''' Force all declaration errors to be generated.
''' </summary>
Friend Overrides Sub GenerateDeclarationErrors(cancellationToken As CancellationToken)
Throw ExceptionUtilities.Unreachable
End Sub
''' <remarks>
''' This is for perf, not for correctness.
''' </remarks>
Friend Overrides ReadOnly Property DeclaringCompilation As VisualBasicCompilation
Get
Return Nothing
End Get
End Property
Friend Overrides Function GetGuidString(ByRef guidString As String) As Boolean
Return _underlyingType.GetGuidString(guidString)
End Function
Public Overrides Function GetDocumentationCommentXml(Optional preferredCulture As CultureInfo = Nothing, Optional expandIncludes As Boolean = False, Optional cancellationToken As CancellationToken = Nothing) As String
Return _underlyingType.GetDocumentationCommentXml(preferredCulture, expandIncludes, cancellationToken)
End Function
Friend Overrides Iterator Function GetSynthesizedWithEventsOverrides() As IEnumerable(Of PropertySymbol)
For Each underlying As PropertySymbol In _underlyingType.GetSynthesizedWithEventsOverrides()
Yield RetargetingTranslator.Retarget(underlying)
Next
End Function
Friend Overrides ReadOnly Property HasAnyDeclaredRequiredMembers As Boolean
Get
Debug.Assert(Not _underlyingType.HasAnyDeclaredRequiredMembers)
Return False
End Get
End Property
End Class
End Namespace
|