| File: Symbols\SubstitutedErrorType.vb | Web Access |
| Project: src\roslyn\src\Compilers\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.vbproj (Microsoft.CodeAnalysis.VisualBasic) |
' 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 Friend NotInheritable Class SubstitutedErrorType Inherits ErrorTypeSymbol ' The _fullInstanceType is the instance that is also contained in its ' instance type, etc. all the way out. Private ReadOnly _fullInstanceType As InstanceErrorTypeSymbol Private ReadOnly _substitution As TypeSubstitution Private ReadOnly _container As Symbol ' True if the _substitution doesn't involved of my direct ' type parameters, only type parameters of containing types. Private ReadOnly Property IdentitySubstitutionOnMyTypeParameters As Boolean Get Return _substitution.Pairs.Length = 0 End Get End Property Public Overrides ReadOnly Property Name As String Get Return _fullInstanceType.Name End Get End Property Friend Overrides ReadOnly Property MangleName As Boolean Get Return _fullInstanceType.MangleName End Get End Property Public Overrides ReadOnly Property MetadataName As String Get Return _fullInstanceType.MetadataName End Get End Property Public Overrides ReadOnly Property IsImplicitlyDeclared As Boolean Get Return _fullInstanceType.IsImplicitlyDeclared End Get End Property Public Overrides ReadOnly Property OriginalDefinition As NamedTypeSymbol Get Return _fullInstanceType End Get End Property Friend Overrides ReadOnly Property ErrorInfo As DiagnosticInfo Get Return _fullInstanceType.ErrorInfo End Get End Property Private ReadOnly Property ConstructedFromItself As Boolean Get Return _fullInstanceType.Arity = 0 OrElse IdentitySubstitutionOnMyTypeParameters End Get End Property Public Overrides ReadOnly Property ConstructedFrom As NamedTypeSymbol Get If ConstructedFromItself Then Return Me End If If Me.ContainingSymbol Is Nothing OrElse Me.ContainingSymbol.IsDefinition Then Return _fullInstanceType End If Dim substitution As TypeSubstitution = _substitution.Parent Debug.Assert(substitution IsNot Nothing AndAlso substitution.TargetGenericDefinition Is Me.ContainingType.OriginalDefinition) ' 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. substitution = VisualBasic.Symbols.TypeSubstitution.Concat(_fullInstanceType, substitution, Nothing) Return New SubstitutedErrorType(Me.ContainingSymbol, _fullInstanceType, substitution) End Get End Property Friend Overrides ReadOnly Property TypeSubstitution As TypeSubstitution Get Return _substitution End Get End Property Public Overrides ReadOnly Property ContainingAssembly As AssemblySymbol Get Return _fullInstanceType.ContainingAssembly End Get End Property Public Overrides ReadOnly Property Arity As Integer Get Return _fullInstanceType.Arity End Get End Property Public Overrides ReadOnly Property TypeParameters As ImmutableArray(Of TypeParameterSymbol) Get Return _fullInstanceType.TypeParameters End Get End Property Friend Overrides ReadOnly Property TypeArgumentsNoUseSiteDiagnostics As ImmutableArray(Of TypeSymbol) Get ' TODO: Is creating a new list here every time the right approach? Should this be cached? If IdentitySubstitutionOnMyTypeParameters Then Return StaticCast(Of TypeSymbol).From(TypeParameters) Else Return _substitution.GetTypeArgumentsFor(_fullInstanceType, Nothing) End If End Get End Property Public Overrides Function GetTypeArgumentCustomModifiers(ordinal As Integer) As ImmutableArray(Of CustomModifier) If IdentitySubstitutionOnMyTypeParameters Then Return GetEmptyTypeArgumentCustomModifiers(ordinal) End If Return _substitution.GetTypeArgumentsCustomModifiersFor(_fullInstanceType.TypeParameters(ordinal)) End Function Friend Overrides ReadOnly Property HasTypeArgumentsCustomModifiers As Boolean Get If IdentitySubstitutionOnMyTypeParameters Then Return False End If Return _substitution.HasTypeArgumentsCustomModifiersFor(_fullInstanceType) 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(InternalSubstituteTypeParametersInSubstitutedErrorType(additionalSubstitution)) End Function Private Overloads Function InternalSubstituteTypeParametersInSubstitutedErrorType(additionalSubstitution As TypeSubstitution) As NamedTypeSymbol If additionalSubstitution Is Nothing Then Return Me End If Dim container As Symbol = ContainingSymbol Dim containingType = TryCast(container, NamedTypeSymbol) If containingType Is Nothing Then Debug.Assert(_substitution.Parent Is Nothing) Dim substitution As TypeSubstitution = VisualBasic.Symbols.TypeSubstitution.AdjustForConstruct(Nothing, _substitution, additionalSubstitution) If substitution Is Nothing Then Return _fullInstanceType End If If substitution Is _substitution Then Return Me End If Return New SubstitutedErrorType(container, _fullInstanceType, substitution) Else Dim newContainer = DirectCast(containingType.InternalSubstituteTypeParameters(additionalSubstitution).AsTypeSymbolOnly(), NamedTypeSymbol) Dim newSubstitution = VisualBasic.Symbols.TypeSubstitution.AdjustForConstruct(newContainer.TypeSubstitution, _substitution, additionalSubstitution) If newSubstitution Is Nothing Then Debug.Assert(newContainer.TypeSubstitution Is Nothing AndAlso newContainer.IsDefinition) Return _fullInstanceType End If If newContainer Is containingType AndAlso newSubstitution Is _substitution Then Return Me End If Return New SubstitutedErrorType(newContainer, _fullInstanceType, newSubstitution) End If End Function ' We can only construct if we have an identify substitution on all of our type parameters. Friend Overrides ReadOnly Property CanConstruct As Boolean Get Return Arity > 0 AndAlso IdentitySubstitutionOnMyTypeParameters End Get End Property Public Overrides Function Construct(typeArguments As ImmutableArray(Of TypeSymbol)) As NamedTypeSymbol CheckCanConstructAndTypeArguments(typeArguments) Dim substitution = TypeSubstitution.Create(_fullInstanceType, _fullInstanceType.TypeParameters, typeArguments, allowAlphaRenamedTypeParametersAsArguments:=True) If substitution Is Nothing Then Return Me Else Return New SubstitutedErrorType(_container, _fullInstanceType, TypeSubstitution.Concat(_fullInstanceType, _substitution.Parent, substitution)) End If End Function Public Sub New(container As Symbol, fullInstanceType As InstanceErrorTypeSymbol, substitution As TypeSubstitution) MyBase.New() Debug.Assert(fullInstanceType IsNot Nothing) Debug.Assert(substitution IsNot Nothing) Debug.Assert(substitution.TargetGenericDefinition Is fullInstanceType) _container = container _fullInstanceType = fullInstanceType _substitution = substitution End Sub Public Overrides ReadOnly Property ContainingSymbol As Symbol Get Return _container End Get End Property Public Overrides Function GetHashCode() As Integer Dim hash As Integer = _fullInstanceType.GetHashCode() If Me._substitution.WasConstructedForModifiers() Then Return hash End If hash = Roslyn.Utilities.Hash.Combine(ContainingType, hash) If Not ConstructedFromItself Then For Each typeArgument In TypeArgumentsNoUseSiteDiagnostics hash = Roslyn.Utilities.Hash.Combine(typeArgument, hash) Next End If Return hash End Function Public Overrides Function Equals(obj As TypeSymbol, comparison As TypeCompareKind) As Boolean If Me Is obj Then Return True End If If obj Is Nothing Then Return False End If If (comparison And TypeCompareKind.AllIgnoreOptionsForVB) = 0 AndAlso Not Me.GetType().Equals(obj.GetType()) Then Return False End If Dim otherTuple = TryCast(obj, TupleTypeSymbol) If otherTuple IsNot Nothing Then Return otherTuple.Equals(Me, comparison) End If If Not _fullInstanceType.Equals(obj.OriginalDefinition) Then Return False End If Dim containingType = Me.ContainingType If containingType IsNot Nothing AndAlso Not containingType.Equals(obj.ContainingType, comparison) Then Return False End If Dim other = DirectCast(obj, ErrorTypeSymbol) If Me.ConstructedFromItself AndAlso other Is other.ConstructedFrom Then ' No need to compare type arguments on those containers when they didn't add type arguments. Return True End If Dim arguments = TypeArgumentsNoUseSiteDiagnostics Dim otherArguments = other.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, other) Then Return False End If Return True End Function End Class End Namespace