File: Binding\Binder_Constraints.vb
Web Access
Project: src\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
 
    Partial Friend Class Binder
        Friend Function BindTypeParameterConstraintClause(
            containingSymbol As Symbol,
            clause As TypeParameterConstraintClauseSyntax,
            diagnostics As BindingDiagnosticBag
        ) As ImmutableArray(Of TypeParameterConstraint)
            Debug.Assert((containingSymbol.Kind = SymbolKind.NamedType) OrElse (containingSymbol.Kind = SymbolKind.Method))
 
            If clause Is Nothing Then
                Return ImmutableArray(Of TypeParameterConstraint).Empty
            End If
 
            Dim constraints = TypeParameterConstraintKind.None
            Dim constraintsBuilder = ArrayBuilder(Of TypeParameterConstraint).GetInstance()
            Select Case clause.Kind
                Case SyntaxKind.TypeParameterSingleConstraintClause
                    BindTypeParameterConstraint(containingSymbol, DirectCast(clause, TypeParameterSingleConstraintClauseSyntax).Constraint, constraints, constraintsBuilder, diagnostics)
 
                Case SyntaxKind.TypeParameterMultipleConstraintClause
                    For Each syntax As ConstraintSyntax In DirectCast(clause, TypeParameterMultipleConstraintClauseSyntax).Constraints
                        BindTypeParameterConstraint(containingSymbol, syntax, constraints, constraintsBuilder, diagnostics)
                    Next
 
                Case Else
                    Throw ExceptionUtilities.UnexpectedValue(clause.Kind)
            End Select
            Return constraintsBuilder.ToImmutableAndFree()
        End Function
 
        Private Sub BindTypeParameterConstraint(
            containingSymbol As Symbol,
            syntax As ConstraintSyntax,
            ByRef constraints As TypeParameterConstraintKind,
            constraintsBuilder As ArrayBuilder(Of TypeParameterConstraint),
            diagnostics As BindingDiagnosticBag
        )
            Debug.Assert((containingSymbol.Kind = SymbolKind.NamedType) OrElse (containingSymbol.Kind = SymbolKind.Method))
 
            Select Case syntax.Kind
                Case SyntaxKind.NewConstraint
                    If (constraints And TypeParameterConstraintKind.Constructor) <> 0 Then
                        ReportDiagnostic(diagnostics, syntax, ERRID.ERR_MultipleNewConstraints)
                    ElseIf (constraints And TypeParameterConstraintKind.ValueType) <> 0 Then
                        ReportDiagnostic(diagnostics, syntax, ERRID.ERR_NewAndValueConstraintsCombined)
                    Else
                        constraints = constraints Or TypeParameterConstraintKind.Constructor
                        constraintsBuilder.Add(New TypeParameterConstraint(TypeParameterConstraintKind.Constructor, syntax.GetLocation()))
                    End If
 
                Case SyntaxKind.ClassConstraint
                    If (constraints And TypeParameterConstraintKind.ReferenceType) <> 0 Then
                        ReportDiagnostic(diagnostics, syntax, ERRID.ERR_MultipleReferenceConstraints)
                    ElseIf (constraints And TypeParameterConstraintKind.ValueType) <> 0 Then
                        ReportDiagnostic(diagnostics, syntax, ERRID.ERR_RefAndValueConstraintsCombined)
                    Else
                        constraints = constraints Or TypeParameterConstraintKind.ReferenceType
                        constraintsBuilder.Add(New TypeParameterConstraint(TypeParameterConstraintKind.ReferenceType, syntax.GetLocation()))
                    End If
 
                Case SyntaxKind.StructureConstraint
                    If (constraints And TypeParameterConstraintKind.ValueType) <> 0 Then
                        ReportDiagnostic(diagnostics, syntax, ERRID.ERR_MultipleValueConstraints)
                    ElseIf (constraints And TypeParameterConstraintKind.Constructor) <> 0 Then
                        ReportDiagnostic(diagnostics, syntax, ERRID.ERR_NewAndValueConstraintsCombined)
                    ElseIf (constraints And TypeParameterConstraintKind.ReferenceType) <> 0 Then
                        ReportDiagnostic(diagnostics, syntax, ERRID.ERR_RefAndValueConstraintsCombined)
                    Else
                        constraints = constraints Or TypeParameterConstraintKind.ValueType
                        constraintsBuilder.Add(New TypeParameterConstraint(TypeParameterConstraintKind.ValueType, syntax.GetLocation()))
                    End If
 
                Case SyntaxKind.TypeConstraint
                    Dim typeOrAlias = BindTypeOrAliasSyntax(DirectCast(syntax, TypeConstraintSyntax).Type, diagnostics)
                    Debug.Assert(typeOrAlias IsNot Nothing)
                    Dim constraintType = TryCast(typeOrAlias.UnwrapAlias(), TypeSymbol)
                    If constraintType Is Nothing Then
                        ReportDiagnostic(diagnostics, syntax, ERRID.ERR_UnrecognizedType)
                    Else
                        constraintsBuilder.Add(New TypeParameterConstraint(constraintType, syntax.GetLocation()))
 
                        AccessCheck.VerifyAccessExposureForMemberType(containingSymbol, syntax, constraintType, diagnostics)
                    End If
 
                Case Else
                    Throw ExceptionUtilities.UnexpectedValue(syntax.Kind)
 
            End Select
        End Sub
    End Class
 
End Namespace