|
' 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 Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
''' <summary>
''' The base class for potentially constructible (i.e. with known arity) error type symbols
''' </summary>
Friend MustInherit Class InstanceErrorTypeSymbol
Inherits ErrorTypeSymbol
Protected ReadOnly _arity As Integer
Private _lazyTypeParameters As ImmutableArray(Of TypeParameterSymbol)
Friend Sub New(arity As Integer)
Debug.Assert(arity >= 0)
_arity = arity
If arity = 0 Then
_lazyTypeParameters = ImmutableArray(Of TypeParameterSymbol).Empty
End If
End Sub
Public NotOverridable Overrides ReadOnly Property Arity As Integer
Get
Return _arity
End Get
End Property
' Instance types are always constructible if they have arity >= 1
Friend Overrides ReadOnly Property CanConstruct As Boolean
Get
Return _arity > 0
End Get
End Property
Public NotOverridable Overrides Function Construct(typeArguments As ImmutableArray(Of TypeSymbol)) As NamedTypeSymbol
CheckCanConstructAndTypeArguments(typeArguments)
Dim substitution = TypeSubstitution.Create(Me, Me.TypeParameters, typeArguments, allowAlphaRenamedTypeParametersAsArguments:=True)
If substitution Is Nothing Then
Return Me
Else
Return New SubstitutedErrorType(Me.ContainingSymbol, Me, substitution)
End If
End Function
Friend Overrides ReadOnly Property TypeSubstitution As TypeSubstitution
Get
Return Nothing
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 NotOverridable Overrides Function InternalSubstituteTypeParameters(substitution As TypeSubstitution) As TypeWithModifiers
Return New TypeWithModifiers(InternalSubstituteTypeParametersInInstanceErrorTypeSymbol(substitution))
End Function
Private Overloads Function InternalSubstituteTypeParametersInInstanceErrorTypeSymbol(substitution As TypeSubstitution) As NamedTypeSymbol
If substitution IsNot Nothing Then
' The substitution might target one of this type's children.
substitution = substitution.GetSubstitutionForGenericDefinitionOrContainers(Me)
End If
If substitution Is Nothing Then
Return Me
End If
Dim container As Symbol = ContainingSymbol
Dim containingType As NamedTypeSymbol = TryCast(container, NamedTypeSymbol)
If containingType Is Nothing Then
Debug.Assert(substitution.TargetGenericDefinition Is Me AndAlso substitution.Parent Is Nothing AndAlso substitution.Pairs.Length > 0)
Return New SubstitutedErrorType(container, Me, substitution)
Else
Dim newContainer = DirectCast(containingType.InternalSubstituteTypeParameters(substitution).AsTypeSymbolOnly(), NamedTypeSymbol)
If substitution.TargetGenericDefinition Is Me Then
Debug.Assert(substitution IsNot Nothing)
Debug.Assert(newContainer.TypeSubstitution Is substitution.Parent) ' How can it be otherwise? The contained type didn't have any substitution before.
Else
' We don't alpha-rename type parameters of error type symbols because they don't have constraints
' and, therefore, have nothing to substitute. Just use identity substitution.
Debug.Assert(newContainer.TypeSubstitution IsNot Nothing)
substitution = VisualBasic.Symbols.TypeSubstitution.Concat(Me, newContainer.TypeSubstitution, Nothing)
End If
Return New SubstitutedErrorType(newContainer, Me, substitution)
End If
End Function
Public Overrides ReadOnly Property TypeParameters As ImmutableArray(Of TypeParameterSymbol)
Get
If _lazyTypeParameters.IsDefault Then
Dim params = New TypeParameterSymbol(_arity - 1) {}
For i As Integer = 0 To _arity - 1 Step 1
params(i) = New ErrorTypeParameterSymbol(Me, i)
Next
ImmutableInterlocked.InterlockedCompareExchange(_lazyTypeParameters,
params.AsImmutableOrNull(),
Nothing)
End If
Return _lazyTypeParameters
End Get
End Property
Friend Overrides ReadOnly Property TypeArgumentsNoUseSiteDiagnostics As ImmutableArray(Of TypeSymbol)
Get
Return StaticCast(Of TypeSymbol).From(Me.TypeParameters)
End Get
End Property
Public NotOverridable Overrides Function GetTypeArgumentCustomModifiers(ordinal As Integer) As ImmutableArray(Of CustomModifier)
' This is always the instance type, so the type arguments do not have any modifiers.
Return GetEmptyTypeArgumentCustomModifiers(ordinal)
End Function
Friend NotOverridable Overrides ReadOnly Property HasTypeArgumentsCustomModifiers As Boolean
Get
' This is always the instance type, so the type arguments do not have any modifiers.
Return False
End Get
End Property
Public MustOverride Overrides Function GetHashCode() As Integer
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
Dim otherInstance = TryCast(other, InstanceErrorTypeSymbol)
If otherInstance Is Nothing AndAlso (comparison And TypeCompareKind.AllIgnoreOptionsForVB) = 0 Then
Return False
End If
Dim otherTuple = TryCast(other, TupleTypeSymbol)
If otherTuple IsNot Nothing Then
Return otherTuple.Equals(Me, comparison)
End If
If otherInstance IsNot Nothing Then
Return SpecializedEquals(otherInstance)
End If
Debug.Assert((comparison And TypeCompareKind.AllIgnoreOptionsForVB) <> 0)
If Not Me.Equals(other.OriginalDefinition) Then
Return False
End If
' Delegate comparison to the other type to ensure symmetry
Debug.Assert(TypeOf other Is SubstitutedErrorType)
Return other.Equals(Me, comparison)
End Function
Protected MustOverride Function SpecializedEquals(other As InstanceErrorTypeSymbol) As Boolean
Private NotInheritable Class ErrorTypeParameterSymbol
Inherits TypeParameterSymbol
Private ReadOnly _container As InstanceErrorTypeSymbol
Private ReadOnly _ordinal As Integer
Public Sub New(container As InstanceErrorTypeSymbol, ordinal As Integer)
_container = container
_ordinal = ordinal
End Sub
Public Overrides ReadOnly Property TypeParameterKind As TypeParameterKind
Get
Return TypeParameterKind.Type
End Get
End Property
Public Overrides ReadOnly Property Name As String
Get
Return String.Empty
End Get
End Property
Friend Overrides ReadOnly Property ConstraintTypesNoUseSiteDiagnostics As ImmutableArray(Of TypeSymbol)
Get
Return ImmutableArray(Of TypeSymbol).Empty
End Get
End Property
Friend Overrides ReadOnly Property HasUnmanagedTypeConstraint As Boolean
Get
Return False
End Get
End Property
Friend Overrides Function GetConstraints() As ImmutableArray(Of TypeParameterConstraint)
Return ImmutableArray(Of TypeParameterConstraint).Empty
End Function
Public Overrides ReadOnly Property ContainingSymbol As Symbol
Get
Return _container
End Get
End Property
Public Overrides ReadOnly Property HasConstructorConstraint As Boolean
Get
Return False
End Get
End Property
Public Overrides ReadOnly Property HasReferenceTypeConstraint As Boolean
Get
Return False
End Get
End Property
Public Overrides ReadOnly Property HasValueTypeConstraint As Boolean
Get
Return False
End Get
End Property
Public Overrides ReadOnly Property AllowsRefLikeType As Boolean
Get
Return False
End Get
End Property
Public Overrides ReadOnly Property Locations As ImmutableArray(Of Location)
Get
Return ImmutableArray(Of Location).Empty
End Get
End Property
Public Overrides ReadOnly Property DeclaringSyntaxReferences As ImmutableArray(Of SyntaxReference)
Get
Return ImmutableArray(Of SyntaxReference).Empty
End Get
End Property
Public Overrides ReadOnly Property Ordinal As Integer
Get
Return _ordinal
End Get
End Property
Public Overrides ReadOnly Property Variance As VarianceKind
Get
Return VarianceKind.None
End Get
End Property
Public Overrides Function GetHashCode() As Integer
Return Hash.Combine(_container.GetHashCode(), _ordinal)
End Function
Public Overrides Function Equals(obj As TypeSymbol, comparison As TypeCompareKind) As Boolean
If obj Is Nothing Then
Return False
End If
If obj Is Me Then
Return True
End If
Dim other = TryCast(obj, ErrorTypeParameterSymbol)
Return other IsNot Nothing AndAlso other._ordinal = Me._ordinal AndAlso other._container.Equals(Me._container, comparison)
End Function
Friend Overrides Sub EnsureAllConstraintsAreResolved()
End Sub
End Class
End Class
End Namespace
|