|
' 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.Generic
Imports System.Collections.Immutable
Imports System.Globalization
Imports System.Runtime.InteropServices
Imports System.Threading
Imports Microsoft.CodeAnalysis.PooledObjects
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports TypeKind = Microsoft.CodeAnalysis.TypeKind
Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
''' <summary>
''' A SubstitutedNamedType represents a named type that has had some sort
''' of substitution applied to it. I.e., its not a pure instance type, but at least
''' one type parameter in this type or a containing type has a substitution made for
''' it.
''' </summary>
Friend MustInherit Class SubstitutedNamedType
Inherits NamedTypeSymbol
''' <summary>
''' Type substitution for this symbol, it targets OriginalDefinition of the symbol.
''' </summary>
Private ReadOnly _substitution As TypeSubstitution
Private Sub New(substitution As TypeSubstitution)
Debug.Assert(substitution IsNot Nothing)
Debug.Assert(substitution.TargetGenericDefinition.IsDefinition)
Debug.Assert(TypeOf substitution.TargetGenericDefinition Is InstanceTypeSymbol) ' Required to ensure symmetrical equality
_substitution = substitution
End Sub
Public NotOverridable Overrides ReadOnly Property Name As String
Get
Return OriginalDefinition.Name
End Get
End Property
Friend NotOverridable Overrides ReadOnly Property MangleName As Boolean
Get
Return OriginalDefinition.MangleName
End Get
End Property
Public NotOverridable Overrides ReadOnly Property MetadataName As String
Get
Return OriginalDefinition.MetadataName
End Get
End Property
Friend NotOverridable Overrides ReadOnly Property DefaultPropertyName As String
Get
Return OriginalDefinition.DefaultPropertyName
End Get
End Property
Friend NotOverridable Overrides ReadOnly Property HasSpecialName As Boolean
Get
Return OriginalDefinition.HasSpecialName
End Get
End Property
Public NotOverridable Overrides ReadOnly Property IsSerializable As Boolean
Get
Return OriginalDefinition.IsSerializable
End Get
End Property
Friend Overrides ReadOnly Property Layout As TypeLayout
Get
Return OriginalDefinition.Layout
End Get
End Property
Friend Overrides ReadOnly Property MarshallingCharSet As CharSet
Get
Return OriginalDefinition.MarshallingCharSet
End Get
End Property
Friend NotOverridable Overrides ReadOnly Property TypeSubstitution As TypeSubstitution
Get
Return _substitution
End Get
End Property
Public NotOverridable Overrides ReadOnly Property OriginalDefinition As NamedTypeSymbol
Get
Return DirectCast(_substitution.TargetGenericDefinition, NamedTypeSymbol)
End Get
End Property
Public NotOverridable Overrides ReadOnly Property ContainingAssembly As AssemblySymbol
Get
Return OriginalDefinition.ContainingAssembly
End Get
End Property
Public NotOverridable Overrides ReadOnly Property Arity As Integer
Get
Return OriginalDefinition.Arity
End Get
End Property
Public NotOverridable Overrides ReadOnly Property DeclaredAccessibility As Accessibility
Get
Return OriginalDefinition.DeclaredAccessibility
End Get
End Property
Public NotOverridable Overrides ReadOnly Property IsMustInherit As Boolean
Get
Return OriginalDefinition.IsMustInherit
End Get
End Property
Public NotOverridable Overrides ReadOnly Property IsNotInheritable As Boolean
Get
Return OriginalDefinition.IsNotInheritable
End Get
End Property
Public NotOverridable Overrides ReadOnly Property IsImplicitlyDeclared As Boolean
Get
Return OriginalDefinition.IsImplicitlyDeclared
End Get
End Property
Friend NotOverridable Overrides ReadOnly Property EmbeddedSymbolKind As EmbeddedSymbolKind
Get
Return OriginalDefinition.EmbeddedSymbolKind
End Get
End Property
Public NotOverridable Overrides ReadOnly Property MightContainExtensionMethods As Boolean
Get
Return OriginalDefinition.MightContainExtensionMethods
End Get
End Property
Friend NotOverridable Overrides ReadOnly Property HasCodeAnalysisEmbeddedAttribute As Boolean
Get
Return OriginalDefinition.HasCodeAnalysisEmbeddedAttribute
End Get
End Property
Friend NotOverridable Overrides ReadOnly Property HasVisualBasicEmbeddedAttribute As Boolean
Get
Return OriginalDefinition.HasVisualBasicEmbeddedAttribute
End Get
End Property
Friend Overrides ReadOnly Property IsExtensibleInterfaceNoUseSiteDiagnostics As Boolean
Get
Return OriginalDefinition.IsExtensibleInterfaceNoUseSiteDiagnostics
End Get
End Property
Friend NotOverridable Overrides ReadOnly Property IsWindowsRuntimeImport As Boolean
Get
Return OriginalDefinition.IsWindowsRuntimeImport
End Get
End Property
Friend NotOverridable Overrides ReadOnly Property ShouldAddWinRTMembers As Boolean
Get
Return OriginalDefinition.ShouldAddWinRTMembers
End Get
End Property
Friend NotOverridable Overrides ReadOnly Property IsComImport As Boolean
Get
Return OriginalDefinition.IsComImport
End Get
End Property
Friend Overrides ReadOnly Property CoClassType As TypeSymbol
Get
Return OriginalDefinition.CoClassType
End Get
End Property
Friend NotOverridable Overrides Function GetAppliedConditionalSymbols() As ImmutableArray(Of String)
Return OriginalDefinition.GetAppliedConditionalSymbols()
End Function
Friend NotOverridable Overrides Function GetAttributeUsageInfo() As AttributeUsageInfo
Return OriginalDefinition.GetAttributeUsageInfo()
End Function
Friend NotOverridable Overrides ReadOnly Property HasDeclarativeSecurity As Boolean
Get
Return OriginalDefinition.HasDeclarativeSecurity
End Get
End Property
Friend NotOverridable Overrides Function GetSecurityInformation() As IEnumerable(Of Microsoft.Cci.SecurityAttribute)
Return OriginalDefinition.GetSecurityInformation()
End Function
Public NotOverridable Overrides ReadOnly Property TypeKind As TypeKind
Get
Return OriginalDefinition.TypeKind
End Get
End Property
Friend Overrides ReadOnly Property IsInterface As Boolean
Get
Return OriginalDefinition.IsInterface
End Get
End Property
Public NotOverridable Overrides ReadOnly Property Locations As ImmutableArray(Of Location)
Get
Return OriginalDefinition.Locations
End Get
End Property
Public NotOverridable Overrides ReadOnly Property DeclaringSyntaxReferences As ImmutableArray(Of SyntaxReference)
Get
Return OriginalDefinition.DeclaringSyntaxReferences
End Get
End Property
Public NotOverridable Overrides Function GetAttributes() As ImmutableArray(Of VisualBasicAttributeData)
Return OriginalDefinition.GetAttributes()
End Function
Public NotOverridable Overrides ReadOnly Property EnumUnderlyingType As NamedTypeSymbol
Get
Return OriginalDefinition.EnumUnderlyingType
End Get
End Property
Friend NotOverridable Overrides ReadOnly Property ObsoleteAttributeData As ObsoleteAttributeData
Get
Return OriginalDefinition.ObsoleteAttributeData
End Get
End Property
Friend NotOverridable Overrides Function MakeDeclaredBase(basesBeingResolved As BasesBeingResolved, diagnostics As BindingDiagnosticBag) As NamedTypeSymbol
Return DirectCast(OriginalDefinition.GetDeclaredBase(basesBeingResolved).InternalSubstituteTypeParameters(_substitution).AsTypeSymbolOnly(), NamedTypeSymbol)
End Function
Friend NotOverridable Overrides Function MakeDeclaredInterfaces(basesBeingResolved As BasesBeingResolved, diagnostics As BindingDiagnosticBag) As ImmutableArray(Of NamedTypeSymbol)
Dim instanceInterfaces = OriginalDefinition.GetDeclaredInterfacesNoUseSiteDiagnostics(basesBeingResolved)
If instanceInterfaces.Length = 0 Then
Return ImmutableArray(Of NamedTypeSymbol).Empty
Else
Dim substitutedInterfaces = New NamedTypeSymbol(instanceInterfaces.Length - 1) {}
For i As Integer = 0 To instanceInterfaces.Length - 1 Step 1
substitutedInterfaces(i) = DirectCast(instanceInterfaces(i).InternalSubstituteTypeParameters(_substitution).AsTypeSymbolOnly(), NamedTypeSymbol)
Next
Return substitutedInterfaces.AsImmutableOrNull
End If
End Function
Friend NotOverridable Overrides Function MakeAcyclicBaseType(diagnostics As BindingDiagnosticBag) As NamedTypeSymbol
Dim fullBase = OriginalDefinition.BaseTypeNoUseSiteDiagnostics
If fullBase IsNot Nothing Then
Return DirectCast(fullBase.InternalSubstituteTypeParameters(_substitution).AsTypeSymbolOnly(), NamedTypeSymbol)
End If
Return Nothing
End Function
Friend NotOverridable Overrides Function MakeAcyclicInterfaces(diagnostics As BindingDiagnosticBag) As ImmutableArray(Of NamedTypeSymbol)
Dim instanceInterfaces = OriginalDefinition.InterfacesNoUseSiteDiagnostics
If instanceInterfaces.Length = 0 Then
Return ImmutableArray(Of NamedTypeSymbol).Empty
Else
Dim substitutedInterfaces = New NamedTypeSymbol(instanceInterfaces.Length - 1) {}
For i As Integer = 0 To instanceInterfaces.Length - 1 Step 1
substitutedInterfaces(i) = DirectCast(instanceInterfaces(i).InternalSubstituteTypeParameters(_substitution).AsTypeSymbolOnly(), NamedTypeSymbol)
Next
Return substitutedInterfaces.AsImmutableOrNull()
End If
End Function
Private Overloads Function SubstituteTypeParametersForMemberType(memberType As NamedTypeSymbol) As NamedTypeSymbol
Debug.Assert(memberType.IsDefinition AndAlso memberType.ContainingSymbol Is Me.OriginalDefinition)
If memberType.Arity = 0 Then
Return SpecializedNonGenericType.Create(Me, memberType, _substitution)
End If
Return SpecializedGenericType.Create(Me, memberType)
End Function
Protected Overridable Function SubstituteTypeParametersForMemberMethod(memberMethod As MethodSymbol) As SubstitutedMethodSymbol
If memberMethod.Arity > 0 Then
Return SubstitutedMethodSymbol.SpecializedGenericMethod.Create(Me, memberMethod)
End If
Return New SubstitutedMethodSymbol.SpecializedNonGenericMethod(Me, memberMethod)
End Function
Protected Overridable Function SubstituteTypeParametersForMemberField(memberField As FieldSymbol) As SubstitutedFieldSymbol
Return New SubstitutedFieldSymbol(Me, memberField)
End Function
Private Function SubstituteTypeParametersForMemberProperty(memberProperty As PropertySymbol) As SubstitutedPropertySymbol
Dim getMethod = If(memberProperty.GetMethod Is Nothing, Nothing, SubstituteTypeParametersForMemberMethod(memberProperty.GetMethod))
Dim setMethod = If(memberProperty.SetMethod Is Nothing, Nothing, SubstituteTypeParametersForMemberMethod(memberProperty.SetMethod))
Dim associatedField = If(memberProperty.AssociatedField Is Nothing, Nothing, SubstituteTypeParametersForMemberField(memberProperty.AssociatedField))
Return New SubstitutedPropertySymbol(Me, memberProperty, getMethod, setMethod, associatedField)
End Function
Private Function SubstituteTypeParametersForMemberEvent(memberEvent As EventSymbol) As SubstitutedEventSymbol
Dim addMethod = If(memberEvent.AddMethod Is Nothing, Nothing, SubstituteTypeParametersForMemberMethod(memberEvent.AddMethod))
Dim removeMethod = If(memberEvent.RemoveMethod Is Nothing, Nothing, SubstituteTypeParametersForMemberMethod(memberEvent.RemoveMethod))
Dim raiseMethod = If(memberEvent.RaiseMethod Is Nothing, Nothing, SubstituteTypeParametersForMemberMethod(memberEvent.RaiseMethod))
Dim associatedField = If(memberEvent.AssociatedField Is Nothing, Nothing, SubstituteTypeParametersForMemberField(memberEvent.AssociatedField))
Return CreateSubstitutedEventSymbol(memberEvent, addMethod, removeMethod, raiseMethod, associatedField)
End Function
Public Overrides ReadOnly Property MemberNames As IEnumerable(Of String)
Get
Return OriginalDefinition.MemberNames
End Get
End Property
Public Overrides Function GetMembers() As ImmutableArray(Of Symbol)
Dim members = OriginalDefinition.GetMembers()
Return GetMembers_Worker(members)
End Function
Friend Overrides Function GetMembersUnordered() As ImmutableArray(Of Symbol)
Dim members = OriginalDefinition.GetMembersUnordered()
Return GetMembers_Worker(members)
End Function
Private Function GetMembers_Worker(members As ImmutableArray(Of Symbol)) As ImmutableArray(Of Symbol)
Dim result = ArrayBuilder(Of Symbol).GetInstance()
' Substitute methods first to ensure accessor methods are
' available when constructing properties and events.
Dim methodSubstitutions = members.OfType(Of MethodSymbol)().ToDictionary(Function(m) m, Function(m) SubstituteTypeParametersForMemberMethod(m))
' Substitute remaining members.
For Each member In members
Select Case member.Kind
Case SymbolKind.NamedType
result.Add(SubstituteTypeParametersForMemberType(DirectCast(member, NamedTypeSymbol)))
Case SymbolKind.Method
result.Add(methodSubstitutions(DirectCast(member, MethodSymbol)))
Case SymbolKind.Property
Dim memberProperty = DirectCast(member, PropertySymbol)
Dim getMethod = GetMethodSubstitute(methodSubstitutions, memberProperty.GetMethod)
Dim setMethod = GetMethodSubstitute(methodSubstitutions, memberProperty.SetMethod)
Dim associatedField = If(memberProperty.AssociatedField Is Nothing, Nothing, SubstituteTypeParametersForMemberField(memberProperty.AssociatedField))
result.Add(New SubstitutedPropertySymbol(Me, memberProperty, getMethod, setMethod, associatedField))
Case SymbolKind.Event
Dim memberEvent = DirectCast(member, EventSymbol)
Dim addMethod = GetMethodSubstitute(methodSubstitutions, memberEvent.AddMethod)
Dim removeMethod = GetMethodSubstitute(methodSubstitutions, memberEvent.RemoveMethod)
Dim raiseMethod = GetMethodSubstitute(methodSubstitutions, memberEvent.RaiseMethod)
Dim associatedField = If(memberEvent.AssociatedField Is Nothing, Nothing, SubstituteTypeParametersForMemberField(memberEvent.AssociatedField))
result.Add(CreateSubstitutedEventSymbol(memberEvent, addMethod, removeMethod, raiseMethod, associatedField))
Case SymbolKind.Field
result.Add(SubstituteTypeParametersForMemberField(DirectCast(member, FieldSymbol)))
Case Else
Throw ExceptionUtilities.UnexpectedValue(member.Kind)
End Select
Next
Return result.ToImmutableAndFree()
End Function
Protected Overridable Function CreateSubstitutedEventSymbol(memberEvent As EventSymbol,
addMethod As SubstitutedMethodSymbol,
removeMethod As SubstitutedMethodSymbol,
raiseMethod As SubstitutedMethodSymbol,
associatedField As SubstitutedFieldSymbol) As SubstitutedEventSymbol
Return New SubstitutedEventSymbol(Me, memberEvent, addMethod, removeMethod, raiseMethod, associatedField)
End Function
Private Shared Function GetMethodSubstitute(methodSubstitutions As Dictionary(Of MethodSymbol, SubstitutedMethodSymbol), method As MethodSymbol) As SubstitutedMethodSymbol
Return If((method Is Nothing), Nothing, methodSubstitutions(method))
End Function
Public Overrides Function GetMembers(name As String) As ImmutableArray(Of Symbol)
' TODO - Perf
Return OriginalDefinition.GetMembers(name).SelectAsArray(Function(member, self) self.SubstituteTypeParametersInMember(member), Me)
End Function
Friend Overrides Function GetTypeMembersUnordered() As ImmutableArray(Of NamedTypeSymbol)
Return OriginalDefinition.GetTypeMembersUnordered().SelectAsArray(Function(nestedType, self) self.SubstituteTypeParametersForMemberType(nestedType), Me)
End Function
Public Overrides Function GetTypeMembers() As ImmutableArray(Of NamedTypeSymbol)
Return OriginalDefinition.GetTypeMembers().SelectAsArray(Function(nestedType, self) self.SubstituteTypeParametersForMemberType(nestedType), Me)
End Function
Public Overrides Function GetTypeMembers(name As String) As ImmutableArray(Of NamedTypeSymbol)
' TODO - Perf
Return OriginalDefinition.GetTypeMembers(name).SelectAsArray(Function(nestedType, self) self.SubstituteTypeParametersForMemberType(nestedType), Me)
End Function
Public Overrides Function GetTypeMembers(name As String, arity As Integer) As ImmutableArray(Of NamedTypeSymbol)
Return OriginalDefinition.GetTypeMembers(name, arity).SelectAsArray(Function(nestedType, self) self.SubstituteTypeParametersForMemberType(nestedType), Me)
End Function
Friend NotOverridable Overrides Function GetFieldsToEmit() As IEnumerable(Of FieldSymbol)
Throw ExceptionUtilities.Unreachable
End Function
' Given a member from the original type of this type, substitute into it and get the corresponding member in this type.
Friend Function GetMemberForDefinition(member As Symbol) As Symbol
Debug.Assert(member.IsDefinition)
Debug.Assert(TypeSymbol.Equals(member.ContainingType, Me.OriginalDefinition, TypeCompareKind.ConsiderEverything))
Return SubstituteTypeParametersInMember(member)
End Function
' Given a member from the full instance type, substitute into it and get the new member in this type.
Private Function SubstituteTypeParametersInMember(member As Symbol) As Symbol
Select Case member.Kind
Case SymbolKind.NamedType
Return SubstituteTypeParametersForMemberType(DirectCast(member, NamedTypeSymbol))
Case SymbolKind.Method
Dim memberMethod = DirectCast(member, MethodSymbol)
' If the method is a property or event accessor, substitute the property or event
' and return the specific accessor so that AssociatedPropertyOrEvent is set correctly
' on the returned accessor. Note: since this function is used to substitute members
' on demand, if this function is called for a property and it's accessor methods
' individually, we'll end up creating 3 properties, 3 get accessors, and 3 set accessors.
Select Case memberMethod.MethodKind
Case MethodKind.PropertyGet, MethodKind.PropertySet
Debug.Assert(memberMethod.AssociatedSymbol IsNot Nothing)
Dim propertySymbol = SubstituteTypeParametersForMemberProperty(DirectCast(memberMethod.AssociatedSymbol, PropertySymbol))
Return If(memberMethod.MethodKind = MethodKind.PropertyGet, propertySymbol.GetMethod, propertySymbol.SetMethod)
Case MethodKind.EventAdd
Debug.Assert(memberMethod.AssociatedSymbol IsNot Nothing)
Dim eventSymbol = SubstituteTypeParametersForMemberEvent(DirectCast(memberMethod.AssociatedSymbol, EventSymbol))
Return eventSymbol.AddMethod
Case MethodKind.EventRemove
Debug.Assert(memberMethod.AssociatedSymbol IsNot Nothing)
Dim eventSymbol = SubstituteTypeParametersForMemberEvent(DirectCast(memberMethod.AssociatedSymbol, EventSymbol))
Return eventSymbol.RemoveMethod
Case MethodKind.EventRaise
Debug.Assert(memberMethod.AssociatedSymbol IsNot Nothing)
Dim eventSymbol = SubstituteTypeParametersForMemberEvent(DirectCast(memberMethod.AssociatedSymbol, EventSymbol))
Return eventSymbol.RaiseMethod
Case Else
Return SubstituteTypeParametersForMemberMethod(memberMethod)
End Select
Case SymbolKind.Property
Return SubstituteTypeParametersForMemberProperty(DirectCast(member, PropertySymbol))
Case SymbolKind.Event
Return SubstituteTypeParametersForMemberEvent(DirectCast(member, EventSymbol))
Case SymbolKind.Field
Return SubstituteTypeParametersForMemberField(DirectCast(member, FieldSymbol))
Case Else
Throw ExceptionUtilities.UnexpectedValue(member.Kind)
End Select
End Function
Public NotOverridable Overrides Function GetHashCode() As Integer
Dim hash As Integer = OriginalDefinition.GetHashCode()
If Me._substitution.WasConstructedForModifiers() Then
Return hash
End If
hash = Roslyn.Utilities.Hash.Combine(ContainingType, hash)
' There is a circularity problem here with alpha-renamed type parameters.
' Calculating GetHashCode for them calls back into container's GetHashCode.
If Me IsNot Me.ConstructedFrom Then
For Each typeArgument In TypeArgumentsNoUseSiteDiagnostics
hash = Roslyn.Utilities.Hash.Combine(typeArgument, hash)
Next
End If
Return hash
End Function
Public NotOverridable Overrides Function Equals(other As TypeSymbol, comparison As TypeCompareKind) As Boolean
If other Is Me Then
Return True
End If
If other Is Nothing Then
Return False
End If
If (comparison And TypeCompareKind.AllIgnoreOptionsForVB) = 0 AndAlso
Not Me.GetType().Equals(other.GetType()) Then
Return False
End If
Dim otherTuple = TryCast(other, TupleTypeSymbol)
If otherTuple IsNot Nothing Then
Return otherTuple.Equals(Me, comparison)
End If
If Not OriginalDefinition.Equals(other.OriginalDefinition) Then
Return False
End If
Dim containingType = Me.ContainingType
If containingType IsNot Nothing AndAlso
Not containingType.Equals(other.ContainingType, comparison) Then
Return False
End If
Dim otherNamed = DirectCast(other, NamedTypeSymbol)
If Me Is Me.ConstructedFrom AndAlso otherNamed Is otherNamed.ConstructedFrom Then
' No need to compare type arguments on those containers when they didn't add type arguments.
' That would cause cycles because Equals for them calls back into container's Equals.
Return True
End If
Dim arguments = TypeArgumentsNoUseSiteDiagnostics
Dim otherArguments = otherNamed.TypeArgumentsNoUseSiteDiagnostics
Dim count As Integer = arguments.Length
For i As Integer = 0 To count - 1 Step 1
If Not arguments(i).Equals(otherArguments(i), comparison) Then
Return False
End If
Next
If (comparison And TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds) = 0 AndAlso
Not HasSameTypeArgumentCustomModifiers(Me, otherNamed) Then
Return False
End If
Return True
End Function
Friend Overrides Function GetDirectBaseTypeNoUseSiteDiagnostics(basesBeingResolved As BasesBeingResolved) As NamedTypeSymbol
Dim fullBase = OriginalDefinition.GetDirectBaseTypeNoUseSiteDiagnostics(basesBeingResolved)
If fullBase IsNot Nothing Then
Return DirectCast(fullBase.InternalSubstituteTypeParameters(_substitution).AsTypeSymbolOnly(), NamedTypeSymbol)
End If
Return Nothing
End Function
Public Overrides Function GetDocumentationCommentXml(Optional preferredCulture As CultureInfo = Nothing, Optional expandIncludes As Boolean = False, Optional cancellationToken As CancellationToken = Nothing) As String
Return OriginalDefinition.GetDocumentationCommentXml(preferredCulture, expandIncludes, cancellationToken)
End Function
Friend NotOverridable Overrides Iterator Function GetSynthesizedWithEventsOverrides() As IEnumerable(Of PropertySymbol)
For Each definition In OriginalDefinition.GetSynthesizedWithEventsOverrides()
Yield SubstituteTypeParametersForMemberProperty(definition)
Next
End Function
Friend Overrides ReadOnly Property HasAnyDeclaredRequiredMembers As Boolean
Get
Return OriginalDefinition.HasAnyDeclaredRequiredMembers
End Get
End Property
Friend Overrides Function GetGuidString(ByRef guidString As String) As Boolean
Return OriginalDefinition.GetGuidString(guidString)
End Function
''' <summary>
''' Base class for symbols representing non-generic or open generic types contained within constructed generic type.
''' For example: A(Of Integer).B, A(Of Integer).B.C or A(Of Integer).B.C(Of ).
''' </summary>
Friend MustInherit Class SpecializedType
Inherits SubstitutedNamedType
''' <summary>
''' Symbol for the containing type, either specialized or constructed.
''' </summary>
Protected ReadOnly _container As NamedTypeSymbol
Protected Sub New(container As NamedTypeSymbol, substitution As TypeSubstitution)
MyBase.New(substitution)
Debug.Assert(container IsNot Nothing)
Debug.Assert(TypeOf container Is SubstitutedNamedType)
Debug.Assert(substitution.Parent Is container.TypeSubstitution)
_container = container
End Sub
Public Overrides ReadOnly Property ConstructedFrom As NamedTypeSymbol
Get
Return Me
End Get
End Property
Public NotOverridable Overrides ReadOnly Property ContainingSymbol As Symbol
Get
Return _container
End Get
End Property
Public Shadows ReadOnly Property ContainingType As NamedTypeSymbol
Get
Return _container
End Get
End Property
Friend NotOverridable Overrides Function GetUnificationUseSiteDiagnosticRecursive(owner As Symbol, ByRef checkedTypes As HashSet(Of TypeSymbol)) As DiagnosticInfo
Return Nothing
End Function
End Class
''' <summary>
''' Symbol representing open generic type directly or indirectly contained within constructed
''' generic type.
''' For example: A(Of Integer).B(Of ) or A(Of Integer).B.C(Of , )
''' </summary>
Friend Class SpecializedGenericType
Inherits SpecializedType
''' <summary>
''' Alpha-renamed type parameters, i.e. type parameters with constraints substituted according
''' to containing type's TypeSubstitution.
''' For example:
''' Class A (Of T)
''' Class B(Of S As T)
''' Dim x As A(Of Integer).B(Of S) 'error BC32044: Type argument 'S' does not inherit from or implement the constraint type 'Integer'.
''' End Class
''' End Class
'''
''' Given a type A(Of IComparable).B(Of ), alpha-renamed type parameter S will have type constraint IComparable.
''' </summary>
Private ReadOnly _typeParameters As ImmutableArray(Of TypeParameterSymbol)
Public Shared Function Create(
container As NamedTypeSymbol,
fullInstanceType As NamedTypeSymbol
) As SpecializedGenericType
Debug.Assert(fullInstanceType.IsDefinition)
Debug.Assert(fullInstanceType.Arity > 0)
' Create alpha-renamed type parameters.
' Note that these type parameters don't have their containing symbol set yet.
' It will be done later, in the constructor of this type.
Dim typeParametersDefinitions As ImmutableArray(Of TypeParameterSymbol) = fullInstanceType.TypeParameters
Dim alphaRenamedTypeParameters = New SubstitutedTypeParameterSymbol(typeParametersDefinitions.Length - 1) {}
For i As Integer = 0 To typeParametersDefinitions.Length - 1 Step 1
alphaRenamedTypeParameters(i) = New SubstitutedTypeParameterSymbol(typeParametersDefinitions(i))
Next
Dim newTypeParameters = alphaRenamedTypeParameters.AsImmutableOrNull()
' Add a substitution to map from type parameter definitions to corresponding
' alpha-renamed type parameters.
Debug.Assert(container.TypeSubstitution IsNot Nothing AndAlso
container.TypeSubstitution.TargetGenericDefinition Is fullInstanceType.ContainingSymbol)
Dim substitution = VisualBasic.Symbols.TypeSubstitution.CreateForAlphaRename(container.TypeSubstitution, newTypeParameters)
Debug.Assert(substitution.TargetGenericDefinition Is fullInstanceType)
' Now create the symbol.
Return New SpecializedGenericType(container, substitution, newTypeParameters)
End Function
Private Sub New(
container As NamedTypeSymbol,
substitution As TypeSubstitution,
typeParameters As ImmutableArray(Of SubstitutedTypeParameterSymbol)
)
MyBase.New(container, substitution)
Debug.Assert(Not typeParameters.IsDefault AndAlso typeParameters.Length = DirectCast(substitution.TargetGenericDefinition, NamedTypeSymbol).Arity)
_typeParameters = StaticCast(Of TypeParameterSymbol).From(typeParameters)
' Set container for type parameters
For Each param In typeParameters
param.SetContainingSymbol(Me)
Next
End Sub
Public Overrides ReadOnly Property TypeParameters As ImmutableArray(Of TypeParameterSymbol)
Get
Return _typeParameters
End Get
End Property
Friend Overrides ReadOnly Property TypeArgumentsNoUseSiteDiagnostics As ImmutableArray(Of TypeSymbol)
Get
Return StaticCast(Of TypeSymbol).From(TypeParameters)
End Get
End Property
Public NotOverridable Overrides Function GetTypeArgumentCustomModifiers(ordinal As Integer) As ImmutableArray(Of CustomModifier)
Return GetEmptyTypeArgumentCustomModifiers(ordinal)
End Function
Friend NotOverridable Overrides ReadOnly Property HasTypeArgumentsCustomModifiers As Boolean
Get
Return False
End Get
End Property
Friend Overrides ReadOnly Property CanConstruct As Boolean
Get
' Cannot construct this type if any container of this type is another SpecializedGenericType.
Dim containerToCheck As NamedTypeSymbol = _container
Do
Debug.Assert(Not containerToCheck.IsDefinition)
If containerToCheck.Arity > 0 Then
If containerToCheck.ConstructedFrom Is containerToCheck Then
' Run into a SpecializedGenericType
Debug.Assert(TypeOf containerToCheck Is SpecializedGenericType)
Return False
Else
' Run into a Constructed type
Debug.Assert(TypeOf containerToCheck Is ConstructedType)
Return True
End If
End If
containerToCheck = containerToCheck.ContainingType
Loop While containerToCheck IsNot Nothing AndAlso Not containerToCheck.IsDefinition
Return True
End Get
End Property
Public Overrides Function Construct(typeArguments As ImmutableArray(Of TypeSymbol)) As NamedTypeSymbol
CheckCanConstructAndTypeArguments(typeArguments)
typeArguments = typeArguments.TransformToCanonicalFormFor(Me)
If typeArguments.IsDefault Then
' identity substitution
Return Me
End If
Debug.Assert(_substitution.Parent IsNot Nothing)
Dim substitution = TypeSubstitution.Create(_substitution.Parent, Me.OriginalDefinition, typeArguments,
allowAlphaRenamedTypeParametersAsArguments:=True)
Return New ConstructedSpecializedGenericType(Me, substitution)
End Function
''' <summary>
''' Substitute the given type substitution within this type, returning a new type. If the
''' substitution had no effect, return Me.
''' !!! Only code implementing construction of generic types is allowed to call this method !!!
''' !!! All other code should use Construct methods. !!!
''' </summary>
Friend Overrides Function InternalSubstituteTypeParameters(additionalSubstitution As TypeSubstitution) As TypeWithModifiers
' I do not believe it is ever valid to do this operation on an open generic type.
' However, just in case later we discover that it is valid, I'll leave commented out
' implementation below.
Throw ExceptionUtilities.Unreachable
' TODO: Remove this code once we are confident that it is really unreachable.
'If additionalSubstitution Is Nothing Then
' Return Me
'End If
'Dim newContainer = _container.InternalSubstituteTypeParameters(additionalSubstitution)
'Dim additionalSubstitutionForMe = additionalSubstitution.GetSubstitutionForGenericDefinition(_fullInstanceType)
'Dim constructFrom As SpecializedGenericType = Me
'If newContainer IsNot _container Then
' If newContainer.IsDefinition Then
' Debug.Assert(newContainer Is _fullInstanceType.ContainingSymbol)
' If additionalSubstitutionForMe Is Nothing OrElse additionalSubstitutionForMe.Pairs.Count = 0 Then
' Return _fullInstanceType
' End If
' ' My type parameters are substituted
' Dim substitution As TypeSubstitution = additionalSubstitutionForMe.AdjustParent(Nothing)
' Return New ConstructedInstanceType(_fullInstanceType, substitution)
' End If
' ' The constructed from is changed.
' constructFrom = Create(DirectCast(newContainer, NamedTypeSymbol), _fullInstanceType)
'End If
'If additionalSubstitutionForMe Is Nothing Then
' ' Substitution for my type parameters hasn't changed.
' ' Was identity and stays identity.
' Return constructFrom
'Else
' ' My type parameters are substituted
' Dim substitution As TypeSubstitution = additionalSubstitutionForMe.AdjustParent(newContainer.TypeSubstitution)
' Return New ConstructedSpecializedGenericType(constructFrom, substitution)
'End If
End Function
End Class
''' <summary>
''' Symbol representing non-generic type directly or indirectly contained within constructed
''' generic type.
''' For example: A(Of Integer).B or A(Of Integer).B.C
''' </summary>
Friend Class SpecializedNonGenericType
Inherits SpecializedType
Public Shared Function Create(
container As NamedTypeSymbol,
fullInstanceType As NamedTypeSymbol,
substitution As TypeSubstitution
) As SpecializedType
Debug.Assert(fullInstanceType.IsDefinition)
Debug.Assert(fullInstanceType.Arity = 0)
' Parent's substitution might not match similar part of passed in substitution,
' due to an alpha-rename in parent, etc. We need to use that part, because parent's
' alpha-rename should be taken into consideration within this type.
Dim parentsTypeSubstitution = container.TypeSubstitution
Debug.Assert(parentsTypeSubstitution IsNot Nothing)
Debug.Assert(parentsTypeSubstitution.TargetGenericDefinition Is fullInstanceType.ContainingSymbol)
If substitution.TargetGenericDefinition IsNot fullInstanceType Then
' We can ignore passed in substitution completely.
substitution = VisualBasic.Symbols.TypeSubstitution.Concat(fullInstanceType, parentsTypeSubstitution, Nothing)
Debug.Assert(substitution.TargetGenericDefinition Is fullInstanceType)
Else
Debug.Assert(substitution.Pairs.Length = 0)
If substitution.Parent IsNot parentsTypeSubstitution Then
substitution = VisualBasic.Symbols.TypeSubstitution.Concat(fullInstanceType, parentsTypeSubstitution, Nothing)
End If
End If
Return New SpecializedNonGenericType(DirectCast(container, NamedTypeSymbol), substitution)
End Function
Private Sub New(container As NamedTypeSymbol, substitution As TypeSubstitution)
MyBase.New(container, substitution)
Debug.Assert(substitution.Pairs.Length = 0)
End Sub
Public Overrides ReadOnly Property TypeParameters As ImmutableArray(Of TypeParameterSymbol)
Get
Return ImmutableArray(Of TypeParameterSymbol).Empty
End Get
End Property
Friend Overrides ReadOnly Property TypeArgumentsNoUseSiteDiagnostics As ImmutableArray(Of TypeSymbol)
Get
Return ImmutableArray(Of TypeSymbol).Empty
End Get
End Property
Public NotOverridable Overrides Function GetTypeArgumentCustomModifiers(ordinal As Integer) As ImmutableArray(Of CustomModifier)
Return GetEmptyTypeArgumentCustomModifiers(ordinal)
End Function
Friend NotOverridable Overrides ReadOnly Property HasTypeArgumentsCustomModifiers As Boolean
Get
Return False
End Get
End Property
Friend Overrides ReadOnly Property CanConstruct As Boolean
Get
Return False
End Get
End Property
Public Overrides Function Construct(typeArguments As ImmutableArray(Of TypeSymbol)) As NamedTypeSymbol
Throw New InvalidOperationException()
End Function
''' <summary>
''' Substitute the given type substitution within this type, returning a new type. If the
''' substitution had no effect, return Me.
''' !!! Only code implementing construction of generic types is allowed to call this method !!!
''' !!! All other code should use Construct methods. !!!
''' </summary>
Friend Overrides Function InternalSubstituteTypeParameters(additionalSubstitution As TypeSubstitution) As TypeWithModifiers
Return New TypeWithModifiers(InternalSubstituteTypeParametersInSpecializedNonGenericType(additionalSubstitution))
End Function
Private Overloads Function InternalSubstituteTypeParametersInSpecializedNonGenericType(additionalSubstitution As TypeSubstitution) As NamedTypeSymbol
If additionalSubstitution Is Nothing Then
Return Me
End If
Dim newContainer = DirectCast(_container.InternalSubstituteTypeParameters(additionalSubstitution).AsTypeSymbolOnly(), NamedTypeSymbol)
If newContainer IsNot _container Then
' The container is affected.
Dim definition = Me.OriginalDefinition
If newContainer.IsDefinition Then
' New substitution cancelled out original substitution.
Debug.Assert(newContainer.TypeSubstitution Is Nothing AndAlso definition.ContainingSymbol Is newContainer)
Return definition
End If
Return Create(DirectCast(newContainer, NamedTypeSymbol), definition, newContainer.TypeSubstitution)
End If
' No effect.
Return Me
End Function
End Class
''' <summary>
''' Base class for symbols representing constructed generic types.
''' For example: A(Of Integer), A.B(Of Integer), A(Of Integer).B.C(Of Integer).
''' </summary>
Friend MustInherit Class ConstructedType
Inherits SubstitutedNamedType
Private ReadOnly _typeArguments As ImmutableArray(Of TypeSymbol)
Private ReadOnly _hasTypeArgumentsCustomModifiers As Boolean
Protected Sub New(substitution As TypeSubstitution)
MyBase.New(substitution)
_typeArguments = substitution.GetTypeArgumentsFor(OriginalDefinition, _hasTypeArgumentsCustomModifiers)
End Sub
Public NotOverridable Overrides ReadOnly Property ContainingSymbol As Symbol
Get
Return ConstructedFrom.ContainingSymbol
End Get
End Property
Public Overrides ReadOnly Property IsAnonymousType As Boolean
Get
Return ConstructedFrom.IsAnonymousType
End Get
End Property
Public NotOverridable Overrides ReadOnly Property TypeParameters As ImmutableArray(Of TypeParameterSymbol)
Get
Return ConstructedFrom.TypeParameters
End Get
End Property
Friend NotOverridable Overrides ReadOnly Property TypeArgumentsNoUseSiteDiagnostics As ImmutableArray(Of TypeSymbol)
Get
Return _typeArguments
End Get
End Property
Public NotOverridable Overrides Function GetTypeArgumentCustomModifiers(ordinal As Integer) As ImmutableArray(Of CustomModifier)
If _hasTypeArgumentsCustomModifiers Then
Return _substitution.GetTypeArgumentsCustomModifiersFor(OriginalDefinition.TypeParameters(ordinal))
End If
Return GetEmptyTypeArgumentCustomModifiers(ordinal)
End Function
Friend NotOverridable Overrides ReadOnly Property HasTypeArgumentsCustomModifiers As Boolean
Get
Return _hasTypeArgumentsCustomModifiers
End Get
End Property
Friend Overrides ReadOnly Property CanConstruct As Boolean
Get
Return False
End Get
End Property
Public Overrides Function Construct(typeArguments As ImmutableArray(Of TypeSymbol)) As NamedTypeSymbol
Throw New InvalidOperationException()
End Function
Friend NotOverridable Overrides Function GetUnificationUseSiteDiagnosticRecursive(owner As Symbol, ByRef checkedTypes As HashSet(Of TypeSymbol)) As DiagnosticInfo
Dim result As DiagnosticInfo = If(ConstructedFrom.GetUnificationUseSiteDiagnosticRecursive(owner, checkedTypes),
GetUnificationUseSiteDiagnosticRecursive(_typeArguments, owner, checkedTypes))
If result Is Nothing AndAlso _hasTypeArgumentsCustomModifiers Then
For i As Integer = 0 To Me.Arity - 1
result = GetUnificationUseSiteDiagnosticRecursive(Me.GetTypeArgumentCustomModifiers(i), owner, checkedTypes)
If result IsNot Nothing Then
Exit For
End If
Next
End If
Return result
End Function
End Class
''' <summary>
''' Symbols representing constructed generic type that isn't contained within another constructed generic type.
''' For example: A(Of Integer), A.B(Of Integer), but not A(Of Integer).B.C(Of Integer).
''' </summary>
Friend Class ConstructedInstanceType
Inherits ConstructedType
Public Sub New(substitution As TypeSubstitution)
MyBase.New(substitution)
Debug.Assert(substitution.Parent Is Nothing)
End Sub
Public Overrides ReadOnly Property ConstructedFrom As NamedTypeSymbol
Get
Return Me.OriginalDefinition
End Get
End Property
''' <summary>
''' Substitute the given type substitution within this type, returning a new type. If the
''' substitution had no effect, return Me.
''' !!! Only code implementing construction of generic types is allowed to call this method !!!
''' !!! All other code should use Construct methods. !!!
''' </summary>
Friend Overrides Function InternalSubstituteTypeParameters(additionalSubstitution As TypeSubstitution) As TypeWithModifiers
Return New TypeWithModifiers(InternalSubstituteTypeParametersInConstructedInstanceType(additionalSubstitution))
End Function
Private Overloads Function InternalSubstituteTypeParametersInConstructedInstanceType(additionalSubstitution As TypeSubstitution) As NamedTypeSymbol
If additionalSubstitution Is Nothing Then
Return Me
End If
Dim definition As NamedTypeSymbol = Me.OriginalDefinition
Dim containedType As NamedTypeSymbol = definition.ContainingType
Dim newContainedType As NamedTypeSymbol
If containedType IsNot Nothing Then
newContainedType = DirectCast(containedType.InternalSubstituteTypeParameters(additionalSubstitution).AsTypeSymbolOnly, NamedTypeSymbol)
Else
newContainedType = Nothing
End If
Dim substitution As TypeSubstitution
If newContainedType IsNot containedType Then
' Old container was a definition then new container must be constructed or specialized
Debug.Assert(containedType.IsDefinition AndAlso Not newContainedType.IsDefinition)
Dim constructFrom As SpecializedGenericType = SpecializedGenericType.Create(newContainedType, definition)
Debug.Assert(newContainedType.TypeSubstitution IsNot Nothing)
substitution = VisualBasic.Symbols.TypeSubstitution.AdjustForConstruct(newContainedType.TypeSubstitution, _substitution, additionalSubstitution)
Debug.Assert(substitution IsNot Nothing)
Return New ConstructedSpecializedGenericType(constructFrom, substitution)
End If
Debug.Assert(newContainedType Is Nothing OrElse newContainedType.TypeSubstitution Is Nothing)
substitution = VisualBasic.Symbols.TypeSubstitution.AdjustForConstruct(Nothing, _substitution, additionalSubstitution)
If substitution Is Nothing Then
' Old substitution is cancelled out.
Return Me.OriginalDefinition
End If
If substitution IsNot _substitution Then
Debug.Assert(substitution.TargetGenericDefinition Is _substitution.TargetGenericDefinition)
Return New ConstructedInstanceType(substitution)
End If
' No effect.
Return Me
End Function
End Class
''' <summary>
''' Symbols representing constructed generic type that is contained within another constructed generic type.
''' For example: A(Of Integer).B(Of Integer), A(Of Integer).B.C(Of Integer).
''' </summary>
Friend Class ConstructedSpecializedGenericType
Inherits ConstructedType
''' <summary>
''' Symbol for the ConstructedFrom type.
''' A(Of Integer).B(Of ) for A(Of Integer).B(Of Integer),
''' A(Of Integer).B.C(Of ) for A(Of Integer).B.C(Of Integer)
'''
''' All types in its containership hierarchy must be either constructed or non-generic, or original definitions.
''' </summary>
Private ReadOnly _constructedFrom As SpecializedGenericType
Public Sub New(constructedFrom As SpecializedGenericType, substitution As TypeSubstitution)
MyBase.New(substitution)
Debug.Assert(constructedFrom IsNot Nothing)
Debug.Assert(substitution.TargetGenericDefinition Is constructedFrom.OriginalDefinition)
Debug.Assert(substitution.Parent Is constructedFrom.TypeSubstitution.Parent)
Debug.Assert(constructedFrom.CanConstruct)
_constructedFrom = constructedFrom
End Sub
Public Overrides ReadOnly Property ConstructedFrom As NamedTypeSymbol
Get
Return _constructedFrom
End Get
End Property
''' <summary>
''' Substitute the given type substitution within this type, returning a new type. If the
''' substitution had no effect, return Me.
''' !!! Only code implementing construction of generic types is allowed to call this method !!!
''' !!! All other code should use Construct methods. !!!
''' </summary>
Friend Overrides Function InternalSubstituteTypeParameters(additionalSubstitution As TypeSubstitution) As TypeWithModifiers
Return New TypeWithModifiers(InternalSubstituteTypeParametersInConstructedSpecializedGenericType(additionalSubstitution))
End Function
Private Overloads Function InternalSubstituteTypeParametersInConstructedSpecializedGenericType(additionalSubstitution As TypeSubstitution) As NamedTypeSymbol
If additionalSubstitution Is Nothing Then
Return Me
End If
Dim fullInstanceType As NamedTypeSymbol = _constructedFrom.OriginalDefinition
Dim container As NamedTypeSymbol = _constructedFrom.ContainingType
Debug.Assert(Not container.IsDefinition)
Dim newContainer = DirectCast(container.InternalSubstituteTypeParameters(additionalSubstitution).AsTypeSymbolOnly, NamedTypeSymbol)
Dim newSubstitution As TypeSubstitution = VisualBasic.Symbols.TypeSubstitution.AdjustForConstruct(newContainer.TypeSubstitution, _substitution, additionalSubstitution)
If newSubstitution Is Nothing Then
' Substitutions cancelled each other out.
Debug.Assert(newContainer.IsDefinition AndAlso newContainer.TypeSubstitution Is Nothing)
Return fullInstanceType
End If
If newContainer.IsDefinition Then
' Only container's substitution got cancelled out.
Debug.Assert(newSubstitution.Parent Is Nothing AndAlso fullInstanceType.ContainingSymbol Is newContainer AndAlso
newSubstitution.TargetGenericDefinition Is fullInstanceType)
Return New ConstructedInstanceType(newSubstitution)
End If
Dim constructFrom As SpecializedGenericType = _constructedFrom
If newContainer IsNot container Then
' The constructed from is changed.
constructFrom = SpecializedGenericType.Create(DirectCast(newContainer, NamedTypeSymbol), fullInstanceType)
End If
If constructFrom IsNot _constructedFrom OrElse newSubstitution IsNot _substitution Then
Return New ConstructedSpecializedGenericType(constructFrom, newSubstitution)
End If
' No effect
Return Me
End Function
End Class
''' <summary>
''' Force all declaration errors to be generated.
''' </summary>
Friend Overrides Sub GenerateDeclarationErrors(cancellationToken As CancellationToken)
Throw ExceptionUtilities.Unreachable
End Sub
End Class
End Namespace
|