예제 #1
0
        /// <summary>
        /// Generate a thread-safe accessor for a regular field-like event.
        ///
        /// DelegateType tmp0 = _event; //backing field
        /// DelegateType tmp1;
        /// DelegateType tmp2;
        /// do {
        ///     tmp1 = tmp0;
        ///     tmp2 = (DelegateType)Delegate.Combine(tmp1, value); //Remove for -=
        ///     tmp0 = Interlocked.CompareExchange&lt;DelegateType&gt;(ref _event, tmp2, tmp1);
        /// } while ((object)tmp0 != (object)tmp1);
        /// </summary>
        internal static BoundBlock ConstructFieldLikeEventAccessorBody_Regular(SourceEventSymbol eventSymbol, bool isAddMethod, CSharpCompilation compilation, DiagnosticBag diagnostics)
        {
            CSharpSyntaxNode syntax = eventSymbol.CSharpSyntaxNode;

            TypeSymbol      delegateType  = eventSymbol.Type;
            MethodSymbol    accessor      = isAddMethod ? eventSymbol.AddMethod : eventSymbol.RemoveMethod;
            ParameterSymbol thisParameter = accessor.ThisParameter;

            TypeSymbol   boolType              = compilation.GetSpecialType(SpecialType.System_Boolean);
            MethodSymbol updateMethod          = (MethodSymbol)compilation.GetSpecialTypeMember(isAddMethod ? SpecialMember.System_Delegate__Combine : SpecialMember.System_Delegate__Remove);
            MethodSymbol compareExchangeMethod = GetConstructedCompareExchangeMethod(delegateType, compilation, accessor.Locations[0], diagnostics);

            if ((object)compareExchangeMethod == null)
            {
                return(new BoundBlock(syntax,
                                      locals: ImmutableArray <LocalSymbol> .Empty,
                                      statements: ImmutableArray.Create <BoundStatement>(
                                          new BoundReturnStatement(syntax,
                                                                   expressionOpt: null)
                {
                    WasCompilerGenerated = true
                }))
                {
                    WasCompilerGenerated = true
                });
            }

            GeneratedLabelSymbol loopLabel = new GeneratedLabelSymbol("loop");

            const int numTemps = 3;

            LocalSymbol[] tmps      = new LocalSymbol[numTemps];
            BoundLocal[]  boundTmps = new BoundLocal[numTemps];

            for (int i = 0; i < numTemps; i++)
            {
                tmps[i]      = new SynthesizedLocal(accessor, delegateType, SynthesizedLocalKind.LoweringTemp);
                boundTmps[i] = new BoundLocal(syntax, tmps[i], null, delegateType);
            }

            BoundThisReference fieldReceiver = eventSymbol.IsStatic ?
                                               null :
                                               new BoundThisReference(syntax, thisParameter.Type)
            {
                WasCompilerGenerated = true
            };

            BoundFieldAccess boundBackingField = new BoundFieldAccess(syntax,
                                                                      receiver: fieldReceiver,
                                                                      fieldSymbol: eventSymbol.AssociatedField,
                                                                      constantValueOpt: null)
            {
                WasCompilerGenerated = true
            };

            BoundParameter boundParameter = new BoundParameter(syntax,
                                                               parameterSymbol: accessor.Parameters[0])
            {
                WasCompilerGenerated = true
            };

            // tmp0 = _event;
            BoundStatement tmp0Init = new BoundExpressionStatement(syntax,
                                                                   expression: new BoundAssignmentOperator(syntax,
                                                                                                           left: boundTmps[0],
                                                                                                           right: boundBackingField,
                                                                                                           type: delegateType)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            };

            // LOOP:
            BoundStatement loopStart = new BoundLabelStatement(syntax,
                                                               label: loopLabel)
            {
                WasCompilerGenerated = true
            };

            // tmp1 = tmp0;
            BoundStatement tmp1Update = new BoundExpressionStatement(syntax,
                                                                     expression: new BoundAssignmentOperator(syntax,
                                                                                                             left: boundTmps[1],
                                                                                                             right: boundTmps[0],
                                                                                                             type: delegateType)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            };

            // (DelegateType)Delegate.Combine(tmp1, value)
            BoundExpression delegateUpdate = BoundConversion.SynthesizedNonUserDefined(syntax,
                                                                                       operand: BoundCall.Synthesized(syntax,
                                                                                                                      receiverOpt: null,
                                                                                                                      method: updateMethod,
                                                                                                                      arguments: ImmutableArray.Create <BoundExpression>(boundTmps[1], boundParameter)),
                                                                                       kind: ConversionKind.ExplicitReference,
                                                                                       type: delegateType);

            // tmp2 = (DelegateType)Delegate.Combine(tmp1, value);
            BoundStatement tmp2Update = new BoundExpressionStatement(syntax,
                                                                     expression: new BoundAssignmentOperator(syntax,
                                                                                                             left: boundTmps[2],
                                                                                                             right: delegateUpdate,
                                                                                                             type: delegateType)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            };

            // Interlocked.CompareExchange<DelegateType>(ref _event, tmp2, tmp1)
            BoundExpression compareExchange = BoundCall.Synthesized(syntax,
                                                                    receiverOpt: null,
                                                                    method: compareExchangeMethod,
                                                                    arguments: ImmutableArray.Create <BoundExpression>(boundBackingField, boundTmps[2], boundTmps[1]));

            // tmp0 = Interlocked.CompareExchange<DelegateType>(ref _event, tmp2, tmp1);
            BoundStatement tmp0Update = new BoundExpressionStatement(syntax,
                                                                     expression: new BoundAssignmentOperator(syntax,
                                                                                                             left: boundTmps[0],
                                                                                                             right: compareExchange,
                                                                                                             type: delegateType)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            };

            // tmp0 == tmp1 // i.e. exit when they are equal, jump to start otherwise
            BoundExpression loopExitCondition = new BoundBinaryOperator(syntax,
                                                                        operatorKind: BinaryOperatorKind.ObjectEqual,
                                                                        left: boundTmps[0],
                                                                        right: boundTmps[1],
                                                                        constantValueOpt: null,
                                                                        methodOpt: null,
                                                                        resultKind: LookupResultKind.Viable,
                                                                        type: boolType)
            {
                WasCompilerGenerated = true
            };

            // branchfalse (tmp0 == tmp1) LOOP
            BoundStatement loopEnd = new BoundConditionalGoto(syntax,
                                                              condition: loopExitCondition,
                                                              jumpIfTrue: false,
                                                              label: loopLabel)
            {
                WasCompilerGenerated = true
            };

            BoundStatement @return = new BoundReturnStatement(syntax,
                                                              expressionOpt: null)
            {
                WasCompilerGenerated = true
            };

            return(new BoundBlock(syntax,
                                  locals: tmps.AsImmutable(),
                                  statements: ImmutableArray.Create <BoundStatement>(
                                      tmp0Init,
                                      loopStart,
                                      tmp1Update,
                                      tmp2Update,
                                      tmp0Update,
                                      loopEnd,
                                      @return))
            {
                WasCompilerGenerated = true
            });
        }
예제 #2
0
        /// <summary>
        /// Generate a thread-safe accessor for a WinRT field-like event.
        ///
        /// Add:
        ///   return EventRegistrationTokenTable&lt;Event&gt;.GetOrCreateEventRegistrationTokenTable(ref _tokenTable).AddEventHandler(value);
        ///
        /// Remove:
        ///   EventRegistrationTokenTable&lt;Event&gt;.GetOrCreateEventRegistrationTokenTable(ref _tokenTable).RemoveEventHandler(value);
        /// </summary>
        internal static BoundBlock ConstructFieldLikeEventAccessorBody_WinRT(SourceEventSymbol eventSymbol, bool isAddMethod, CSharpCompilation compilation, DiagnosticBag diagnostics)
        {
            CSharpSyntaxNode syntax = eventSymbol.CSharpSyntaxNode;

            MethodSymbol accessor = isAddMethod ? eventSymbol.AddMethod : eventSymbol.RemoveMethod;

            Debug.Assert((object)accessor != null);

            FieldSymbol field = eventSymbol.AssociatedField;

            Debug.Assert((object)field != null);

            NamedTypeSymbol fieldType = (NamedTypeSymbol)field.Type;

            Debug.Assert(fieldType.Name == "EventRegistrationTokenTable");

            MethodSymbol getOrCreateMethod = (MethodSymbol)Binder.GetWellKnownTypeMember(
                compilation,
                WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationTokenTable_T__GetOrCreateEventRegistrationTokenTable,
                diagnostics,
                syntax: syntax);

            if ((object)getOrCreateMethod == null)
            {
                Debug.Assert(diagnostics.HasAnyErrors());
                return(null);
            }

            getOrCreateMethod = getOrCreateMethod.AsMember(fieldType);

            WellKnownMember processHandlerMember = isAddMethod
                ? WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationTokenTable_T__AddEventHandler
                : WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationTokenTable_T__RemoveEventHandler;

            MethodSymbol processHandlerMethod = (MethodSymbol)Binder.GetWellKnownTypeMember(
                compilation,
                processHandlerMember,
                diagnostics,
                syntax: syntax);

            if ((object)processHandlerMethod == null)
            {
                Debug.Assert(diagnostics.HasAnyErrors());
                return(null);
            }

            processHandlerMethod = processHandlerMethod.AsMember(fieldType);

            // _tokenTable
            BoundFieldAccess fieldAccess = new BoundFieldAccess(
                syntax,
                field.IsStatic ? null : new BoundThisReference(syntax, accessor.ThisParameter.Type),
                field,
                constantValueOpt: null)
            {
                WasCompilerGenerated = true
            };

            // EventRegistrationTokenTable<Event>.GetOrCreateEventRegistrationTokenTable(ref _tokenTable)
            BoundCall getOrCreateCall = BoundCall.Synthesized(
                syntax,
                receiverOpt: null,
                method: getOrCreateMethod,
                arg0: fieldAccess);

            // value
            BoundParameter parameterAccess = new BoundParameter(
                syntax,
                accessor.Parameters.Single());

            // EventRegistrationTokenTable<Event>.GetOrCreateEventRegistrationTokenTable(ref _tokenTable).AddHandler(value) // or RemoveHandler
            BoundCall processHandlerCall = BoundCall.Synthesized(
                syntax,
                receiverOpt: getOrCreateCall,
                method: processHandlerMethod,
                arg0: parameterAccess);

            if (isAddMethod)
            {
                // {
                //     return EventRegistrationTokenTable<Event>.GetOrCreateEventRegistrationTokenTable(ref _tokenTable).AddHandler(value);
                // }
                BoundStatement returnStatement = BoundReturnStatement.Synthesized(syntax, processHandlerCall);
                return(BoundBlock.SynthesizedNoLocals(syntax, returnStatement));
            }
            else
            {
                // {
                //     EventRegistrationTokenTable<Event>.GetOrCreateEventRegistrationTokenTable(ref _tokenTable).RemoveHandler(value);
                //     return;
                // }
                BoundStatement callStatement   = new BoundExpressionStatement(syntax, processHandlerCall);
                BoundStatement returnStatement = new BoundReturnStatement(syntax, expressionOpt: null);
                return(BoundBlock.SynthesizedNoLocals(syntax, callStatement, returnStatement));
            }
        }
예제 #3
0
 /// <summary>
 /// Generate an accessor for a field-like event.
 /// </summary>
 internal static BoundBlock ConstructFieldLikeEventAccessorBody(SourceEventSymbol eventSymbol, bool isAddMethod, CSharpCompilation compilation, DiagnosticBag diagnostics)
 {
     Debug.Assert(eventSymbol.HasAssociatedField);
     return(ConstructFieldLikeEventAccessorBody_Regular(eventSymbol, isAddMethod, compilation, diagnostics));
 }
        /// <summary>
        /// Generate a thread-safe accessor for a regular field-like event.
        ///
        /// DelegateType tmp0 = _event; //backing field
        /// DelegateType tmp1;
        /// DelegateType tmp2;
        /// do {
        ///     tmp1 = tmp0;
        ///     tmp2 = (DelegateType)Delegate.Combine(tmp1, value); //Remove for -=
        ///     tmp0 = Interlocked.CompareExchange&lt;DelegateType&gt;(ref _event, tmp2, tmp1);
        /// } while ((object)tmp0 != (object)tmp1);
        ///
        /// Note, if System.Threading.Interlocked.CompareExchange&lt;T&gt; is not available,
        /// we emit the following code and mark the method Synchronized (unless it is a struct).
        ///
        /// _event = (DelegateType)Delegate.Combine(_event, value); //Remove for -=
        ///
        /// </summary>
        internal static BoundBlock ConstructFieldLikeEventAccessorBody_Regular(SourceEventSymbol eventSymbol, bool isAddMethod, CSharpCompilation compilation, DiagnosticBag diagnostics)
        {
            CSharpSyntaxNode syntax = eventSymbol.CSharpSyntaxNode;

            TypeSymbol      delegateType  = eventSymbol.Type;
            MethodSymbol    accessor      = isAddMethod ? eventSymbol.AddMethod : eventSymbol.RemoveMethod;
            ParameterSymbol thisParameter = accessor.ThisParameter;

            TypeSymbol boolType = compilation.GetSpecialType(SpecialType.System_Boolean);

            SpecialMember updateMethodId = isAddMethod ? SpecialMember.System_Delegate__Combine : SpecialMember.System_Delegate__Remove;
            MethodSymbol  updateMethod   = (MethodSymbol)compilation.GetSpecialTypeMember(updateMethodId);

            BoundStatement @return = new BoundReturnStatement(syntax,
                                                              refKind: RefKind.None,
                                                              expressionOpt: null)
            {
                WasCompilerGenerated = true
            };

            if (updateMethod == null)
            {
                MemberDescriptor memberDescriptor = SpecialMembers.GetDescriptor(updateMethodId);
                diagnostics.Add(new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_MissingPredefinedMember,
                                                                      memberDescriptor.DeclaringTypeMetadataName,
                                                                      memberDescriptor.Name),
                                                 syntax.Location));

                return(BoundBlock.SynthesizedNoLocals(syntax, @return));
            }

            Binder.ReportUseSiteDiagnostics(updateMethod, diagnostics, syntax);

            BoundThisReference fieldReceiver = eventSymbol.IsStatic ?
                                               null :
                                               new BoundThisReference(syntax, thisParameter.Type)
            {
                WasCompilerGenerated = true
            };

            BoundFieldAccess boundBackingField = new BoundFieldAccess(syntax,
                                                                      receiver: fieldReceiver,
                                                                      fieldSymbol: eventSymbol.AssociatedField,
                                                                      constantValueOpt: null)
            {
                WasCompilerGenerated = true
            };

            BoundParameter boundParameter = new BoundParameter(syntax,
                                                               parameterSymbol: accessor.Parameters[0])
            {
                WasCompilerGenerated = true
            };

            BoundExpression delegateUpdate;

            MethodSymbol compareExchangeMethod = (MethodSymbol)compilation.GetWellKnownTypeMember(WellKnownMember.System_Threading_Interlocked__CompareExchange_T);

            if ((object)compareExchangeMethod == null)
            {
                // (DelegateType)Delegate.Combine(_event, value)
                delegateUpdate = BoundConversion.SynthesizedNonUserDefined(syntax,
                                                                           operand: BoundCall.Synthesized(syntax,
                                                                                                          receiverOpt: null,
                                                                                                          method: updateMethod,
                                                                                                          arguments: ImmutableArray.Create <BoundExpression>(boundBackingField, boundParameter)),
                                                                           conversion: Conversion.ExplicitReference,
                                                                           type: delegateType);

                // _event = (DelegateType)Delegate.Combine(_event, value);
                BoundStatement eventUpdate = new BoundExpressionStatement(syntax,
                                                                          expression: new BoundAssignmentOperator(syntax,
                                                                                                                  left: boundBackingField,
                                                                                                                  right: delegateUpdate,
                                                                                                                  type: delegateType)
                {
                    WasCompilerGenerated = true
                })
                {
                    WasCompilerGenerated = true
                };

                return(BoundBlock.SynthesizedNoLocals(syntax,
                                                      statements: ImmutableArray.Create <BoundStatement>(
                                                          eventUpdate,
                                                          @return)));
            }

            compareExchangeMethod = compareExchangeMethod.Construct(ImmutableArray.Create <TypeSymbol>(delegateType));

            Binder.ReportUseSiteDiagnostics(compareExchangeMethod, diagnostics, syntax);

            GeneratedLabelSymbol loopLabel = new GeneratedLabelSymbol("loop");

            const int numTemps = 3;

            LocalSymbol[] tmps      = new LocalSymbol[numTemps];
            BoundLocal[]  boundTmps = new BoundLocal[numTemps];

            for (int i = 0; i < numTemps; i++)
            {
                tmps[i]      = new SynthesizedLocal(accessor, TypeWithAnnotations.Create(delegateType), SynthesizedLocalKind.LoweringTemp);
                boundTmps[i] = new BoundLocal(syntax, tmps[i], null, delegateType);
            }

            // tmp0 = _event;
            BoundStatement tmp0Init = new BoundExpressionStatement(syntax,
                                                                   expression: new BoundAssignmentOperator(syntax,
                                                                                                           left: boundTmps[0],
                                                                                                           right: boundBackingField,
                                                                                                           type: delegateType)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            };

            // LOOP:
            BoundStatement loopStart = new BoundLabelStatement(syntax,
                                                               label: loopLabel)
            {
                WasCompilerGenerated = true
            };

            // tmp1 = tmp0;
            BoundStatement tmp1Update = new BoundExpressionStatement(syntax,
                                                                     expression: new BoundAssignmentOperator(syntax,
                                                                                                             left: boundTmps[1],
                                                                                                             right: boundTmps[0],
                                                                                                             type: delegateType)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            };

            // (DelegateType)Delegate.Combine(tmp1, value)
            delegateUpdate = BoundConversion.SynthesizedNonUserDefined(syntax,
                                                                       operand: BoundCall.Synthesized(syntax,
                                                                                                      receiverOpt: null,
                                                                                                      method: updateMethod,
                                                                                                      arguments: ImmutableArray.Create <BoundExpression>(boundTmps[1], boundParameter)),
                                                                       conversion: Conversion.ExplicitReference,
                                                                       type: delegateType);

            // tmp2 = (DelegateType)Delegate.Combine(tmp1, value);
            BoundStatement tmp2Update = new BoundExpressionStatement(syntax,
                                                                     expression: new BoundAssignmentOperator(syntax,
                                                                                                             left: boundTmps[2],
                                                                                                             right: delegateUpdate,
                                                                                                             type: delegateType)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            };

            // Interlocked.CompareExchange<DelegateType>(ref _event, tmp2, tmp1)
            BoundExpression compareExchange = BoundCall.Synthesized(syntax,
                                                                    receiverOpt: null,
                                                                    method: compareExchangeMethod,
                                                                    arguments: ImmutableArray.Create <BoundExpression>(boundBackingField, boundTmps[2], boundTmps[1]));

            // tmp0 = Interlocked.CompareExchange<DelegateType>(ref _event, tmp2, tmp1);
            BoundStatement tmp0Update = new BoundExpressionStatement(syntax,
                                                                     expression: new BoundAssignmentOperator(syntax,
                                                                                                             left: boundTmps[0],
                                                                                                             right: compareExchange,
                                                                                                             type: delegateType)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            };

            // tmp0 == tmp1 // i.e. exit when they are equal, jump to start otherwise
            BoundExpression loopExitCondition = new BoundBinaryOperator(syntax,
                                                                        operatorKind: BinaryOperatorKind.ObjectEqual,
                                                                        left: boundTmps[0],
                                                                        right: boundTmps[1],
                                                                        constantValueOpt: null,
                                                                        methodOpt: null,
                                                                        resultKind: LookupResultKind.Viable,
                                                                        type: boolType)
            {
                WasCompilerGenerated = true
            };

            // branchfalse (tmp0 == tmp1) LOOP
            BoundStatement loopEnd = new BoundConditionalGoto(syntax,
                                                              condition: loopExitCondition,
                                                              jumpIfTrue: false,
                                                              label: loopLabel)
            {
                WasCompilerGenerated = true
            };

            return(new BoundBlock(syntax,
                                  locals: tmps.AsImmutable(),
                                  statements: ImmutableArray.Create <BoundStatement>(
                                      tmp0Init,
                                      loopStart,
                                      tmp1Update,
                                      tmp2Update,
                                      tmp0Update,
                                      loopEnd,
                                      @return))
            {
                WasCompilerGenerated = true
            });
        }
예제 #5
0
        private void CompileNamedType(NamedTypeSymbol symbol)
        {
            TypeCompilationState compilationState = new TypeCompilationState(symbol, moduleBeingBuilt);

            cancellationToken.ThrowIfCancellationRequested();

            // Find the constructor of a script class.
            MethodSymbol scriptCtor = null;

            if (symbol.IsScriptClass)
            {
                // The field initializers of a script class could be arbitrary statements,
                // including blocks.  Field initializers containing blocks need to
                // use a MethodBodySemanticModel to build up the appropriate tree of binders, and
                // MethodBodySemanticModel requires an "owning" method.  That's why we're digging out
                // the constructor - it will own the field initializers.
                scriptCtor = symbol.InstanceConstructors[0];
                Debug.Assert((object)scriptCtor != null);
            }

            var synthesizedSubmissionFields   = symbol.IsSubmissionClass ? new SynthesizedSubmissionFields(compilation, symbol) : null;
            var processedStaticInitializers   = new ProcessedFieldInitializers();
            var processedInstanceInitializers = new ProcessedFieldInitializers();

            var sourceTypeSymbol = symbol as SourceMemberContainerTypeSymbol;

            if ((object)sourceTypeSymbol != null)
            {
                BindFieldInitializers(sourceTypeSymbol, scriptCtor, sourceTypeSymbol.StaticInitializers, this.generateDebugInfo, ref processedStaticInitializers);
                BindFieldInitializers(sourceTypeSymbol, scriptCtor, sourceTypeSymbol.InstanceInitializers, this.generateDebugInfo, ref processedInstanceInitializers);

                if (compilationState.Emitting)
                {
                    CompileSynthesizedExplicitImplementations(sourceTypeSymbol, compilationState);
                }
            }

            // Indicates if a static constructor is in the member,
            // so we can decide to synthesize a static constructor.
            bool hasStaticConstructor = false;

            foreach (var member in symbol.GetMembers())
            {
                //When a filter is supplied, limit the compilation of members passing the filter.
                if ((this.filter != null) && !this.filter(member))
                {
                    continue;
                }

                switch (member.Kind)
                {
                case SymbolKind.NamedType:
                    member.Accept(this, compilationState);
                    break;

                case SymbolKind.Method:
                {
                    MethodSymbol method = (MethodSymbol)member;
                    if (method.IsSubmissionConstructor || IsFieldLikeEventAccessor(method))
                    {
                        continue;
                    }

                    if (method.IsPartial())
                    {
                        method = method.PartialImplementation();
                        if ((object)method == null)
                        {
                            continue;
                        }
                    }

                    ProcessedFieldInitializers processedInitializers =
                        method.MethodKind == MethodKind.Constructor ? processedInstanceInitializers :
                        method.MethodKind == MethodKind.StaticConstructor ? processedStaticInitializers :
                        default(ProcessedFieldInitializers);

                    CompileMethod(method, ref processedInitializers, synthesizedSubmissionFields, compilationState);

                    // Set a flag to indicate that a static constructor is created.
                    if (method.MethodKind == MethodKind.StaticConstructor)
                    {
                        hasStaticConstructor = true;
                    }

                    break;
                }

                case SymbolKind.Property:
                {
                    SourcePropertySymbol sourceProperty = member as SourcePropertySymbol;
                    if ((object)sourceProperty != null && sourceProperty.IsSealed && compilationState.Emitting)
                    {
                        CompileSynthesizedSealedAccessors(sourceProperty, compilationState);
                    }
                    break;
                }

                case SymbolKind.Event:
                {
                    SourceEventSymbol eventSymbol = member as SourceEventSymbol;
                    if ((object)eventSymbol != null && eventSymbol.HasAssociatedField && !eventSymbol.IsAbstract && compilationState.Emitting)
                    {
                        CompileFieldLikeEventAccessor(eventSymbol, isAddMethod: true, compilationState: compilationState);
                        CompileFieldLikeEventAccessor(eventSymbol, isAddMethod: false, compilationState: compilationState);
                    }
                    break;
                }

                case SymbolKind.Field:
                {
                    SourceMemberFieldSymbol fieldSymbol = member as SourceMemberFieldSymbol;
                    if ((object)fieldSymbol != null)
                    {
                        if (fieldSymbol.IsConst)
                        {
                            // We check specifically for constant fields with bad values because they never result
                            // in bound nodes being inserted into method bodies (in which case, they would be covered
                            // by the method-level check).
                            ConstantValue constantValue = fieldSymbol.GetConstantValue(ConstantFieldsInProgress.Empty, earlyDecodingWellKnownAttributes: false);
                            SetGlobalErrorIfTrue(constantValue == null || constantValue.IsBad);
                        }

                        if (fieldSymbol.IsFixed && compilationState.Emitting)
                        {
                            // force the generation of implementation types for fixed-size buffers
                            TypeSymbol discarded = fieldSymbol.FixedImplementationType(compilationState.ModuleBuilder);
                        }
                    }
                    break;
                }
                }
            }

            Debug.Assert(symbol.TypeKind != TypeKind.Submission || ((object)scriptCtor != null && scriptCtor.IsSubmissionConstructor));

            //  process additional anonymous type members
            if (AnonymousTypeManager.IsAnonymousTypeTemplate(symbol))
            {
                ProcessedFieldInitializers processedInitializers = default(ProcessedFieldInitializers);
                foreach (var method in AnonymousTypeManager.GetAnonymousTypeHiddenMethods(symbol))
                {
                    CompileMethod(method, ref processedInitializers, synthesizedSubmissionFields, compilationState);
                }
            }

            // In the case there are field initializers but we haven't created an implicit static constructor (.cctor) for it,
            // (since we may not add .cctor implicitly created for decimals into the symbol table)
            // it is necessary for the compiler to generate the static constructor here if we are emitting.
            if (moduleBeingBuilt != null && !hasStaticConstructor && !processedStaticInitializers.BoundInitializers.IsDefaultOrEmpty)
            {
                Debug.Assert(processedStaticInitializers.BoundInitializers.All((init) =>
                                                                               (init.Kind == BoundKind.FieldInitializer) && !((BoundFieldInitializer)init).Field.IsMetadataConstant));

                MethodSymbol method = new SynthesizedStaticConstructor(sourceTypeSymbol);
                if ((this.filter == null) || this.filter(method))
                {
                    CompileMethod(method, ref processedStaticInitializers, synthesizedSubmissionFields, compilationState);
                    // If this method has been successfully built, we emit it.
                    if (moduleBeingBuilt.GetMethodBody(method) != null)
                    {
                        moduleBeingBuilt.AddCompilerGeneratedDefinition(sourceTypeSymbol, method);
                    }
                }
            }

            // compile submission constructor last so that synthesized submission fields are collected from all script methods:
            if (synthesizedSubmissionFields != null && compilationState.Emitting)
            {
                Debug.Assert(scriptCtor.IsSubmissionConstructor);
                CompileMethod(scriptCtor, ref processedInstanceInitializers, synthesizedSubmissionFields, compilationState);
                synthesizedSubmissionFields.AddToType(scriptCtor.ContainingType, compilationState.ModuleBuilder);
            }

            //  Emit synthesized methods produced during lowering if any
            CompileGeneratedMethods(compilationState);
            compilationState.Free();
        }