Friend Shared Sub Create()

in src/Compilers/VisualBasic/Portable/Symbols/Source/SourceMemberFieldSymbol.vb [370:631]


        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 DiagnosticBag)

            

            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
                
                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)

            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, 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, SyntaxKind.WithEventsKeyword)
                            modifiers = New MemberModifiers(modifiers.FoundFlags And Not SourceMemberFlags.WithEvents, modifiers.ComputedFlags)
                        End If

                    Case DeclarationKind.Module
                        
                        If (modifiers.FoundFlags And SourceMemberFlags.InvalidInModule) <> 0 Then
                            binder.ReportModifierError(syntax.Modifiers, ERRID.ERR_ModuleCantUseVariableSpecifier1, diagBag,
                                                       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

            
            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, SyntaxKind.SharedKeyword)
                End If

                If (modifiers.FoundFlags And SourceMemberFlags.ReadOnly) <> 0 Then
                    binder.ReportModifierError(syntax.Modifiers, ERRID.ERR_BadConstFlags1, diagBag, SyntaxKind.ReadOnlyKeyword)
                End If

                If (modifiers.FoundFlags And SourceMemberFlags.WithEvents) <> 0 Then
                    binder.ReportModifierError(syntax.Modifiers, ERRID.ERR_BadConstFlags1, diagBag, SyntaxKind.WithEventsKeyword)
                End If

                If (modifiers.FoundFlags And SourceMemberFlags.Dim) <> 0 Then
                    binder.ReportModifierError(syntax.Modifiers, ERRID.ERR_BadConstFlags1, diagBag, SyntaxKind.DimKeyword)
                End If

                modifiers = New MemberModifiers(modifiers.FoundFlags And Not FlagsNotCombinableWithConst,
                                                modifiers.ComputedFlags)
            End If

            
            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
                
                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
                
                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
                
                

                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
                        
                        
                        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)

                    
                    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
                            fieldSymbol = New SourceFieldSymbolWithInitializer(
                                container,
                                modifiedIdentifierRef,
                                identifier.ValueText,
                                perFieldFlags,
                                initializerOptRef)
                        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
                                
                                binder.ReportDiagnostic(diagBag, modifiedIdentifier, ERRID.ERR_ArrayInitInStruct)

                            Else
                                If initializerOpt Is Nothing Then
                                    
                                    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
                                    
                                    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

                    
                    Dim symbolsAreShared = nameCount > 0 AndAlso fieldOrWithEventSymbols(0).IsShared

                    If symbolsAreShared Then
                        
                        SourceNamedTypeSymbol.AddInitializer(staticInitializers, initializer, members.StaticSyntaxLength)
                    Else
                        SourceNamedTypeSymbol.AddInitializer(instanceInitializers, initializer, members.InstanceSyntaxLength)
                    End If
                End If
            Next
        End Sub