/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Portable/Symbols/PropertySymbol.vb
700 строк
30 KB
Julien Couvreur
Extensions: Add ReduceExtensionMember API (#80659)
22 окт 2025, 22:56
Не верифицирован
22 окт 2025, 22:56
91e1fa9
Код
Авторство
О чём код?
' 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.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ''' <summary> ''' Represents a property. ''' </summary> Friend MustInherit Class PropertySymbol Inherits Symbol Implements IPropertySymbol, IPropertySymbolInternal ' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ' Changes to the public interface of this class should remain synchronized with the C# version. ' Do not make any changes to the public interface without making the corresponding change ' to the C# version. ' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Friend Sub New() End Sub ''' <summary> ''' Get the original definition of this symbol. If this symbol is derived from another ''' symbol by (say) type substitution, this gets the original symbol, as it was defined ''' in source or metadata. ''' </summary> Public Overridable Shadows ReadOnly Property OriginalDefinition As PropertySymbol Get ' Default implements returns Me. Return Me End Get End Property Protected NotOverridable Overrides ReadOnly Property OriginalSymbolDefinition As Symbol Get Return Me.OriginalDefinition End Get End Property ''' <summary> ''' Source: Returns False; properties from source cannot return by reference. ''' Metadata: Returns whether or not this property returns by reference. ''' </summary> Public MustOverride ReadOnly Property ReturnsByRef As Boolean ''' <summary> ''' Gets the type of the property. ''' </summary> Public MustOverride ReadOnly Property Type As TypeSymbol ''' <summary> ''' Returns the list of custom modifiers, if any, associated with the type of the property. ''' </summary> Public MustOverride ReadOnly Property TypeCustomModifiers As ImmutableArray(Of CustomModifier) ''' <summary> ''' Custom modifiers associated with the ref modifier, or an empty array if there are none. ''' </summary> Public MustOverride ReadOnly Property RefCustomModifiers As ImmutableArray(Of CustomModifier) ''' <summary> ''' Gets the parameters of this property. If this property has no parameters, returns ''' an empty list. ''' </summary> Public MustOverride ReadOnly Property Parameters As ImmutableArray(Of ParameterSymbol) ''' <summary> ''' Optimization: in many cases, the parameter count (fast) is sufficient and we ''' don't need the actual parameter symbols (slow). ''' </summary> ''' <remarks> ''' The default implementation is always correct, but may be unnecessarily slow. ''' </remarks> Public Overridable ReadOnly Property ParameterCount As Integer Get Return Me.Parameters.Length End Get End Property ''' <summary> ''' True if the property itself Is excluded from code coverage instrumentation. ''' True for source properties marked with <see cref="AttributeDescription.ExcludeFromCodeCoverageAttribute"/>. ''' </summary> Friend Overridable ReadOnly Property IsDirectlyExcludedFromCodeCoverage As Boolean Get Return False End Get End Property ''' <summary> ''' True if this symbol has a special name (metadata flag SpecialName is set). ''' </summary> Friend MustOverride ReadOnly Property HasSpecialName As Boolean ''' <summary> ''' Returns true if this property is a default property. ''' </summary> Public MustOverride ReadOnly Property IsDefault As Boolean Implements IPropertySymbol.IsIndexer ''' <summary> ''' Returns true if this is a read-only property; i.e., has no set accessor. ''' </summary> Public Overridable ReadOnly Property IsReadOnly As Boolean Implements IPropertySymbol.IsReadOnly Get Return (Me.SetMethod Is Nothing) End Get End Property ''' <summary> ''' Indicates if the property can be read, which means this ''' type overrides OR inherits a getter for this property. ''' </summary> Friend ReadOnly Property IsReadable As Boolean Get Return Me.GetMostDerivedGetMethod() IsNot Nothing End Get End Property ''' <summary> ''' Returns true if this is a write-only property; i.e., has no get accessor. ''' </summary> Public Overridable ReadOnly Property IsWriteOnly As Boolean Implements IPropertySymbol.IsWriteOnly Get Return (Me.GetMethod Is Nothing) End Get End Property ''' <summary> ''' Indicates if the property has a Set accessor. ''' </summary> Friend ReadOnly Property HasSet As Boolean Get Return Me.GetMostDerivedSetMethod() IsNot Nothing End Get End Property ''' <summary> ''' Indicates if the property can be written into, which means this ''' property has a setter or it is a getter only autoproperty accessed ''' in a corresponding constructor or initializer. ''' If the setter is init-only, we also check that it is accessed in a constructor ''' on Me/MyBase/MyClass or is a target of a member initializer in an object member ''' initializer. ''' </summary> Friend Function IsWritable(receiverOpt As BoundExpression, containingBinder As Binder, isKnownTargetOfObjectMemberInitializer As Boolean) As Boolean Debug.Assert(containingBinder IsNot Nothing) Dim mostDerivedSet As MethodSymbol = Me.GetMostDerivedSetMethod() If mostDerivedSet IsNot Nothing Then If Not mostDerivedSet.IsInitOnly Then Return True End If If receiverOpt Is Nothing Then Return False End If ' ok: New C() With { .InitOnlyProperty = ... } If isKnownTargetOfObjectMemberInitializer Then Debug.Assert(receiverOpt.Kind = BoundKind.WithLValueExpressionPlaceholder) Return True End If ' ok: setting on `Me`/`MyBase`/`MyClass` from an instance constructor Dim containingMember As Symbol = containingBinder.ContainingMember If If(TryCast(containingMember, MethodSymbol)?.MethodKind <> MethodKind.Constructor, True) Then Return False End If If receiverOpt.Kind = BoundKind.WithLValueExpressionPlaceholder OrElse receiverOpt.Kind = BoundKind.WithRValueExpressionPlaceholder Then ' This can be a reference used as a target for a `With` statement Dim currentBinder As Binder = containingBinder While currentBinder IsNot Nothing AndAlso currentBinder.ContainingMember Is containingMember Dim withBlockBinder = TryCast(currentBinder, WithBlockBinder) If withBlockBinder IsNot Nothing Then If withBlockBinder.Info?.ExpressionPlaceholder Is receiverOpt Then receiverOpt = withBlockBinder.Info.OriginalExpression End If Exit While End If currentBinder = currentBinder.ContainingBinder End While End If Do Select Case receiverOpt.Kind Case BoundKind.MeReference, BoundKind.MyBaseReference, BoundKind.MyClassReference Return True Case BoundKind.Parenthesized receiverOpt = DirectCast(receiverOpt, BoundParenthesized).Expression Case Else Return False End Select Loop End If Dim sourceProperty As SourcePropertySymbol = TryCast(Me, SourcePropertySymbol) Dim propertyIsStatic As Boolean = Me.IsShared Dim fromMember = containingBinder.ContainingMember Return sourceProperty IsNot Nothing AndAlso fromMember IsNot Nothing AndAlso sourceProperty.IsAutoProperty AndAlso TypeSymbol.Equals(sourceProperty.ContainingType, fromMember.ContainingType, TypeCompareKind.ConsiderEverything) AndAlso propertyIsStatic = fromMember.IsShared AndAlso (propertyIsStatic OrElse (receiverOpt IsNot Nothing AndAlso receiverOpt.Kind = BoundKind.MeReference)) AndAlso ((fromMember.Kind = SymbolKind.Method AndAlso DirectCast(fromMember, MethodSymbol).IsAnyConstructor) OrElse TypeOf containingBinder Is DeclarationInitializerBinder) End Function ''' <summary> ''' Gets the associated "get" method for this property. If this property ''' has no get accessor, returns Nothing. ''' </summary> Public MustOverride ReadOnly Property GetMethod As MethodSymbol ''' <summary> ''' Retrieves Get method for this property or 'most derived' Get method from closest ''' overridden property if such property exists. ''' ''' NOTE: It is not possible in VB, but possible in other languages (for example in C#) to ''' override read-write property and provide override only for setter, thus inheriting ''' getter's implementation. This method will find the Get method from the most-derived ''' overridden property in this case ''' </summary> Friend Function GetMostDerivedGetMethod() As MethodSymbol Dim [property] = Me Do Dim getMethod = [property].GetMethod If getMethod IsNot Nothing Then Return getMethod End If [property] = [property].OverriddenProperty Loop Until [property] Is Nothing Return Nothing End Function ''' <summary> ''' Gets the associated "set" method for this property. If this property ''' has no set accessor, returns Nothing. ''' </summary> Public MustOverride ReadOnly Property SetMethod As MethodSymbol ''' <summary> ''' Retrieves Set method for this property or 'most derived' Set method from closest ''' overridden property if such property exists. ''' ''' NOTE: It is not possible in VB, but possible in other languages (for example in C#) to ''' override read-write property and provide override only for getter, thus inheriting ''' setter's implementation. This method will find the Set method from the most-derived ''' overridden property in this case ''' </summary> Friend Function GetMostDerivedSetMethod() As MethodSymbol Dim [property] = Me Do Dim setMethod = [property].SetMethod If setMethod IsNot Nothing Then Return setMethod End If [property] = [property].OverriddenProperty Loop Until [property] Is Nothing Return Nothing End Function ''' <summary> ''' Backing field of the property, or Nothing if the property doesn't have any. ''' </summary> ''' <remarks> ''' Properties imported from metadata return Nothing. ''' </remarks> Friend MustOverride ReadOnly Property AssociatedField As FieldSymbol ''' <summary> ''' Gets the attributes on event's associated field, if any. ''' </summary> ''' <returns>Returns an array of <see cref="VisualBasicAttributeData"/> or an empty array if there are no attributes.</returns> ''' <remarks> ''' Only WithEvent property may have any attributes applied on its backing field. ''' </remarks> Public Function GetFieldAttributes() As ImmutableArray(Of VisualBasicAttributeData) Dim field = Me.AssociatedField Return If(field Is Nothing, ImmutableArray(Of VisualBasicAttributeData).Empty, field.GetAttributes()) End Function ''' <summary> ''' Returns true if this property hides a base property by name and signature. ''' The equivalent of the "hidebysig" flag in metadata. ''' </summary> ''' <remarks> ''' This property should not be confused with general property overloading in Visual Basic, and is not directly related. ''' This property will only return true if this method hides a base property by name and signature (Overloads keyword). ''' </remarks> Public MustOverride ReadOnly Property IsOverloads As Boolean ''' <summary> ''' Gets the resolution priority of this property, 0 if not set. ''' </summary> Public ReadOnly Property OverloadResolutionPriority As Integer Get Return If(CanHaveOverloadResolutionPriority, GetOverloadResolutionPriority(), 0) End Get End Property Public MustOverride Function GetOverloadResolutionPriority() As Integer Public ReadOnly Property CanHaveOverloadResolutionPriority As Boolean Get Return Not IsOverrides End Get End Property ''' <summary> ''' If this property overrides another property (because it both had the Overrides modifier ''' and there correctly was a property to override), returns the overridden property. ''' </summary> Public ReadOnly Property OverriddenProperty As PropertySymbol Get If Me.IsOverrides Then If IsDefinition Then Return OverriddenMembers.OverriddenMember End If Return OverriddenMembersResult(Of PropertySymbol).GetOverriddenMember(Me, Me.OriginalDefinition.OverriddenProperty) End If Return Nothing End Get End Property ''' <summary> ''' Helper method for accessors to get the overridden accessor methods. Should only be called by the ''' accessor method symbols. ''' </summary> ''' <param name="getter">True to get overridden getters, False to get overridden setters</param> ''' <returns>All the accessors of the given kind implemented by this property.</returns> Friend Function GetAccessorOverride(getter As Boolean) As MethodSymbol Dim overriddenProp = Me.OverriddenProperty If overriddenProp IsNot Nothing Then Return If(getter, overriddenProp.GetMethod, overriddenProp.SetMethod) Else Return Nothing End If End Function ' Get the set of overridden and hidden members for this property. Friend Overridable ReadOnly Property OverriddenMembers As OverriddenMembersResult(Of PropertySymbol) Get ' To save space, the default implementation does not cache its result. We expect there to ' be a very large number of MethodSymbols and we expect that a large percentage of them will ' obviously not override anything (e.g. static methods, constructors, destructors, etc). Return OverrideHidingHelper(Of PropertySymbol).MakeOverriddenMembers(Me) End Get End Property ''' <summary> ''' Returns interface properties explicitly implemented by this property. ''' </summary> Public MustOverride ReadOnly Property ExplicitInterfaceImplementations As ImmutableArray(Of PropertySymbol) Public NotOverridable Overrides ReadOnly Property Kind As SymbolKind Get Return SymbolKind.Property End Get End Property Friend MustOverride ReadOnly Property CallingConvention As Microsoft.Cci.CallingConvention Friend Overrides Function Accept(Of TArgument, TResult)(visitor As VisualBasicSymbolVisitor(Of TArgument, TResult), arg As TArgument) As TResult Return visitor.VisitProperty(Me, arg) End Function ''' <summary> ''' Get the "this" parameter for this property. This is only valid for source fields. ''' </summary> Friend Overridable ReadOnly Property MeParameter As ParameterSymbol Get Throw ExceptionUtilities.Unreachable End Get End Property Friend Overridable ReadOnly Property ReducedFrom As PropertySymbol Get Return Nothing End Get End Property Friend Overridable ReadOnly Property ReducedFromDefinition As PropertySymbol Get Return Nothing End Get End Property Friend Overridable ReadOnly Property ReceiverType As TypeSymbol Get Return ContainingType End Get End Property Friend Overrides Function GetUseSiteInfo() As UseSiteInfo(Of AssemblySymbol) If Me.IsDefinition Then Return New UseSiteInfo(Of AssemblySymbol)(PrimaryDependency) End If Return Me.OriginalDefinition.GetUseSiteInfo() End Function Friend Function CalculateUseSiteInfo() As UseSiteInfo(Of AssemblySymbol) Debug.Assert(IsDefinition) ' Check return type. Dim useSiteInfo As UseSiteInfo(Of AssemblySymbol) = New UseSiteInfo(Of AssemblySymbol)(Me.PrimaryDependency) If MergeUseSiteInfo(useSiteInfo, DeriveUseSiteInfoFromType(Me.Type)) Then Return useSiteInfo End If ' Check return type custom modifiers. Dim refModifiersUseSiteInfo = DeriveUseSiteInfoFromCustomModifiers(Me.RefCustomModifiers) If MergeUseSiteInfo(useSiteInfo, refModifiersUseSiteInfo) Then Return useSiteInfo End If Dim typeModifiersUseSiteInfo = DeriveUseSiteInfoFromCustomModifiers(Me.TypeCustomModifiers) If MergeUseSiteInfo(useSiteInfo, typeModifiersUseSiteInfo) Then Return useSiteInfo End If ' Check parameters. Dim parametersUseSiteInfo = DeriveUseSiteInfoFromParameters(Me.Parameters) If MergeUseSiteInfo(useSiteInfo, parametersUseSiteInfo) Then Return useSiteInfo End If Dim errorInfo As DiagnosticInfo = useSiteInfo.DiagnosticInfo ' If the member is in an assembly with unified references, ' we check if its definition depends on a type from a unified reference. If errorInfo Is Nothing AndAlso Me.ContainingModule.HasUnifiedReferences Then Dim unificationCheckedTypes As HashSet(Of TypeSymbol) = Nothing errorInfo = If(Me.Type.GetUnificationUseSiteDiagnosticRecursive(Me, unificationCheckedTypes), If(GetUnificationUseSiteDiagnosticRecursive(Me.RefCustomModifiers, Me, unificationCheckedTypes), If(GetUnificationUseSiteDiagnosticRecursive(Me.TypeCustomModifiers, Me, unificationCheckedTypes), GetUnificationUseSiteDiagnosticRecursive(Me.Parameters, Me, unificationCheckedTypes)))) Debug.Assert(errorInfo Is Nothing OrElse errorInfo.Severity = DiagnosticSeverity.Error) End If If errorInfo IsNot Nothing Then Return New UseSiteInfo(Of AssemblySymbol)(errorInfo) End If Dim primaryDependency = useSiteInfo.PrimaryDependency Dim secondaryDependency = useSiteInfo.SecondaryDependencies refModifiersUseSiteInfo.MergeDependencies(primaryDependency, secondaryDependency) typeModifiersUseSiteInfo.MergeDependencies(primaryDependency, secondaryDependency) parametersUseSiteInfo.MergeDependencies(primaryDependency, secondaryDependency) Return New UseSiteInfo(Of AssemblySymbol)(diagnosticInfo:=Nothing, primaryDependency, secondaryDependency) End Function ''' <summary> ''' Return error code that has highest priority while calculating use site error for this symbol. ''' </summary> Protected Overrides Function IsHighestPriorityUseSiteError(code As Integer) As Boolean Return code = ERRID.ERR_UnsupportedProperty1 OrElse code = ERRID.ERR_UnsupportedCompilerFeature End Function Public NotOverridable Overrides ReadOnly Property HasUnsupportedMetadata As Boolean Get Dim info As DiagnosticInfo = GetUseSiteInfo().DiagnosticInfo Return info IsNot Nothing AndAlso (info.Code = ERRID.ERR_UnsupportedProperty1 OrElse info.Code = ERRID.ERR_UnsupportedCompilerFeature) End Get End Property ''' <summary> ''' Returns true if this property is an auto-created WithEvents property that ''' takes place of a field member when the field is marked as WithEvents. ''' </summary> Public Overridable ReadOnly Property IsWithEvents As Boolean Implements IPropertySymbol.IsWithEvents Get Dim overridden = Me.OverriddenProperty If overridden Is Nothing Then Return False End If Return overridden.IsWithEvents End Get End Property Friend Overrides ReadOnly Property EmbeddedSymbolKind As EmbeddedSymbolKind Get Return Me.ContainingSymbol.EmbeddedSymbolKind End Get End Property ''' <summary> ''' Is this a property of a tuple type? ''' </summary> Public Overridable ReadOnly Property IsTupleProperty() As Boolean Get Return False End Get End Property ''' <summary> ''' If this is a property of a tuple type, return corresponding underlying property from the ''' tuple underlying type. Otherwise, Nothing. ''' </summary> Public Overridable ReadOnly Property TupleUnderlyingProperty() As PropertySymbol Get Return Nothing End Get End Property ''' <summary> ''' Clone the property parameters for the accessor method. The ''' parameters are cloned (rather than referenced from the property) ''' since the ContainingSymbol needs to be set to the accessor. ''' </summary> Friend Sub CloneParameters(method As MethodSymbol, parameters As ArrayBuilder(Of ParameterSymbol)) Dim originalParameters = Me.Parameters For i As Integer = 0 To originalParameters.Length - 1 Dim propertyParameter = originalParameters(i) ' TODO: Should CustomModifiers be used from this property ' parameter even in the case of overridden properties? parameters.Add(propertyParameter.ChangeOwner(method)) Next End Sub ''' <summary> ''' Is this an auto-generated property of a group class? ''' </summary> Friend MustOverride Overrides ReadOnly Property IsMyGroupCollectionProperty As Boolean Public MustOverride ReadOnly Property IsRequired As Boolean #Region "IPropertySymbol" Private ReadOnly Property IPropertySymbol_ExplicitInterfaceImplementations As ImmutableArray(Of IPropertySymbol) Implements IPropertySymbol.ExplicitInterfaceImplementations Get Return ImmutableArrayExtensions.Cast(Of PropertySymbol, IPropertySymbol)(Me.ExplicitInterfaceImplementations) End Get End Property Private ReadOnly Property IPropertySymbol_GetMethod As IMethodSymbol Implements IPropertySymbol.GetMethod Get Return Me.GetMethod End Get End Property Private ReadOnly Property IPropertySymbol_OriginalDefinition As IPropertySymbol Implements IPropertySymbol.OriginalDefinition Get Return Me.OriginalDefinition End Get End Property Private ReadOnly Property IPropertySymbol_OverriddenProperty As IPropertySymbol Implements IPropertySymbol.OverriddenProperty Get Return Me.OverriddenProperty End Get End Property Private ReadOnly Property IPropertySymbol_Parameters As ImmutableArray(Of IParameterSymbol) Implements IPropertySymbol.Parameters Get Return StaticCast(Of IParameterSymbol).From(Me.Parameters) End Get End Property Private ReadOnly Property IPropertySymbol_SetMethod As IMethodSymbol Implements IPropertySymbol.SetMethod Get Return Me.SetMethod End Get End Property Private ReadOnly Property IPropertySymbol_IsRequired As Boolean Implements IPropertySymbol.IsRequired Get Return Me.IsRequired End Get End Property Private ReadOnly Property IPropertySymbol_ReturnsByRef As Boolean Implements IPropertySymbol.ReturnsByRef Get Return Me.ReturnsByRef End Get End Property Private ReadOnly Property IPropertySymbol_ByRefReturnIsReadonly As Boolean Implements IPropertySymbol.ReturnsByRefReadonly Get Return False End Get End Property Private ReadOnly Property IPropertySymbol_RefKind As RefKind Implements IPropertySymbol.RefKind Get Return If(Me.ReturnsByRef, RefKind.Ref, RefKind.None) End Get End Property Private ReadOnly Property IPropertySymbol_Type As ITypeSymbol Implements IPropertySymbol.Type Get Return Me.Type End Get End Property Private ReadOnly Property IPropertySymbol_NullableAnnotation As NullableAnnotation Implements IPropertySymbol.NullableAnnotation Get Return NullableAnnotation.None End Get End Property Private ReadOnly Property IPropertySymbol_RefCustomModifiers As ImmutableArray(Of CustomModifier) Implements IPropertySymbol.RefCustomModifiers Get Return Me.RefCustomModifiers End Get End Property Private ReadOnly Property IPropertySymbol_TypeCustomModifiers As ImmutableArray(Of CustomModifier) Implements IPropertySymbol.TypeCustomModifiers Get Return Me.TypeCustomModifiers End Get End Property Private ReadOnly Property IPropertySymbol_PartialDefinitionPart As IPropertySymbol Implements IPropertySymbol.PartialDefinitionPart Get ' Feature not supported in VB Return Nothing End Get End Property Private ReadOnly Property IPropertySymbol_PartialImplementationPart As IPropertySymbol Implements IPropertySymbol.PartialImplementationPart Get ' Feature not supported in VB Return Nothing End Get End Property Private ReadOnly Property IPropertySymbol_IsPartialDefinition As Boolean Implements IPropertySymbol.IsPartialDefinition Get ' Feature not supported in VB Return False End Get End Property Public ReadOnly Property IPropertySymbolInternal_PartialImplementationPart As IPropertySymbolInternal Implements IPropertySymbolInternal.PartialImplementationPart Get ' Feature not supported in VB Return Nothing End Get End Property Public ReadOnly Property IPropertySymbolInternal_PartialDefinitionPart As IPropertySymbolInternal Implements IPropertySymbolInternal.PartialDefinitionPart Get ' Feature not supported in VB Return Nothing End Get End Property Public Overrides Sub Accept(visitor As SymbolVisitor) visitor.VisitProperty(Me) End Sub Public Overrides Function Accept(Of TResult)(visitor As SymbolVisitor(Of TResult)) As TResult Return visitor.VisitProperty(Me) End Function Public Overrides Function Accept(Of TArgument, TResult)(visitor As SymbolVisitor(Of TArgument, TResult), argument As TArgument) As TResult Return visitor.VisitProperty(Me, argument) End Function Public Overrides Sub Accept(visitor As VisualBasicSymbolVisitor) visitor.VisitProperty(Me) End Sub Public Overrides Function Accept(Of TResult)(visitor As VisualBasicSymbolVisitor(Of TResult)) As TResult Return visitor.VisitProperty(Me) End Function Public Function ReduceExtensionMember(receiverType As ITypeSymbol) As IPropertySymbol Implements IPropertySymbol.ReduceExtensionMember Return Nothing End Function #End Region End Class End Namespace