private void AddNonTypeMembers()

in src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs [2928:3280]


        private void AddNonTypeMembers(
            MembersAndInitializersBuilder builder,
            SyntaxList<MemberDeclarationSyntax> members,
            DiagnosticBag diagnostics)
        {
            if (members.Count == 0)
            {
                return;
            }

            var firstMember = members[0];
            var bodyBinder = this.GetBinder(firstMember);

            ArrayBuilder<FieldOrPropertyInitializer> staticInitializers = null;
            ArrayBuilder<FieldOrPropertyInitializer> instanceInitializers = null;

            foreach (var m in members)
            {
                if (_lazyMembersAndInitializers != null)
                {
                    // membersAndInitializers is already computed. no point to continue.
                    return;
                }

                bool reportMisplacedGlobalCode = !m.HasErrors;

                switch (m.Kind())
                {
                    case SyntaxKind.FieldDeclaration:
                        {
                            var fieldSyntax = (FieldDeclarationSyntax)m;
                            if (IsImplicitClass && reportMisplacedGlobalCode)
                            {
                                diagnostics.Add(ErrorCode.ERR_NamespaceUnexpected,
                                    new SourceLocation(fieldSyntax.Declaration.Variables.First().Identifier));
                            }

                            bool modifierErrors;
                            var modifiers = SourceMemberFieldSymbol.MakeModifiers(this, fieldSyntax.Declaration.Variables[0].Identifier, fieldSyntax.Modifiers, diagnostics, out modifierErrors);
                            foreach (var variable in fieldSyntax.Declaration.Variables)
                            {
                                var fieldSymbol = (modifiers & DeclarationModifiers.Fixed) == 0
                                    ? new SourceMemberFieldSymbolFromDeclarator(this, variable, modifiers, modifierErrors, diagnostics)
                                    : new SourceFixedFieldSymbol(this, variable, modifiers, modifierErrors, diagnostics);
                                builder.NonTypeNonIndexerMembers.Add(fieldSymbol);

                                if (IsScriptClass)
                                {
                                    // also gather expression-declared variables from the bracketed argument lists and the initializers
                                    ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeNonIndexerMembers, variable, this,
                                                            DeclarationModifiers.Private | (modifiers & DeclarationModifiers.Static),
                                                            fieldSymbol);
                                }

                                if (variable.Initializer != null)
                                {
                                    if (fieldSymbol.IsStatic)
                                    {
                                        AddInitializer(ref staticInitializers, ref builder.StaticSyntaxLength, fieldSymbol, variable.Initializer);
                                    }
                                    else
                                    {
                                        AddInitializer(ref instanceInitializers, ref builder.InstanceSyntaxLength, fieldSymbol, variable.Initializer);
                                    }
                                }
                            }
                        }
                        break;

                    case SyntaxKind.MethodDeclaration:
                        {
                            var methodSyntax = (MethodDeclarationSyntax)m;
                            if (IsImplicitClass && reportMisplacedGlobalCode)
                            {
                                diagnostics.Add(ErrorCode.ERR_NamespaceUnexpected,
                                    new SourceLocation(methodSyntax.Identifier));
                            }

                            var method = SourceOrdinaryMethodSymbol.CreateMethodSymbol(this, bodyBinder, methodSyntax, diagnostics);
                            builder.NonTypeNonIndexerMembers.Add(method);
                        }
                        break;

                    case SyntaxKind.ConstructorDeclaration:
                        {
                            var constructorSyntax = (ConstructorDeclarationSyntax)m;
                            if (IsImplicitClass && reportMisplacedGlobalCode)
                            {
                                diagnostics.Add(ErrorCode.ERR_NamespaceUnexpected,
                                    new SourceLocation(constructorSyntax.Identifier));
                            }

                            var constructor = SourceConstructorSymbol.CreateConstructorSymbol(this, constructorSyntax, diagnostics);
                            builder.NonTypeNonIndexerMembers.Add(constructor);
                        }
                        break;

                    case SyntaxKind.DestructorDeclaration:
                        {
                            var destructorSyntax = (DestructorDeclarationSyntax)m;
                            if (IsImplicitClass && reportMisplacedGlobalCode)
                            {
                                diagnostics.Add(ErrorCode.ERR_NamespaceUnexpected,
                                    new SourceLocation(destructorSyntax.Identifier));
                            }

                            // CONSIDER: if this doesn't (directly or indirectly) override object.Finalize, the
                            // runtime won't consider it a finalizer and it will not be marked as a destructor
                            // when it is loaded from metadata.  Perhaps we should just treat it as an Ordinary
                            // method in such cases?
                            var destructor = new SourceDestructorSymbol(this, destructorSyntax, diagnostics);
                            builder.NonTypeNonIndexerMembers.Add(destructor);
                        }
                        break;

                    case SyntaxKind.PropertyDeclaration:
                        {
                            var propertySyntax = (PropertyDeclarationSyntax)m;
                            if (IsImplicitClass && reportMisplacedGlobalCode)
                            {
                                diagnostics.Add(ErrorCode.ERR_NamespaceUnexpected,
                                    new SourceLocation(propertySyntax.Identifier));
                            }

                            var property = SourcePropertySymbol.Create(this, bodyBinder, propertySyntax, diagnostics);
                            builder.NonTypeNonIndexerMembers.Add(property);

                            AddAccessorIfAvailable(builder.NonTypeNonIndexerMembers, property.GetMethod, diagnostics);
                            AddAccessorIfAvailable(builder.NonTypeNonIndexerMembers, property.SetMethod, diagnostics);
                            FieldSymbol backingField = property.BackingField;

                            // TODO: can we leave this out of the member list?
                            // From the 10/12/11 design notes:
                            //   In addition, we will change autoproperties to behavior in 
                            //   a similar manner and make the autoproperty fields private.
                            if ((object)backingField != null)
                            {
                                builder.NonTypeNonIndexerMembers.Add(backingField);

                                var initializer = propertySyntax.Initializer;
                                if (initializer != null)
                                {
                                    if (IsScriptClass)
                                    {
                                        // also gather expression-declared variables from the initializer
                                        ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeNonIndexerMembers,
                                                                                      initializer,
                                                                                      this,
                                                                                      DeclarationModifiers.Private | (property.IsStatic ? DeclarationModifiers.Static : 0),
                                                                                      backingField);
                                    }

                                    if (property.IsStatic)
                                    {
                                        AddInitializer(ref staticInitializers, ref builder.StaticSyntaxLength, backingField, initializer);
                                    }
                                    else
                                    {
                                        AddInitializer(ref instanceInitializers, ref builder.InstanceSyntaxLength, backingField, initializer);
                                    }
                                }
                            }
                        }
                        break;

                    case SyntaxKind.EventFieldDeclaration:
                        {
                            var eventFieldSyntax = (EventFieldDeclarationSyntax)m;
                            if (IsImplicitClass && reportMisplacedGlobalCode)
                            {
                                diagnostics.Add(
                                    ErrorCode.ERR_NamespaceUnexpected,
                                    new SourceLocation(eventFieldSyntax.Declaration.Variables.First().Identifier));
                            }

                            foreach (VariableDeclaratorSyntax declarator in eventFieldSyntax.Declaration.Variables)
                            {
                                SourceFieldLikeEventSymbol @event = new SourceFieldLikeEventSymbol(this, bodyBinder, eventFieldSyntax.Modifiers, declarator, diagnostics);
                                builder.NonTypeNonIndexerMembers.Add(@event);

                                FieldSymbol associatedField = @event.AssociatedField;

                                if (IsScriptClass)
                                {
                                    // also gather expression-declared variables from the bracketed argument lists and the initializers
                                    ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeNonIndexerMembers, declarator, this,
                                                            DeclarationModifiers.Private | (@event.IsStatic ? DeclarationModifiers.Static : 0),
                                                            associatedField);
                                }

                                if ((object)associatedField != null)
                                {
                                    // NOTE: specifically don't add the associated field to the members list
                                    // (regard it as an implementation detail).

                                    if (declarator.Initializer != null)
                                    {
                                        if (associatedField.IsStatic)
                                        {
                                            AddInitializer(ref staticInitializers, ref builder.StaticSyntaxLength, associatedField, declarator.Initializer);
                                        }
                                        else
                                        {
                                            AddInitializer(ref instanceInitializers, ref builder.InstanceSyntaxLength, associatedField, declarator.Initializer);
                                        }
                                    }
                                }

                                Debug.Assert((object)@event.AddMethod != null);
                                Debug.Assert((object)@event.RemoveMethod != null);

                                AddAccessorIfAvailable(builder.NonTypeNonIndexerMembers, @event.AddMethod, diagnostics);
                                AddAccessorIfAvailable(builder.NonTypeNonIndexerMembers, @event.RemoveMethod, diagnostics);
                            }
                        }
                        break;

                    case SyntaxKind.EventDeclaration:
                        {
                            var eventSyntax = (EventDeclarationSyntax)m;
                            if (IsImplicitClass && reportMisplacedGlobalCode)
                            {
                                diagnostics.Add(ErrorCode.ERR_NamespaceUnexpected,
                                    new SourceLocation(eventSyntax.Identifier));
                            }

                            var @event = new SourceCustomEventSymbol(this, bodyBinder, eventSyntax, diagnostics);

                            builder.NonTypeNonIndexerMembers.Add(@event);

                            AddAccessorIfAvailable(builder.NonTypeNonIndexerMembers, @event.AddMethod, diagnostics);
                            AddAccessorIfAvailable(builder.NonTypeNonIndexerMembers, @event.RemoveMethod, diagnostics);

                            Debug.Assert((object)@event.AssociatedField == null);
                        }
                        break;

                    case SyntaxKind.IndexerDeclaration:
                        {
                            var indexerSyntax = (IndexerDeclarationSyntax)m;
                            if (IsImplicitClass && reportMisplacedGlobalCode)
                            {
                                diagnostics.Add(ErrorCode.ERR_NamespaceUnexpected,
                                    new SourceLocation(indexerSyntax.ThisKeyword));
                            }

                            // We can't create the indexer symbol yet, because we don't know
                            // what name it will have after attribute binding (because of
                            // IndexerNameAttribute).  Instead, we'll keep a (weak) reference
                            // to the syntax and bind it again after early attribute decoding.
                            builder.IndexerDeclarations.Add(indexerSyntax.GetReference());
                        }
                        break;

                    case SyntaxKind.ConversionOperatorDeclaration:
                        {
                            var conversionOperatorSyntax = (ConversionOperatorDeclarationSyntax)m;
                            if (IsImplicitClass && reportMisplacedGlobalCode)
                            {
                                diagnostics.Add(ErrorCode.ERR_NamespaceUnexpected,
                                    new SourceLocation(conversionOperatorSyntax.OperatorKeyword));
                            }

                            var method = SourceUserDefinedConversionSymbol.CreateUserDefinedConversionSymbol
                                (this, conversionOperatorSyntax, diagnostics);
                            builder.NonTypeNonIndexerMembers.Add(method);
                        }
                        break;

                    case SyntaxKind.OperatorDeclaration:
                        {
                            var operatorSyntax = (OperatorDeclarationSyntax)m;
                            if (IsImplicitClass && reportMisplacedGlobalCode)
                            {
                                diagnostics.Add(ErrorCode.ERR_NamespaceUnexpected,
                                    new SourceLocation(operatorSyntax.OperatorKeyword));
                            }

                            var method = SourceUserDefinedOperatorSymbol.CreateUserDefinedOperatorSymbol
                                (this, operatorSyntax, diagnostics);
                            builder.NonTypeNonIndexerMembers.Add(method);
                        }

                        break;

                    case SyntaxKind.GlobalStatement:
                        {
                            var globalStatement = ((GlobalStatementSyntax)m).Statement;

                            if (IsScriptClass)
                            {
                                var innerStatement = globalStatement;

                                // drill into any LabeledStatements 
                                while (innerStatement.Kind() == SyntaxKind.LabeledStatement)
                                {
                                    innerStatement = ((LabeledStatementSyntax)innerStatement).Statement;
                                }

                                switch (innerStatement.Kind())
                                {
                                    case SyntaxKind.LocalDeclarationStatement:
                                        // We shouldn't reach this place, but field declarations preceded with a label end up here.
                                        // This is tracked by https://github.com/dotnet/roslyn/issues/13712. Let's do our best for now.
                                        var decl = (LocalDeclarationStatementSyntax)innerStatement;
                                        foreach (var vdecl in decl.Declaration.Variables)
                                        {
                                            // also gather expression-declared variables from the bracketed argument lists and the initializers
                                            ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeNonIndexerMembers, vdecl, this, DeclarationModifiers.Private,
                                                                                          containingFieldOpt: null);
                                        }
                                        break;

                                    case SyntaxKind.ExpressionStatement:
                                    case SyntaxKind.IfStatement:
                                    case SyntaxKind.YieldReturnStatement:
                                    case SyntaxKind.ReturnStatement:
                                    case SyntaxKind.ThrowStatement:
                                    case SyntaxKind.SwitchStatement:
                                    case SyntaxKind.LockStatement:
                                        ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeNonIndexerMembers,
                                                  innerStatement,
                                                  this,
                                                  DeclarationModifiers.Private,
                                                  containingFieldOpt: null);
                                        break;

                                    default:
                                        // no other statement introduces variables into the enclosing scope
                                        break;
                                }

                                AddInitializer(ref instanceInitializers, ref builder.InstanceSyntaxLength, null, globalStatement);
                            }
                            else if (reportMisplacedGlobalCode)
                            {
                                diagnostics.Add(ErrorCode.ERR_GlobalStatement, new SourceLocation(globalStatement));
                            }
                        }
                        break;

                    default:
                        Debug.Assert(
                            SyntaxFacts.IsTypeDeclaration(m.Kind()) ||
                            m.Kind() == SyntaxKind.NamespaceDeclaration ||
                            m.Kind() == SyntaxKind.IncompleteMember);
                        break;
                }
            }

            AddInitializers(builder.InstanceInitializers, instanceInitializers);
            AddInitializers(builder.StaticInitializers, staticInitializers);
        }