/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Portable/Symbols/Source/SourceMemberFieldSymbol.vb
678 строк
37 KB
Cyrus Najmabadi
Update code to use GetFirstLocation() instead of Locations[0] or Locations.First() (#80709)
21 окт 2025, 00:00
Не верифицирован
21 окт 2025, 00:00
3a723bb
Код
Авторство
О чём код?
' 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.Globalization Imports System.Runtime.InteropServices Imports System.Threading Imports Microsoft.CodeAnalysis.Collections Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports TypeKind = Microsoft.CodeAnalysis.TypeKind Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Friend Class SourceMemberFieldSymbol Inherits SourceFieldSymbol ' The type of the field. Set to Nothing if not computed yet. Private _lazyType As TypeSymbol Private _lazyMeParameter As ParameterSymbol Protected Sub New(container As SourceMemberContainerTypeSymbol, syntaxRef As SyntaxReference, name As String, memberFlags As SourceMemberFlags) MyBase.New(container, syntaxRef, name, memberFlags) End Sub Protected Overrides Sub GenerateDeclarationErrorsImpl(cancellationToken As CancellationToken) MyBase.GenerateDeclarationErrorsImpl(cancellationToken) If (_lazyState And StateFlags.TypeConstraintsChecked) = 0 Then Dim sourceModule = DirectCast(Me.ContainingModule, SourceModuleSymbol) Dim diagnostics = BindingDiagnosticBag.GetInstance() Type.CheckAllConstraints(DeclaringCompilation.LanguageVersion, GetFirstLocation(), diagnostics, template:=New CompoundUseSiteInfo(Of AssemblySymbol)(diagnostics, sourceModule.ContainingAssembly)) sourceModule.AtomicSetFlagAndStoreDiagnostics(_lazyState, StateFlags.TypeConstraintsChecked, 0, diagnostics) diagnostics.Free() End If End Sub Friend NotOverridable Overrides ReadOnly Property DeclarationSyntax As VisualBasicSyntaxNode Get Return Syntax.Parent.Parent End Get End Property Friend NotOverridable Overrides Function IsDefinedInSourceTree(tree As SyntaxTree, definedWithinSpan As TextSpan?, Optional cancellationToken As CancellationToken = Nothing) As Boolean Return IsDefinedInSourceTree(Me.DeclarationSyntax, tree, definedWithinSpan, cancellationToken) End Function Friend NotOverridable Overrides ReadOnly Property GetAttributeDeclarations As OneOrMany(Of SyntaxList(Of AttributeListSyntax)) Get Return OneOrMany.Create(DirectCast(Syntax.Parent.Parent, FieldDeclarationSyntax).AttributeLists) End Get End Property Friend Overrides ReadOnly Property MeParameter As ParameterSymbol Get If IsShared Then Return Nothing Else If _lazyMeParameter Is Nothing Then Interlocked.CompareExchange(Of ParameterSymbol)(_lazyMeParameter, New MeParameterSymbol(Me), Nothing) End If Return _lazyMeParameter End If End Get End Property Public Overrides ReadOnly Property Type As TypeSymbol Get If _lazyType Is Nothing Then Dim sourceModule = DirectCast(Me.ContainingModule, SourceModuleSymbol) Dim diagnostics = BindingDiagnosticBag.GetInstance() Dim varType = ComputeType(diagnostics) Debug.Assert(varType IsNot Nothing) sourceModule.AtomicStoreReferenceAndDiagnostics(_lazyType, varType, diagnostics) diagnostics.Free() End If Return _lazyType End Get End Property Private Function ComputeType(diagBag As BindingDiagnosticBag) As TypeSymbol Dim declaredType = GetDeclaredType(diagBag) ' needed for diagnostic creation in all cases If Not HasDeclaredType Then Return GetInferredType(ConstantFieldsInProgress.Empty) Else Return declaredType End If End Function Private Function GetDeclaredType(diagBag As BindingDiagnosticBag) As TypeSymbol Dim modifiedIdentifier As ModifiedIdentifierSyntax = DirectCast(Syntax, ModifiedIdentifierSyntax) Dim declarator = DirectCast(modifiedIdentifier.Parent, VariableDeclaratorSyntax) Dim binder As Binder = BinderBuilder.CreateBinderForType( DirectCast(Me.ContainingModule, SourceModuleSymbol), Me.SyntaxTree, ContainingType) binder = New LocationSpecificBinder(BindingLocation.FieldType, Me, binder) ' Ignore type syntax errors for all but the first field of a given type. Dim varType = ComputeFieldType(modifiedIdentifier, binder, diagBag, isConst:=Me.IsConst, isWithEvents:=False, ignoreTypeSyntaxDiagnostics:=(m_memberFlags And SourceMemberFlags.FirstFieldDeclarationOfType) = 0) If Not varType.IsErrorType() Then If Me.IsConst Then ' Note: The native compiler reports two errors for "Const F As C": ERR_ConstAsNonConstant ' and ERR_ConstantWithNoValue. Rather than report two errors in those cases, we only ' report ERR_ConstantWithNoValue if ERR_ConstAsNonConstant has not been reported. ' In other words, we only report "Constants must have a value" for fields with missing ' initializer if the field type can be "Const". If Not varType.IsValidTypeForConstField() Then ' "Constants must be of an intrinsic or enumerated type, not a class, structure, type parameter, or array type." If varType.IsArrayType Then ' arrays get the squiggles under the identifier name binder.ReportDiagnostic(diagBag, modifiedIdentifier.Identifier, ERRID.ERR_ConstAsNonConstant) Else ' other data types get the squiggles under the type part of the as clause binder.ReportDiagnostic(diagBag, declarator.AsClause.Type, ERRID.ERR_ConstAsNonConstant) End If ElseIf declarator.Initializer Is Nothing Then ' "Constants must have a value." binder.ReportDiagnostic(diagBag, modifiedIdentifier, ERRID.ERR_ConstantWithNoValue) End If Else Dim restrictedType As TypeSymbol = Nothing If varType.IsRestrictedTypeOrArrayType(restrictedType) Then binder.ReportDiagnostic(diagBag, declarator.AsClause.Type, ERRID.ERR_RestrictedType1, restrictedType) End If End If If HasDeclaredType Then Dim errorLocation = SourceSymbolHelpers.GetAsClauseLocation(modifiedIdentifier.Identifier, declarator.AsClause) AccessCheck.VerifyAccessExposureForMemberType(Me, errorLocation, varType, diagBag) End If End If Return varType End Function ' Helper used for computing the type of a field. Private Shared Function ComputeFieldType(modifiedIdentifierSyntax As ModifiedIdentifierSyntax, binder As Binder, diagnostics As BindingDiagnosticBag, isConst As Boolean, isWithEvents As Boolean, ignoreTypeSyntaxDiagnostics As Boolean) As TypeSymbol Dim declarator = DirectCast(modifiedIdentifierSyntax.Parent, VariableDeclaratorSyntax) Dim asClauseOpt = declarator.AsClause Dim asClauseType As TypeSymbol = Nothing Dim initializerSyntax As VisualBasicSyntaxNode = declarator.Initializer If asClauseOpt IsNot Nothing Then If (asClauseOpt.Kind <> SyntaxKind.AsNewClause OrElse (DirectCast(asClauseOpt, AsNewClauseSyntax).NewExpression.Kind <> SyntaxKind.AnonymousObjectCreationExpression)) Then asClauseType = binder.BindTypeSyntax(asClauseOpt.Type, If(ignoreTypeSyntaxDiagnostics, BindingDiagnosticBag.Discarded, diagnostics)) End If If asClauseOpt.Kind = SyntaxKind.AsNewClause Then initializerSyntax = asClauseOpt End If End If Dim omitFurtherDiagnostics As Boolean = String.IsNullOrEmpty(modifiedIdentifierSyntax.Identifier.ValueText) Dim varType As TypeSymbol If (asClauseOpt IsNot Nothing AndAlso asClauseOpt.Kind = SyntaxKind.AsNewClause AndAlso (DirectCast(asClauseOpt, AsNewClauseSyntax).NewExpression.Kind = SyntaxKind.AnonymousObjectCreationExpression)) Then varType = ErrorTypeSymbol.UnknownResultType Else Dim getErrorInfo As Func(Of DiagnosticInfo) = Nothing If Not omitFurtherDiagnostics AndAlso Not (isConst AndAlso binder.OptionInfer) Then If isWithEvents Then 'WithEvents' variables must have an 'As' clause. getErrorInfo = ErrorFactory.GetErrorInfo_ERR_WithEventsRequiresClass Else If binder.OptionStrict = OptionStrict.On Then getErrorInfo = ErrorFactory.GetErrorInfo_ERR_StrictDisallowImplicitObject ElseIf binder.OptionStrict = OptionStrict.Custom Then getErrorInfo = ErrorFactory.GetErrorInfo_WRN_ObjectAssumedVar1_WRN_MissingAsClauseinVarDecl End If End If End If varType = binder.DecodeModifiedIdentifierType(modifiedIdentifierSyntax, asClauseType, asClauseOpt, initializerSyntax, getErrorInfo, diagnostics, VisualBasic.Binder.ModifiedIdentifierTypeDecoderContext.FieldType) End If Debug.Assert(varType IsNot Nothing) Return varType End Function Friend Shared Function ComputeWithEventsFieldType(propertySymbol As PropertySymbol, modifiedIdentifier As ModifiedIdentifierSyntax, binder As Binder, ignoreTypeSyntaxDiagnostics As Boolean, diagnostics As BindingDiagnosticBag) As TypeSymbol Dim varType = ComputeFieldType(modifiedIdentifier, binder, diagnostics, isConst:=False, isWithEvents:=True, ignoreTypeSyntaxDiagnostics:=ignoreTypeSyntaxDiagnostics) If Not varType.IsErrorType() Then Dim declarator = DirectCast(modifiedIdentifier.Parent, VariableDeclaratorSyntax) Dim identifier = modifiedIdentifier.Identifier ' it must be either a class or an interface or a type parameter ' with class constraints. ' and for arrays there is a special error. If varType.IsArrayType Then ' 'WithEvents' variables cannot be typed as arrays. binder.ReportDiagnostic(diagnostics, modifiedIdentifier, ERRID.ERR_EventSourceIsArray) ElseIf Not (varType.IsClassOrInterfaceType OrElse (varType.Kind = SymbolKind.TypeParameter AndAlso varType.IsReferenceType)) Then If declarator.AsClause IsNot Nothing Then Dim typeSyntax = declarator.AsClause.Type If typeSyntax IsNot Nothing Then ' 'WithEvents' variables can only be typed as classes, interfaces or type parameters with class constraints. binder.ReportDiagnostic(diagnostics, identifier, ERRID.ERR_WithEventsAsStruct) End If End If End If If declarator.AsClause IsNot Nothing Then Dim errorLocation = SourceSymbolHelpers.GetAsClauseLocation(identifier, declarator.AsClause) AccessCheck.VerifyAccessExposureForMemberType(propertySymbol, errorLocation, varType, diagnostics) End If End If Return varType End Function ''' <summary> ''' Gets the inferred type of this const field from the initialization value. ''' </summary> ''' <param name="inProgress">Used to detect dependencies between constant field values.</param><returns></returns> Friend Overrides Function GetInferredType(inProgress As ConstantFieldsInProgress) As TypeSymbol ' there are no inferred types for non const fields, simply return the type in that case If HasDeclaredType Then Return Type End If GetConstantValue(inProgress) ' if constantType is nothing it means that there was no initializer given and a diagnostic has already been issued. ' In this case we'll return System.Object which is the default type for all locals that could not infer a type. Dim constantType = GetInferredConstantType(inProgress) Debug.Assert(constantType IsNot Nothing OrElse EqualsValueOrAsNewInitOpt Is Nothing) If constantType Is Nothing Then constantType = ContainingAssembly.GetSpecialType(SpecialType.System_Object) Else ' Dev11 only allows a restricted set of types for constant fields (see IsValidTypeForConstField()). If Not constantType.IsValidTypeForConstField() Then constantType = ContainingAssembly.GetSpecialType(SpecialType.System_Object) Else ' Dev11 translates all inferred Enum constant types into their underlying types constantType = constantType.GetEnumUnderlyingTypeOrSelf End If End If Return constantType End Function Protected Overridable Function GetInferredConstantType(inProgress As ConstantFieldsInProgress) As TypeSymbol Return Nothing End Function ''' <summary> ''' A source field with an explicit initializer. In a declaration declaring multiple fields, ''' such as "Dim a, b, c = d", this class is used for the first field only. (Other fields in ''' the declaration are instances of SourceFieldSymbolSiblingInitializer.) ''' </summary> Private Class SourceFieldSymbolWithInitializer Inherits SourceMemberFieldSymbol ' reference to the initialization syntax of this field, ' can be an EqualsValue or AsNew syntax node Protected ReadOnly _equalsValueOrAsNewInit As SyntaxReference Public Sub New(container As SourceMemberContainerTypeSymbol, syntaxRef As SyntaxReference, name As String, memberFlags As SourceMemberFlags, equalsValueOrAsNewInit As SyntaxReference) MyBase.New(container, syntaxRef, name, memberFlags) Debug.Assert(equalsValueOrAsNewInit IsNot Nothing) Debug.Assert(IsConst = TypeOf Me Is SourceConstFieldSymbolWithInitializer) _equalsValueOrAsNewInit = equalsValueOrAsNewInit End Sub Friend NotOverridable Overrides ReadOnly Property EqualsValueOrAsNewInitOpt As VisualBasicSyntaxNode Get Return _equalsValueOrAsNewInit.GetVisualBasicSyntax() End Get End Property End Class Private NotInheritable Class SourceConstFieldSymbolWithInitializer Inherits SourceFieldSymbolWithInitializer ''' <summary> ''' A tuple consisting of the evaluated constant value and type ''' </summary> Private _constantTuple As EvaluatedConstant Public Sub New(container As SourceMemberContainerTypeSymbol, syntaxRef As SyntaxReference, name As String, memberFlags As SourceMemberFlags, equalsValueOrAsNewInit As SyntaxReference) MyBase.New(container, syntaxRef, name, memberFlags, equalsValueOrAsNewInit) Debug.Assert(IsConst) End Sub Protected Overrides Function GetLazyConstantTuple() As EvaluatedConstant Return _constantTuple End Function Friend Overrides Function GetConstantValue(inProgress As ConstantFieldsInProgress) As ConstantValue Return GetConstantValueImpl(inProgress) End Function Protected Overrides Function MakeConstantTuple(dependencies As ConstantFieldsInProgress.Dependencies, diagnostics As BindingDiagnosticBag) As EvaluatedConstant Return ConstantValueUtils.EvaluateFieldConstant(Me, _equalsValueOrAsNewInit, dependencies, diagnostics) End Function Protected Overrides Sub SetLazyConstantTuple(constantTuple As EvaluatedConstant, diagnostics As BindingDiagnosticBag) Debug.Assert(constantTuple IsNot Nothing) Dim sourceModule = DirectCast(Me.ContainingModule, SourceModuleSymbol) sourceModule.AtomicStoreReferenceAndDiagnostics(_constantTuple, constantTuple, diagnostics) End Sub Protected Overrides Function GetInferredConstantType(inProgress As ConstantFieldsInProgress) As TypeSymbol GetConstantValueImpl(inProgress) Dim constantTuple As EvaluatedConstant = GetLazyConstantTuple() If constantTuple IsNot Nothing Then Return constantTuple.Type End If Debug.Assert(Not inProgress.IsEmpty) Return New ErrorTypeSymbol() End Function End Class ''' <summary> ''' A source field with an explicit initializer. In a declaration declaring multiple ''' fields, such as "Dim a, b, c = d", this class is used for the fields other than ''' the first. (The first field is an instance of SourceFieldSymbolWithInitializer.) ''' An instance of this class holds a reference to the first field in the declaration ''' and reuses the bound initializer from that field. ''' </summary> Private NotInheritable Class SourceFieldSymbolSiblingInitializer Inherits SourceMemberFieldSymbol ' Sibling field symbol with common initializer (used to ' avoid binding constant initializer multiple times). Private ReadOnly _sibling As SourceMemberFieldSymbol Public Sub New(container As SourceMemberContainerTypeSymbol, syntaxRef As SyntaxReference, name As String, memberFlags As SourceMemberFlags, sibling As SourceMemberFieldSymbol) MyBase.New(container, syntaxRef, name, memberFlags) _sibling = sibling End Sub Friend Overrides ReadOnly Property EqualsValueOrAsNewInitOpt As VisualBasicSyntaxNode Get Return _sibling.EqualsValueOrAsNewInitOpt End Get End Property Friend Overrides Function GetConstantValue(inProgress As ConstantFieldsInProgress) As ConstantValue Return _sibling.GetConstantValue(inProgress) End Function Protected Overrides Function GetInferredConstantType(inProgress As ConstantFieldsInProgress) As TypeSymbol Return _sibling.GetInferredConstantType(inProgress) End Function End Class ' Create variable members, with the given, name, declarator, and declaration syntax. Friend Shared Sub Create(container As SourceMemberContainerTypeSymbol, syntax As FieldDeclarationSyntax, binder As Binder, members As SourceNamedTypeSymbol.MembersAndInitializersBuilder, ByRef staticInitializers As ArrayBuilder(Of FieldOrPropertyInitializer), ByRef instanceInitializers As ArrayBuilder(Of FieldOrPropertyInitializer), diagBag As BindingDiagnosticBag) Debug.Assert(diagBag.AccumulatesDiagnostics) ' Decode the flags. Dim validFlags = SourceMemberFlags.AllAccessibilityModifiers Or SourceMemberFlags.Dim Or SourceMemberFlags.Const Or SourceMemberFlags.Shadows Or SourceMemberFlags.Shared Dim errorId = ERRID.ERR_BadDimFlags1 If syntax.Modifiers.Any(SyntaxKind.WithEventsKeyword) Then validFlags = validFlags Or SourceMemberFlags.WithEvents errorId = ERRID.ERR_BadWithEventsFlags1 Else ' only regular fields can be readonly validFlags = validFlags Or SourceMemberFlags.ReadOnly errorId = ERRID.ERR_BadDimFlags1 End If Dim modifiers = binder.DecodeModifiers(syntax.Modifiers, validFlags, errorId, If(container.IsValueType, Accessibility.Public, Accessibility.Private), diagBag.DiagnosticBag) If container IsNot Nothing Then Select Case container.DeclarationKind Case DeclarationKind.Structure If (modifiers.FoundFlags And SourceMemberFlags.Protected) <> 0 Then binder.ReportModifierError(syntax.Modifiers, ERRID.ERR_StructCantUseVarSpecifier1, diagBag.DiagnosticBag, SyntaxKind.ProtectedKeyword) modifiers = New MemberModifiers(modifiers.FoundFlags And Not SourceMemberFlags.Protected, (modifiers.ComputedFlags And Not SourceMemberFlags.AccessibilityMask) Or SourceMemberFlags.AccessibilityPrivate) End If If (modifiers.FoundFlags And SourceMemberFlags.WithEvents) <> 0 Then binder.ReportModifierError(syntax.Modifiers, ERRID.ERR_StructCantUseVarSpecifier1, diagBag.DiagnosticBag, SyntaxKind.WithEventsKeyword) modifiers = New MemberModifiers(modifiers.FoundFlags And Not SourceMemberFlags.WithEvents, modifiers.ComputedFlags) End If Case DeclarationKind.Module ' Member variables in module are implicitly Shared, and cannot be explicitly Shared. If (modifiers.FoundFlags And SourceMemberFlags.InvalidInModule) <> 0 Then binder.ReportModifierError(syntax.Modifiers, ERRID.ERR_ModuleCantUseVariableSpecifier1, diagBag.DiagnosticBag, SyntaxKind.SharedKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.DefaultKeyword, SyntaxKind.MustOverrideKeyword, SyntaxKind.OverridableKeyword, SyntaxKind.ShadowsKeyword, SyntaxKind.OverridesKeyword, SyntaxKind.NotOverridableKeyword) End If modifiers = New MemberModifiers(modifiers.FoundFlags And Not SourceMemberFlags.InvalidInModule, modifiers.ComputedFlags Or SourceMemberFlags.Shared) End Select End If Const FlagsNotCombinableWithConst As SourceMemberFlags = SourceMemberFlags.WithEvents Or SourceMemberFlags.Shared Or SourceMemberFlags.ReadOnly Or SourceMemberFlags.Dim ' Const fields cannot be Shared or ReadOnly or WithEvents If (modifiers.FoundFlags And SourceMemberFlags.Const) <> 0 AndAlso (modifiers.FoundFlags And FlagsNotCombinableWithConst) <> 0 Then If (modifiers.FoundFlags And SourceMemberFlags.Shared) <> 0 Then binder.ReportModifierError(syntax.Modifiers, ERRID.ERR_BadConstFlags1, diagBag.DiagnosticBag, SyntaxKind.SharedKeyword) End If If (modifiers.FoundFlags And SourceMemberFlags.ReadOnly) <> 0 Then binder.ReportModifierError(syntax.Modifiers, ERRID.ERR_BadConstFlags1, diagBag.DiagnosticBag, SyntaxKind.ReadOnlyKeyword) End If If (modifiers.FoundFlags And SourceMemberFlags.WithEvents) <> 0 Then binder.ReportModifierError(syntax.Modifiers, ERRID.ERR_BadConstFlags1, diagBag.DiagnosticBag, SyntaxKind.WithEventsKeyword) End If If (modifiers.FoundFlags And SourceMemberFlags.Dim) <> 0 Then binder.ReportModifierError(syntax.Modifiers, ERRID.ERR_BadConstFlags1, diagBag.DiagnosticBag, SyntaxKind.DimKeyword) End If modifiers = New MemberModifiers(modifiers.FoundFlags And Not FlagsNotCombinableWithConst, modifiers.ComputedFlags) End If ' VB spec 9.5: const fields are implicitly shared If (modifiers.FoundFlags And SourceMemberFlags.Const) <> 0 AndAlso (modifiers.FoundFlags And SourceMemberFlags.Shared) = 0 Then modifiers = New MemberModifiers(modifiers.FoundFlags, modifiers.ComputedFlags Or SourceMemberFlags.Shared) End If Dim flags = modifiers.AllFlags For Each declarator As VariableDeclaratorSyntax In syntax.Declarators ' field declarations can only have one name (strict on & off) if they have an initialization If declarator.Names.Count > 1 AndAlso declarator.Initializer IsNot Nothing Then binder.ReportDiagnostic(diagBag, declarator, ERRID.ERR_InitWithMultipleDeclarators) End If Dim asClauseOpt = declarator.AsClause Dim initializerOpt = declarator.Initializer Dim initializerSyntax As VisualBasicSyntaxNode = Nothing If asClauseOpt IsNot Nothing AndAlso asClauseOpt.Kind = SyntaxKind.AsNewClause Then initializerSyntax = asClauseOpt Else initializerSyntax = initializerOpt End If Dim initializerOptRef = If(initializerSyntax Is Nothing, Nothing, binder.GetSyntaxReference(initializerSyntax)) #If Not ALLOW_STRUCT_INST_INITIALIZERS Then 'instance members of a structure cannot have initializations (const values are implicitly shared) If container.TypeKind = TypeKind.Structure AndAlso (flags And SourceMemberFlags.Shared) = 0 Then If initializerOpt IsNot Nothing Then binder.ReportDiagnostic(diagBag, If(declarator.Names.Count > 0, declarator.Names.Last, DirectCast(declarator, VisualBasicSyntaxNode)), ERRID.ERR_InitializerInStruct) ElseIf asClauseOpt IsNot Nothing AndAlso asClauseOpt.Kind = SyntaxKind.AsNewClause Then binder.ReportDiagnostic(diagBag, DirectCast(asClauseOpt, AsNewClauseSyntax).NewExpression.NewKeyword, ERRID.ERR_SharedStructMemberCannotSpecifyNew) End If End If #End If Dim nameCount = declarator.Names.Count Dim fieldOrWithEventSymbols(nameCount - 1) As Symbol ' even if a declarator has multiple names, treat them all as legal and report issues for all of them ' this is what Dev10 does. For nameIndex = 0 To nameCount - 1 Dim perFieldFlags As SourceMemberFlags = flags If nameIndex = 0 Then perFieldFlags = perFieldFlags Or SourceMemberFlags.FirstFieldDeclarationOfType End If Dim modifiedIdentifier = declarator.Names(nameIndex) Dim identifier = modifiedIdentifier.Identifier Dim omitFurtherDiagnostics As Boolean = String.IsNullOrEmpty(modifiedIdentifier.Identifier.ValueText) If (modifiers.FoundFlags And SourceMemberFlags.Const) <> 0 AndAlso identifier.GetTypeCharacter() = TypeCharacter.None AndAlso modifiedIdentifier.Nullable.Node Is Nothing AndAlso modifiedIdentifier.ArrayBounds Is Nothing AndAlso modifiedIdentifier.ArrayRankSpecifiers.IsEmpty Then ' Fields have inferred type if they have no type character and no As clause, ?, array bounds, or only "As Object" (and the Object must ' be the actual token "Object", not a synonym like "System.Object") Dim simpleAsClauseSyntax = TryCast(asClauseOpt, SimpleAsClauseSyntax) If simpleAsClauseSyntax Is Nothing OrElse (simpleAsClauseSyntax.Type.Kind = SyntaxKind.PredefinedType AndAlso DirectCast(simpleAsClauseSyntax.Type, PredefinedTypeSyntax).Keyword.Kind = SyntaxKind.ObjectKeyword) Then perFieldFlags = perFieldFlags Or SourceMemberFlags.InferredFieldType End If End If Dim modifiedIdentifierRef = binder.GetSyntaxReference(modifiedIdentifier) ' regular field or WithEvents property? If (modifiers.FoundFlags And SourceMemberFlags.WithEvents) = 0 Then Dim fieldSymbol As SourceFieldSymbol If initializerOptRef Is Nothing Then fieldSymbol = New SourceMemberFieldSymbol( container, modifiedIdentifierRef, identifier.ValueText, perFieldFlags) ElseIf nameIndex = 0 Then If (perFieldFlags And SourceMemberFlags.Const) <> 0 Then fieldSymbol = New SourceConstFieldSymbolWithInitializer( container, modifiedIdentifierRef, identifier.ValueText, perFieldFlags, initializerOptRef) Else fieldSymbol = New SourceFieldSymbolWithInitializer( container, modifiedIdentifierRef, identifier.ValueText, perFieldFlags, initializerOptRef) End If Else fieldSymbol = New SourceFieldSymbolSiblingInitializer( container, modifiedIdentifierRef, identifier.ValueText, perFieldFlags, DirectCast(fieldOrWithEventSymbols(0), SourceMemberFieldSymbol)) End If fieldOrWithEventSymbols(nameIndex) = fieldSymbol If syntax.AttributeLists.Count = 0 Then fieldSymbol.SetCustomAttributeData(CustomAttributesBag(Of VisualBasicAttributeData).Empty) End If If (modifiedIdentifier.ArrayBounds IsNot Nothing) AndAlso (modifiedIdentifier.ArrayBounds.Arguments.Count > 0) Then If container.IsStructureType AndAlso Not fieldSymbol.IsShared Then ' Arrays declared as structure members cannot be declared with an initial size. binder.ReportDiagnostic(diagBag, modifiedIdentifier, ERRID.ERR_ArrayInitInStruct) Else If initializerOpt Is Nothing Then ' Array declaration with implicit initializer. Dim initializer = Function(precedingInitializersLength As Integer) Return New FieldOrPropertyInitializer(fieldSymbol, modifiedIdentifierRef, precedingInitializersLength) End Function If fieldSymbol.IsShared Then SourceNamedTypeSymbol.AddInitializer(staticInitializers, initializer, members.StaticSyntaxLength) Else SourceNamedTypeSymbol.AddInitializer(instanceInitializers, initializer, members.InstanceSyntaxLength) End If Else ' Array declaration with implicit and explicit initializers. binder.ReportDiagnostic(diagBag, modifiedIdentifier, ERRID.ERR_InitWithExplicitArraySizes) End If End If End If container.AddMember(fieldSymbol, binder, members, omitFurtherDiagnostics) Else Dim propertySymbol = SourcePropertySymbol.CreateWithEvents(container, binder, identifier, modifiedIdentifierRef, modifiers, nameIndex = 0, diagBag) fieldOrWithEventSymbols(nameIndex) = propertySymbol container.AddMember(propertySymbol, binder, members, omitFurtherDiagnostics) container.AddMember(propertySymbol.GetMethod, binder, members, omitDiagnostics:=False) container.AddMember(propertySymbol.SetMethod, binder, members, omitDiagnostics:=False) container.AddMember(propertySymbol.AssociatedField, binder, members, omitDiagnostics:=False) End If Next If initializerOptRef IsNot Nothing Then Dim initializer = Function(precedingInitializersLength As Integer) Return New FieldOrPropertyInitializer(fieldOrWithEventSymbols.AsImmutableOrNull, initializerOptRef, precedingInitializersLength) End Function ' all symbols are the same regarding the sharedness Dim symbolsAreShared = nameCount > 0 AndAlso fieldOrWithEventSymbols(0).IsShared If symbolsAreShared Then ' const fields are implicitly shared and get into this list. SourceNamedTypeSymbol.AddInitializer(staticInitializers, initializer, members.StaticSyntaxLength) Else SourceNamedTypeSymbol.AddInitializer(instanceInitializers, initializer, members.InstanceSyntaxLength) End If End If Next End Sub End Class End Namespace