/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/PEFieldSymbol.vb
478 строк
22 KB
dotnet-maestro[bot]
[main] Update dependencies from dotnet/arcade (#68573)
15 июн 2023, 22:11
Не верифицирован
15 июн 2023, 22:11
1a29604
Код
Авторство
О чём код?
' 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.Generic Imports System.Collections.Immutable Imports System.Collections.ObjectModel Imports System.Globalization Imports System.Runtime.InteropServices Imports System.Threading Imports System.Reflection Imports System.Reflection.Metadata Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports TypeKind = Microsoft.CodeAnalysis.TypeKind Imports System.Reflection.Metadata.Ecma335 Imports Microsoft.CodeAnalysis.VisualBasic.Emit Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE ''' <summary> ''' The class to represent all fields imported from a PE/module. ''' </summary> Friend NotInheritable Class PEFieldSymbol Inherits FieldSymbol ''' <summary> ''' This symbol is used as a type for a "fake" required custom modifier added for ByRef fields. ''' This allows us to report use site errors for ByRef fields, and, at the same time, allows us ''' to accurately match them by signature (since this instance is unique and is not used for anything else) ''' without adding full support for RefKind and RefCustomModifiers ''' </summary> Private Shared ReadOnly _byRefPlaceholder As New UnsupportedMetadataTypeSymbol() Private ReadOnly _handle As FieldDefinitionHandle Private ReadOnly _name As String Private ReadOnly _flags As FieldAttributes Private ReadOnly _containingType As PENamedTypeSymbol Private _lazyType As TypeSymbol Private _lazyCustomModifiers As ImmutableArray(Of CustomModifier) Private _lazyConstantValue As ConstantValue = Microsoft.CodeAnalysis.ConstantValue.Unset Private _lazyDocComment As Tuple(Of CultureInfo, String) Private _lazyCustomAttributes As ImmutableArray(Of VisualBasicAttributeData) Private _lazyCachedUseSiteInfo As CachedUseSiteInfo(Of AssemblySymbol) = CachedUseSiteInfo(Of AssemblySymbol).Uninitialized ' Indicates unknown state. Private _lazyObsoleteAttributeData As ObsoleteAttributeData = ObsoleteAttributeData.Uninitialized Private _lazyIsRequired As ThreeState = ThreeState.Unknown Friend Sub New( moduleSymbol As PEModuleSymbol, containingType As PENamedTypeSymbol, handle As FieldDefinitionHandle ) Debug.Assert(moduleSymbol IsNot Nothing) Debug.Assert(containingType IsNot Nothing) Debug.Assert(Not handle.IsNil) _handle = handle _containingType = containingType Try moduleSymbol.Module.GetFieldDefPropsOrThrow(handle, _name, _flags) Catch mrEx As BadImageFormatException If _name Is Nothing Then _name = String.Empty End If _lazyCachedUseSiteInfo.Initialize(ErrorFactory.ErrorInfo(ERRID.ERR_UnsupportedField1, Me)) End Try End Sub Public Overrides ReadOnly Property Name As String Get Return _name End Get End Property Public Overrides ReadOnly Property MetadataToken As Integer Get Return MetadataTokens.GetToken(_handle) End Get End Property Friend ReadOnly Property FieldFlags As FieldAttributes Get Return _flags End Get End Property Public Overrides ReadOnly Property AssociatedSymbol As Symbol Get Return Nothing End Get End Property Public Overrides ReadOnly Property ContainingSymbol As Symbol Get Return _containingType End Get End Property Public Overrides ReadOnly Property ContainingType As NamedTypeSymbol Get Return _containingType End Get End Property Public Overrides ReadOnly Property DeclaredAccessibility As Accessibility Get Dim access As Accessibility = Accessibility.Private Select Case _flags And FieldAttributes.FieldAccessMask Case FieldAttributes.Assembly access = Accessibility.Friend Case FieldAttributes.FamORAssem access = Accessibility.ProtectedOrFriend Case FieldAttributes.FamANDAssem access = Accessibility.ProtectedAndFriend Case FieldAttributes.Private, FieldAttributes.PrivateScope access = Accessibility.Private Case FieldAttributes.Public access = Accessibility.Public Case FieldAttributes.Family access = Accessibility.Protected Case Else access = Accessibility.Private End Select Return access End Get End Property Public Overloads Overrides Function GetAttributes() As ImmutableArray(Of VisualBasicAttributeData) If _lazyCustomAttributes.IsDefault Then Dim containingPEModuleSymbol = DirectCast(ContainingModule(), PEModuleSymbol) Dim filterOutConstantAttributeDescription As AttributeDescription = GetConstantAttributeDescription() If filterOutConstantAttributeDescription.Signatures IsNot Nothing Then Dim constantAttribute As CustomAttributeHandle Dim attributes = containingPEModuleSymbol.GetCustomAttributesForToken( _handle, constantAttribute, filterOutConstantAttributeDescription) ImmutableInterlocked.InterlockedInitialize(_lazyCustomAttributes, attributes) Else containingPEModuleSymbol.LoadCustomAttributes(_handle, _lazyCustomAttributes) End If End If Return _lazyCustomAttributes End Function Private Function GetConstantAttributeDescription() As AttributeDescription Dim value As ConstantValue If Me.Type.SpecialType = SpecialType.System_DateTime Then value = GetConstantValue(ConstantFieldsInProgress.Empty) If value IsNot Nothing AndAlso value.Discriminator = ConstantValueTypeDiscriminator.DateTime Then Return AttributeDescription.DateTimeConstantAttribute End If ElseIf Me.Type.SpecialType = SpecialType.System_Decimal Then value = GetConstantValue(ConstantFieldsInProgress.Empty) If value IsNot Nothing AndAlso value.Discriminator = ConstantValueTypeDiscriminator.Decimal Then Return AttributeDescription.DecimalConstantAttribute End If End If Return Nothing End Function Friend Overrides Iterator Function GetCustomAttributesToEmit(moduleBuilder As PEModuleBuilder) As IEnumerable(Of VisualBasicAttributeData) For Each attribute In GetAttributes() Yield attribute Next ' Yield hidden attributes last, order might be important. Dim filteredOutConstantAttributeDescription As AttributeDescription = GetConstantAttributeDescription() If filteredOutConstantAttributeDescription.Signatures IsNot Nothing Then Dim containingPEModuleSymbol = DirectCast(ContainingModule(), PEModuleSymbol) Yield New PEAttributeData(containingPEModuleSymbol, containingPEModuleSymbol.Module.FindLastTargetAttribute(Me._handle, filteredOutConstantAttributeDescription).Handle) End If End Function Friend Overrides ReadOnly Property HasSpecialName As Boolean Get Return (_flags And FieldAttributes.SpecialName) <> 0 End Get End Property Friend Overrides ReadOnly Property HasRuntimeSpecialName As Boolean Get Return (_flags And FieldAttributes.RTSpecialName) <> 0 End Get End Property Friend Overrides ReadOnly Property IsNotSerialized As Boolean Get #Disable Warning SYSLIB0050 ' 'TypeAttributes.Serializable' is obsolete Return (_flags And FieldAttributes.NotSerialized) <> 0 #Enable Warning SYSLIB0050 End Get End Property Public Overrides ReadOnly Property IsReadOnly As Boolean Get Return (_flags And FieldAttributes.InitOnly) <> 0 End Get End Property Public Overrides ReadOnly Property IsConst As Boolean Get Return (_flags And FieldAttributes.Literal) <> 0 OrElse GetConstantValue(ConstantFieldsInProgress.Empty) IsNot Nothing End Get End Property Friend Overrides Function GetConstantValue(inProgress As ConstantFieldsInProgress) As ConstantValue If _lazyConstantValue Is Microsoft.CodeAnalysis.ConstantValue.Unset Then Dim value As ConstantValue = Nothing If (_flags And FieldAttributes.Literal) <> 0 Then value = _containingType.ContainingPEModule.Module.GetConstantFieldValue(_handle) value = AdjustConstantValueFromMetadata(value, Me.Type, False) Dim selfOrUnderlyingType = Me.Type.GetEnumUnderlyingTypeOrSelf Dim selfOrUnderlyingSpecialType = selfOrUnderlyingType.SpecialType ' handle nothing literal conversions If value.IsNothing Then ' assign a numerical 0 to numeric types If Me.Type.GetEnumUnderlyingTypeOrSelf.IsNumericType Then value = Microsoft.CodeAnalysis.ConstantValue.Default( Microsoft.CodeAnalysis.ConstantValue.GetDiscriminator(selfOrUnderlyingSpecialType)) ElseIf selfOrUnderlyingSpecialType = SpecialType.System_DateTime Then ' assign the default value for DateTime value = Microsoft.CodeAnalysis.ConstantValue.Default(ConstantValueTypeDiscriminator.DateTime) ElseIf selfOrUnderlyingSpecialType = SpecialType.System_Boolean Then ' assign the default value for Boolean value = Microsoft.CodeAnalysis.ConstantValue.Default(ConstantValueTypeDiscriminator.Boolean) ElseIf selfOrUnderlyingSpecialType = SpecialType.System_Char Then ' assign the default value for Char value = Microsoft.CodeAnalysis.ConstantValue.Default(ConstantValueTypeDiscriminator.Char) Else ' This case handles System.Object (last remaining type of VB's primitives types) and ' all type where const folding of a nothing reference would succeed (Dev10 allows importing constants ' of arbitrary reference types with a constant value of "nothing"). So we are allowing a bit more than ' the spec defines. If selfOrUnderlyingType.IsErrorType OrElse Conversions.TryFoldNothingReferenceConversion(value, ConversionKind.WideningNothingLiteral, selfOrUnderlyingType) Is Nothing Then ' type parameters and structures are not supported to be initialized with nothing value = Microsoft.CodeAnalysis.ConstantValue.Bad End If End If ElseIf value.SpecialType <> selfOrUnderlyingSpecialType Then ' If the constant value from metadata is invalid (has a different type), mark the value as bad. value = Microsoft.CodeAnalysis.ConstantValue.Bad End If End If ' If this is a DateTime or Decimal, the constant value comes from an attributes (VB assumption). ' This also means that these values overwrite constant values that have been generated by non VB compilers. Dim defaultValue As ConstantValue = CodeAnalysis.ConstantValue.NotAvailable If Me.Type.SpecialType = SpecialType.System_DateTime Then If PEModule.HasDateTimeConstantAttribute(Handle, defaultValue) Then value = defaultValue End If ElseIf Me.Type.SpecialType = SpecialType.System_Decimal Then If PEModule.HasDecimalConstantAttribute(Handle, defaultValue) Then value = defaultValue End If End If Interlocked.CompareExchange(_lazyConstantValue, value, Microsoft.CodeAnalysis.ConstantValue.Unset) End If Return _lazyConstantValue End Function Public Overrides ReadOnly Property IsRequired As Boolean Get If Not _lazyIsRequired.HasValue() Then _lazyIsRequired = PEModule.HasAttribute(Handle, AttributeDescription.RequiredMemberAttribute).ToThreeState() End If Return _lazyIsRequired.Value() End Get End Property Public Overrides ReadOnly Property IsShared As Boolean Get Return (_flags And FieldAttributes.Static) <> 0 End Get End Property Friend Overrides ReadOnly Property MarshallingInformation As MarshalPseudoCustomAttributeData Get ' the compiler doesn't need full marshalling information, just the unmanaged type Return Nothing End Get End Property Friend Overrides ReadOnly Property ObsoleteAttributeData As ObsoleteAttributeData Get ObsoleteAttributeHelpers.InitializeObsoleteDataFromMetadata(_lazyObsoleteAttributeData, _handle, DirectCast(ContainingModule, PEModuleSymbol)) Return _lazyObsoleteAttributeData End Get End Property Friend Overrides ReadOnly Property IsMarshalledExplicitly As Boolean Get Return (_flags And FieldAttributes.HasFieldMarshal) <> 0 End Get End Property Friend Overrides ReadOnly Property MarshallingType As UnmanagedType Get If (_flags And FieldAttributes.HasFieldMarshal) = 0 Then Return Nothing End If Return PEModule.GetMarshallingType(_handle) End Get End Property Friend Overrides ReadOnly Property MarshallingDescriptor As ImmutableArray(Of Byte) Get If (_flags And FieldAttributes.HasFieldMarshal) = 0 Then Return Nothing End If Return PEModule.GetMarshallingDescriptor(_handle) End Get End Property Friend Overrides ReadOnly Property TypeLayoutOffset As Integer? Get Return PEModule.GetFieldOffset(_handle) End Get End Property Public Overrides ReadOnly Property Locations As ImmutableArray(Of Location) Get Return StaticCast(Of Location).From(_containingType.ContainingPEModule.MetadataLocation) End Get End Property Public Overrides ReadOnly Property DeclaringSyntaxReferences As ImmutableArray(Of SyntaxReference) Get Return ImmutableArray(Of SyntaxReference).Empty End Get End Property Private Sub EnsureSignatureIsLoaded() If _lazyType Is Nothing Then Dim moduleSymbol = _containingType.ContainingPEModule Dim fieldInfo As FieldInfo(Of TypeSymbol) = New MetadataDecoder(moduleSymbol, _containingType).DecodeFieldSignature(_handle) Dim type As TypeSymbol = Nothing Dim customModifiers As ImmutableArray(Of ModifierInfo(Of TypeSymbol)) = Nothing GetSignatureParts(fieldInfo, type, customModifiers) type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, _handle, moduleSymbol) ImmutableInterlocked.InterlockedCompareExchange(_lazyCustomModifiers, VisualBasicCustomModifier.Convert(customModifiers), Nothing) Interlocked.CompareExchange(_lazyType, type, Nothing) End If End Sub Friend Shared Sub GetSignatureParts(fieldInfo As FieldInfo(Of TypeSymbol), ByRef type As TypeSymbol, ByRef customModifiers As ImmutableArray(Of ModifierInfo(Of TypeSymbol))) type = fieldInfo.Type customModifiers = fieldInfo.CustomModifiers.NullToEmpty If fieldInfo.IsByRef Then Dim refCustomModifiers = fieldInfo.RefCustomModifiers.NullToEmpty.Add(New ModifierInfo(Of TypeSymbol)(isOptional:=False, _byRefPlaceholder)) customModifiers = refCustomModifiers.AddRange(customModifiers) ElseIf Not fieldInfo.RefCustomModifiers.IsDefaultOrEmpty Then Throw ExceptionUtilities.Unreachable End If End Sub Public Overrides ReadOnly Property Type As TypeSymbol Get EnsureSignatureIsLoaded() Return _lazyType End Get End Property Public Overrides ReadOnly Property CustomModifiers As ImmutableArray(Of CustomModifier) Get EnsureSignatureIsLoaded() Return _lazyCustomModifiers End Get End Property Public Overrides Function GetDocumentationCommentXml(Optional preferredCulture As CultureInfo = Nothing, Optional expandIncludes As Boolean = False, Optional cancellationToken As CancellationToken = Nothing) As String ' Note: m_LazyDocComment is passed ByRef Return PEDocumentationCommentUtils.GetDocumentationComment( Me, _containingType.ContainingPEModule, preferredCulture, cancellationToken, _lazyDocComment) End Function Friend Overrides Function GetUseSiteInfo() As UseSiteInfo(Of AssemblySymbol) Dim primaryDependency As AssemblySymbol = Me.PrimaryDependency If Not _lazyCachedUseSiteInfo.IsInitialized Then Dim fieldUseSiteInfo = CalculateUseSiteInfo() If fieldUseSiteInfo.DiagnosticInfo Is Nothing Then Dim errorInfo = DeriveCompilerFeatureRequiredDiagnostic(fieldUseSiteInfo) If errorInfo IsNot Nothing Then fieldUseSiteInfo = New UseSiteInfo(Of AssemblySymbol)(errorInfo) End If End If ' if there was no previous use site error for this symbol, check the constant value If fieldUseSiteInfo.DiagnosticInfo Is Nothing Then ' report use site errors for invalid constant values Dim constantValue = GetConstantValue(ConstantFieldsInProgress.Empty) If constantValue IsNot Nothing AndAlso constantValue.IsBad Then fieldUseSiteInfo = New UseSiteInfo(Of AssemblySymbol)(New DiagnosticInfo(MessageProvider.Instance, ERRID.ERR_UnsupportedConstant2, Me.ContainingType, Me.Name)) End If End If _lazyCachedUseSiteInfo.Initialize(primaryDependency, fieldUseSiteInfo) End If Return _lazyCachedUseSiteInfo.ToUseSiteInfo(primaryDependency) End Function Private Function DeriveCompilerFeatureRequiredDiagnostic(ByRef result As UseSiteInfo(Of AssemblySymbol)) As DiagnosticInfo Dim containingModule = _containingType.ContainingPEModule Return If(DeriveCompilerFeatureRequiredAttributeDiagnostic(Me, containingModule, Handle, CompilerFeatureRequiredFeatures.None, New MetadataDecoder(containingModule, _containingType)), _containingType.GetCompilerFeatureRequiredDiagnostic()) End Function Friend ReadOnly Property Handle As FieldDefinitionHandle Get Return _handle End Get End Property ''' <remarks> ''' This is for perf, not for correctness. ''' </remarks> Friend Overrides ReadOnly Property DeclaringCompilation As VisualBasicCompilation Get Return Nothing End Get End Property Private ReadOnly Property PEModule As PEModule Get Return DirectCast(ContainingModule, PEModuleSymbol).Module End Get End Property End Class End Namespace