File: Emit\NoPia\EmbeddedType.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.Emit
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports ReferenceEqualityComparer = Roslyn.Utilities.ReferenceEqualityComparer
 
#If Not DEBUG Then
Imports NamedTypeSymbolAdapter = Microsoft.CodeAnalysis.VisualBasic.Symbols.NamedTypeSymbol
Imports FieldSymbolAdapter = Microsoft.CodeAnalysis.VisualBasic.Symbols.FieldSymbol
Imports MethodSymbolAdapter = Microsoft.CodeAnalysis.VisualBasic.Symbols.MethodSymbol
Imports EventSymbolAdapter = Microsoft.CodeAnalysis.VisualBasic.Symbols.EventSymbol
Imports PropertySymbolAdapter = Microsoft.CodeAnalysis.VisualBasic.Symbols.PropertySymbol
#End If
 
Namespace Microsoft.CodeAnalysis.VisualBasic.Emit.NoPia
 
    Friend NotInheritable Class EmbeddedType
        Inherits EmbeddedTypesManager.CommonEmbeddedType
 
        Private _embeddedAllMembersOfImplementedInterface As Boolean
 
        Public Sub New(typeManager As EmbeddedTypesManager, underlyingNamedType As NamedTypeSymbolAdapter)
            MyBase.New(typeManager, underlyingNamedType)
 
            Debug.Assert(underlyingNamedType.AdaptedNamedTypeSymbol.IsDefinition)
            Debug.Assert(underlyingNamedType.AdaptedNamedTypeSymbol.IsTopLevelType())
            Debug.Assert(Not underlyingNamedType.AdaptedNamedTypeSymbol.IsGenericType)
        End Sub
 
        Public Sub EmbedAllMembersOfImplementedInterface(syntaxNodeOpt As SyntaxNode, diagnostics As DiagnosticBag)
            Debug.Assert(UnderlyingNamedType.AdaptedNamedTypeSymbol.IsInterfaceType())
 
            If _embeddedAllMembersOfImplementedInterface Then
                Return
            End If
 
            _embeddedAllMembersOfImplementedInterface = True
 
            ' Embed all members
            For Each m In UnderlyingNamedType.AdaptedNamedTypeSymbol.GetMethodsToEmit()
                If m IsNot Nothing Then
                    TypeManager.EmbedMethod(Me, m.GetCciAdapter(), syntaxNodeOpt, diagnostics)
                End If
            Next
 
            ' We also should embed properties and events, but we don't need to do this explicitly here
            ' because accessors embed them automatically.
 
            ' Do the same for implemented interfaces.
            For Each [interface] In UnderlyingNamedType.AdaptedNamedTypeSymbol.GetInterfacesToEmit()
                TypeManager.ModuleBeingBuilt.Translate([interface], syntaxNodeOpt, diagnostics, fromImplements:=True)
            Next
        End Sub
 
        Protected Overrides Function GetAssemblyRefIndex() As Integer
            Dim refs = TypeManager.ModuleBeingBuilt.SourceModule.GetReferencedAssemblySymbols()
            Return refs.IndexOf(UnderlyingNamedType.AdaptedNamedTypeSymbol.ContainingAssembly, ReferenceEqualityComparer.Instance)
        End Function
 
        Protected Overrides ReadOnly Property IsPublic As Boolean
            Get
                Return UnderlyingNamedType.AdaptedNamedTypeSymbol.DeclaredAccessibility = Accessibility.Public
            End Get
        End Property
 
        Protected Overrides Function GetBaseClass(moduleBuilder As PEModuleBuilder, syntaxNodeOpt As SyntaxNode, diagnostics As DiagnosticBag) As Cci.ITypeReference
            Dim baseType = UnderlyingNamedType.AdaptedNamedTypeSymbol.BaseTypeNoUseSiteDiagnostics
            Return If(baseType IsNot Nothing, moduleBuilder.Translate(baseType, syntaxNodeOpt, diagnostics), Nothing)
        End Function
 
        Protected Overrides Function GetFieldsToEmit() As IEnumerable(Of FieldSymbolAdapter)
#If DEBUG Then
            Return UnderlyingNamedType.AdaptedNamedTypeSymbol.GetFieldsToEmit().Select(Function(s) s.GetCciAdapter())
#Else
            Return UnderlyingNamedType.AdaptedNamedTypeSymbol.GetFieldsToEmit()
#End If
        End Function
 
        Protected Overrides Function GetMethodsToEmit() As IEnumerable(Of MethodSymbolAdapter)
#If DEBUG Then
            Return UnderlyingNamedType.AdaptedNamedTypeSymbol.GetMethodsToEmit().Select(Function(s) s?.GetCciAdapter())
#Else
            Return UnderlyingNamedType.AdaptedNamedTypeSymbol.GetMethodsToEmit()
#End If
        End Function
 
        Protected Overrides Function GetEventsToEmit() As IEnumerable(Of EventSymbolAdapter)
#If DEBUG Then
            Return UnderlyingNamedType.AdaptedNamedTypeSymbol.GetEventsToEmit().Select(Function(s) s.GetCciAdapter())
#Else
            Return UnderlyingNamedType.AdaptedNamedTypeSymbol.GetEventsToEmit()
#End If
        End Function
 
        Protected Overrides Function GetPropertiesToEmit() As IEnumerable(Of PropertySymbolAdapter)
#If DEBUG Then
            Return UnderlyingNamedType.AdaptedNamedTypeSymbol.GetPropertiesToEmit().Select(Function(s) s.GetCciAdapter())
#Else
            Return UnderlyingNamedType.AdaptedNamedTypeSymbol.GetPropertiesToEmit()
#End If
        End Function
 
        Protected Overrides Iterator Function GetInterfaces(context As EmitContext) As IEnumerable(Of Cci.TypeReferenceWithAttributes)
            Debug.Assert(TypeManager.ModuleBeingBuilt Is context.Module)
 
            Dim moduleBeingBuilt = DirectCast(context.Module, PEModuleBuilder)
 
            For Each [interface] In UnderlyingNamedType.AdaptedNamedTypeSymbol.GetInterfacesToEmit()
                Dim typeRef = moduleBeingBuilt.Translate([interface],
                                                            DirectCast(context.SyntaxNode, VisualBasicSyntaxNode),
                                                            context.Diagnostics)
 
                Yield [interface].GetTypeRefWithAttributes(UnderlyingNamedType.AdaptedNamedTypeSymbol.DeclaringCompilation, typeRef)
            Next
        End Function
 
        Protected Overrides ReadOnly Property IsAbstract As Boolean
            Get
                Return UnderlyingNamedType.AdaptedNamedTypeSymbol.IsMetadataAbstract
            End Get
        End Property
 
        Protected Overrides ReadOnly Property IsBeforeFieldInit As Boolean
            Get
                Select Case UnderlyingNamedType.AdaptedNamedTypeSymbol.TypeKind
                    Case TypeKind.Enum, TypeKind.Delegate, TypeKind.Interface
                        Return False
                End Select
 
                ' We shouldn't embed static constructor.
                Return True
            End Get
        End Property
 
        Protected Overrides ReadOnly Property IsComImport As Boolean
            Get
                Return UnderlyingNamedType.AdaptedNamedTypeSymbol.IsComImport
            End Get
        End Property
 
        Protected Overrides ReadOnly Property IsInterface As Boolean
            Get
                Return UnderlyingNamedType.AdaptedNamedTypeSymbol.IsInterfaceType()
            End Get
        End Property
 
        Protected Overrides ReadOnly Property IsDelegate As Boolean
            Get
                Return UnderlyingNamedType.AdaptedNamedTypeSymbol.IsDelegateType()
            End Get
        End Property
 
        Protected Overrides ReadOnly Property IsSerializable As Boolean
            Get
                Return UnderlyingNamedType.AdaptedNamedTypeSymbol.IsSerializable
            End Get
        End Property
 
        Protected Overrides ReadOnly Property IsSpecialName As Boolean
            Get
                Return UnderlyingNamedType.AdaptedNamedTypeSymbol.HasSpecialName
            End Get
        End Property
 
        Protected Overrides ReadOnly Property IsWindowsRuntimeImport As Boolean
            Get
                Return UnderlyingNamedType.AdaptedNamedTypeSymbol.IsWindowsRuntimeImport
            End Get
        End Property
 
        Protected Overrides ReadOnly Property IsSealed As Boolean
            Get
                Return UnderlyingNamedType.AdaptedNamedTypeSymbol.IsMetadataSealed
            End Get
        End Property
 
        Protected Overrides Function GetTypeLayoutIfStruct() As TypeLayout?
            Return If(UnderlyingNamedType.AdaptedNamedTypeSymbol.IsStructureType(), UnderlyingNamedType.AdaptedNamedTypeSymbol.Layout, Nothing)
        End Function
 
        Protected Overrides ReadOnly Property StringFormat As System.Runtime.InteropServices.CharSet
            Get
                Return UnderlyingNamedType.AdaptedNamedTypeSymbol.MarshallingCharSet
            End Get
        End Property
 
        Protected Overrides Function GetCustomAttributesToEmit(moduleBuilder As PEModuleBuilder) As IEnumerable(Of VisualBasicAttributeData)
            Return UnderlyingNamedType.AdaptedNamedTypeSymbol.GetCustomAttributesToEmit(moduleBuilder)
        End Function
 
        Protected Overrides Function CreateTypeIdentifierAttribute(hasGuid As Boolean, syntaxNodeOpt As SyntaxNode, diagnostics As DiagnosticBag) As VisualBasicAttributeData
            Dim member = If(hasGuid,
                WellKnownMember.System_Runtime_InteropServices_TypeIdentifierAttribute__ctor,
                WellKnownMember.System_Runtime_InteropServices_TypeIdentifierAttribute__ctorStringString)
            Dim ctor = TypeManager.GetWellKnownMethod(member, syntaxNodeOpt, diagnostics)
            If ctor Is Nothing Then
                Return Nothing
            End If
 
            If hasGuid Then
                ' This is an interface with a GuidAttribute, so we will generate the no-parameter TypeIdentifier.
                Return New SynthesizedAttributeData(TypeManager.ModuleBeingBuilt.Compilation, ctor, ImmutableArray(Of TypedConstant).Empty, ImmutableArray(Of KeyValuePair(Of String, TypedConstant)).Empty)
 
            Else
                ' This is an interface with no GuidAttribute, or some other type, so we will generate the
                ' TypeIdentifier with name and scope parameters.
 
                ' Look for a GUID attribute attached to type's containing assembly. If we find one, we'll use it;
                ' otherwise, we expect that we will have reported an error (ERRID_PIAHasNoAssemblyGuid1) about this assembly, since
                ' you can't /link against an assembly which lacks a GuidAttribute.
 
                Dim stringType = TypeManager.GetSystemStringType(syntaxNodeOpt, diagnostics)
 
                If stringType IsNot Nothing Then
                    Dim guidString = TypeManager.GetAssemblyGuidString(UnderlyingNamedType.AdaptedNamedTypeSymbol.ContainingAssembly)
                    Return New SynthesizedAttributeData(TypeManager.ModuleBeingBuilt.Compilation, ctor,
                        ImmutableArray.Create(New TypedConstant(stringType, TypedConstantKind.Primitive, guidString),
                            New TypedConstant(stringType, TypedConstantKind.Primitive, UnderlyingNamedType.AdaptedNamedTypeSymbol.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat))),
                        ImmutableArray(Of KeyValuePair(Of String, TypedConstant)).Empty)
                End If
            End If
 
            Return Nothing
        End Function
 
        Protected Overrides Sub ReportMissingAttribute(description As AttributeDescription, syntaxNodeOpt As SyntaxNode, diagnostics As DiagnosticBag)
            EmbeddedTypesManager.ReportDiagnostic(diagnostics, ERRID.ERR_NoPIAAttributeMissing2, syntaxNodeOpt, UnderlyingNamedType.AdaptedNamedTypeSymbol, description.FullName)
        End Sub
 
        Protected Overrides Sub EmbedDefaultMembers(defaultMember As String, syntaxNodeOpt As SyntaxNode, diagnostics As DiagnosticBag)
            For Each s In UnderlyingNamedType.AdaptedNamedTypeSymbol.GetMembers(defaultMember)
                Select Case s.Kind
                    Case SymbolKind.Field
                        TypeManager.EmbedField(Me, DirectCast(s, FieldSymbol).GetCciAdapter(), syntaxNodeOpt, diagnostics)
                    Case SymbolKind.Method
                        TypeManager.EmbedMethod(Me, DirectCast(s, MethodSymbol).GetCciAdapter(), syntaxNodeOpt, diagnostics)
                    Case SymbolKind.Property
                        TypeManager.EmbedProperty(Me, DirectCast(s, PropertySymbol).GetCciAdapter(), syntaxNodeOpt, diagnostics)
                    Case SymbolKind.Event
                        TypeManager.EmbedEvent(Me, DirectCast(s, EventSymbol).GetCciAdapter(), syntaxNodeOpt, diagnostics, isUsedForComAwareEventBinding:=False)
                End Select
            Next
        End Sub
 
    End Class
 
End Namespace