| File: Symbols\Source\SourceTypeParameterSymbol.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.PooledObjects Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ''' <summary> ''' Represents a type parameter symbol defined in source. ''' </summary> Friend MustInherit Class SourceTypeParameterSymbol Inherits SubstitutableTypeParameterSymbol Private ReadOnly _ordinal As Integer ' 0 is first type parameter, etc. Private ReadOnly _name As String Private _lazyConstraints As ImmutableArray(Of TypeParameterConstraint) Private _lazyConstraintTypes As ImmutableArray(Of TypeSymbol) Protected Sub New(ordinal As Integer, name As String) _ordinal = ordinal _name = name End Sub Public Overrides ReadOnly Property Ordinal As Integer Get Return _ordinal End Get End Property Public Overrides ReadOnly Property Name As String Get Return _name End Get End Property Public Overloads Overrides Function GetAttributes() As ImmutableArray(Of VisualBasicAttributeData) Return ImmutableArray(Of VisualBasicAttributeData).Empty End Function Public Overrides ReadOnly Property HasConstructorConstraint As Boolean Get EnsureAllConstraintsAreResolved() For Each constraint In _lazyConstraints If constraint.IsConstructorConstraint Then Return True End If Next Return False End Get End Property Public Overrides ReadOnly Property HasReferenceTypeConstraint As Boolean Get EnsureAllConstraintsAreResolved() For Each constraint In _lazyConstraints If constraint.IsReferenceTypeConstraint Then Return True End If Next Return False End Get End Property Public Overrides ReadOnly Property HasValueTypeConstraint As Boolean Get EnsureAllConstraintsAreResolved() For Each constraint In _lazyConstraints If constraint.IsValueTypeConstraint Then Return True End If Next Return False End Get End Property Public Overrides ReadOnly Property AllowsRefLikeType As Boolean Get Return False End Get End Property Friend Overrides ReadOnly Property ConstraintTypesNoUseSiteDiagnostics As ImmutableArray(Of TypeSymbol) Get EnsureAllConstraintsAreResolved() Return _lazyConstraintTypes 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) EnsureAllConstraintsAreResolved() Return _lazyConstraints End Function Friend Overrides Sub ResolveConstraints(inProgress As ConsList(Of TypeParameterSymbol)) Debug.Assert(Not inProgress.Contains(Me)) Debug.Assert(Not inProgress.Any() OrElse inProgress.Head.ContainingSymbol Is ContainingSymbol) If _lazyConstraintTypes.IsDefault Then Dim diagnostics = BindingDiagnosticBag.GetInstance() Dim constraints = GetDeclaredConstraints(diagnostics) Dim reportConflicts = DirectConstraintConflictKind.DuplicateTypeConstraint Or If(ReportRedundantConstraints(), DirectConstraintConflictKind.RedundantConstraint, DirectConstraintConflictKind.None) Dim diagnosticsBuilder = ArrayBuilder(Of TypeParameterDiagnosticInfo).GetInstance() constraints = Me.RemoveDirectConstraintConflicts(constraints, inProgress.Prepend(Me), reportConflicts, diagnosticsBuilder) ImmutableInterlocked.InterlockedInitialize(_lazyConstraints, constraints) If ImmutableInterlocked.InterlockedInitialize(_lazyConstraintTypes, GetConstraintTypesOnly(constraints)) Then Dim useSiteDiagnosticsBuilder As ArrayBuilder(Of TypeParameterDiagnosticInfo) = Nothing Me.ReportIndirectConstraintConflicts(diagnosticsBuilder, useSiteDiagnosticsBuilder) If useSiteDiagnosticsBuilder IsNot Nothing Then diagnosticsBuilder.AddRange(useSiteDiagnosticsBuilder) End If For Each diagnostic In diagnosticsBuilder Dim loc = GetLocation(diagnostic) Debug.Assert(loc.IsInSource) diagnostics.Add(diagnostic.UseSiteInfo, loc) Next CheckConstraintTypeConstraints(constraints, diagnostics) Dim sourceModule = DirectCast(ContainingModule, SourceModuleSymbol) sourceModule.AddDeclarationDiagnostics(diagnostics) End If diagnosticsBuilder.Free() diagnostics.Free() End If End Sub Friend Overrides Sub EnsureAllConstraintsAreResolved() If _lazyConstraintTypes.IsDefault Then EnsureAllConstraintsAreResolved(ContainerTypeParameters) End If End Sub Protected MustOverride ReadOnly Property ContainerTypeParameters As ImmutableArray(Of TypeParameterSymbol) Protected MustOverride Overloads Function GetDeclaredConstraints(diagnostics As BindingDiagnosticBag) As ImmutableArray(Of TypeParameterConstraint) ''' <summary> ''' True if the redundant type parameter constraints should be reported as ''' errors. For overridden methods, this is False since type substitution of type ''' arguments for the base/interface may result in redundant constraints. ''' </summary> ''' <remarks> ''' This is a method rather than a property since the ''' implementation may be expensive. ''' </remarks> Protected MustOverride Function ReportRedundantConstraints() As Boolean ' Given a syntax ref, get the symbol location to return. We return ' the location of the Identifier of the type parameter. Protected Shared Function GetSymbolLocation(syntaxRef As SyntaxReference) As Location Dim syntaxNode = syntaxRef.GetSyntax() Dim syntaxTree = syntaxRef.SyntaxTree Return syntaxTree.GetLocation(DirectCast(syntaxNode, TypeParameterSyntax).Identifier.Span) End Function ''' <summary> ''' Check constraints of generic types referenced in constraint types. For instance, ''' with "Interface I(Of T As I(Of T))", check T satisfies constraints on I(Of T). Those ''' constraints are not checked when binding ConstraintTypes since ConstraintTypes ''' has not been set on I(Of T) at that point. ''' </summary> Private Sub CheckConstraintTypeConstraints(constraints As ImmutableArray(Of TypeParameterConstraint), diagnostics As BindingDiagnosticBag) Dim containingAssembly As AssemblySymbol = Me.ContainingAssembly For Each constraint In constraints Dim constraintType = constraint.TypeConstraint If constraintType IsNot Nothing Then Dim location = constraint.LocationOpt Debug.Assert(location IsNot Nothing) Dim useSiteInfo As New CompoundUseSiteInfo(Of AssemblySymbol)(diagnostics, containingAssembly) constraintType.AddUseSiteInfo(useSiteInfo) If Not diagnostics.Add(location, useSiteInfo) Then constraintType.CheckAllConstraints( DeclaringCompilation.LanguageVersion, location, diagnostics, template:=New CompoundUseSiteInfo(Of AssemblySymbol)(diagnostics, containingAssembly)) End If End If Next End Sub ''' <summary> ''' Return the source location of the error, if any. If there error was ''' from a constraint, and that constraint was from source, its location ''' is returned. Otherwise if the type parameter was from source, its ''' location is returned. If neither is from source, Nothing is returned. ''' </summary> Private Shared Function GetLocation(diagnostic As TypeParameterDiagnosticInfo) As Location Dim loc = diagnostic.Constraint.LocationOpt If loc IsNot Nothing Then Return loc End If Dim locations = diagnostic.TypeParameter.Locations If locations.Length > 0 Then Return locations(0) End If Return Nothing End Function Public Overrides ReadOnly Property IsImplicitlyDeclared As Boolean Get Return Me.ContainingSymbol.IsImplicitlyDeclared End Get End Property End Class ''' <summary> ''' Represents a type parameter on a source type (as opposed to a method). ''' </summary> Friend NotInheritable Class SourceTypeParameterOnTypeSymbol Inherits SourceTypeParameterSymbol Private ReadOnly _container As SourceNamedTypeSymbol Private ReadOnly _syntaxRefs As ImmutableArray(Of SyntaxReference) Private _lazyVariance As VarianceKind Public Sub New(container As SourceNamedTypeSymbol, ordinal As Integer, name As String, syntaxRefs As ImmutableArray(Of SyntaxReference)) MyBase.New(ordinal, name) Debug.Assert(Not syntaxRefs.IsEmpty) Debug.Assert(name IsNot Nothing) _container = container _syntaxRefs = syntaxRefs End Sub Public Overrides ReadOnly Property TypeParameterKind As TypeParameterKind Get Return TypeParameterKind.Type End Get End Property Public Overrides ReadOnly Property Variance As VarianceKind Get EnsureAllConstraintsAreResolved() Return _lazyVariance End Get End Property Public Overrides ReadOnly Property Locations As ImmutableArray(Of Location) Get Dim builder = ArrayBuilder(Of Location).GetInstance() For Each syntaxRef In _syntaxRefs builder.Add(GetSymbolLocation(syntaxRef)) Next Return builder.ToImmutableAndFree() End Get End Property Public Overrides ReadOnly Property DeclaringSyntaxReferences As ImmutableArray(Of SyntaxReference) Get Return GetDeclaringSyntaxReferenceHelper(_syntaxRefs) End Get End Property Public Overrides ReadOnly Property ContainingSymbol As Symbol Get Return _container End Get End Property Protected Overrides ReadOnly Property ContainerTypeParameters As ImmutableArray(Of TypeParameterSymbol) Get Return _container.TypeParameters End Get End Property Protected Overrides Function GetDeclaredConstraints(diagnostics As BindingDiagnosticBag) As ImmutableArray(Of TypeParameterConstraint) Dim variance As VarianceKind Dim constraints As ImmutableArray(Of TypeParameterConstraint) = Nothing _container.BindTypeParameterConstraints(Me, variance, constraints, diagnostics) _lazyVariance = variance Return constraints End Function Protected Overrides Function ReportRedundantConstraints() As Boolean Return True End Function End Class ''' <summary> ''' Represents a type parameter on a source method (as opposed to a type). ''' </summary> Friend NotInheritable Class SourceTypeParameterOnMethodSymbol Inherits SourceTypeParameterSymbol Private ReadOnly _container As SourceMemberMethodSymbol Private ReadOnly _syntaxRef As SyntaxReference Public Sub New(container As SourceMemberMethodSymbol, ordinal As Integer, name As String, syntaxRef As SyntaxReference) MyBase.New(ordinal, name) _container = container _syntaxRef = syntaxRef End Sub Public Overrides ReadOnly Property ContainingSymbol As Symbol Get Return _container End Get End Property Public Overrides ReadOnly Property TypeParameterKind As TypeParameterKind Get Return TypeParameterKind.Method End Get End Property Public Overrides ReadOnly Property Variance As VarianceKind Get Return VarianceKind.None End Get End Property Public Overrides ReadOnly Property Locations As ImmutableArray(Of Location) Get Return ImmutableArray.Create(GetSymbolLocation(_syntaxRef)) End Get End Property Public Overrides ReadOnly Property DeclaringSyntaxReferences As ImmutableArray(Of SyntaxReference) Get Return GetDeclaringSyntaxReferenceHelper(_syntaxRef) End Get End Property Protected Overrides ReadOnly Property ContainerTypeParameters As ImmutableArray(Of TypeParameterSymbol) Get Return _container.TypeParameters End Get End Property Protected Overrides Function GetDeclaredConstraints(diagnostics As BindingDiagnosticBag) As ImmutableArray(Of TypeParameterConstraint) Dim syntax = DirectCast(_syntaxRef.GetSyntax(), TypeParameterSyntax) Return _container.BindTypeParameterConstraints(syntax, diagnostics) End Function Protected Overrides Function ReportRedundantConstraints() As Boolean ' If the container is an overridden method, allow redundant constraints. If _container.IsOverrides Then Return False End If ' If the container is a private, explicit interface ' implementation, allow redundant constraints. If (_container.DeclaredAccessibility = Accessibility.Private) AndAlso _container.HasExplicitInterfaceImplementations Then Return False End If Return True End Function End Class End Namespace