Пример #1
0
        internal static void BindFieldInitializers(
            SourceMemberContainerTypeSymbol typeSymbol,
            MethodSymbol scriptCtor,
            ImmutableArray <ImmutableArray <FieldOrPropertyInitializer> > fieldInitializers,
            DiagnosticBag diagnostics,
            ref ProcessedFieldInitializers processedInitializers) //by ref so that we can store the results of lowering
        {
            DiagnosticBag diagsForInstanceInitializers = DiagnosticBag.GetInstance();

            try
            {
                ImportChain firstImportChain;

                processedInitializers.BoundInitializers = BindFieldInitializers(typeSymbol, scriptCtor, fieldInitializers,
                                                                                diagsForInstanceInitializers, out firstImportChain);

                processedInitializers.HasErrors        = diagsForInstanceInitializers.HasAnyErrors();
                processedInitializers.FirstImportChain = firstImportChain;
            }
            finally
            {
                diagnostics.AddRange(diagsForInstanceInitializers);
                diagsForInstanceInitializers.Free();
            }
        }
Пример #2
0
        internal static void BindFieldInitializers(
            CSharpCompilation compilation,
            SynthesizedInteractiveInitializerMethod?scriptInitializerOpt,
            ImmutableArray <ImmutableArray <FieldOrPropertyInitializer> > fieldInitializers,
            BindingDiagnosticBag diagnostics,
            ref ProcessedFieldInitializers processedInitializers
            )
        {
            var diagsForInstanceInitializers = BindingDiagnosticBag.GetInstance(
                withDiagnostics: true,
                diagnostics.AccumulatesDependencies
                );
            ImportChain?firstImportChain;

            processedInitializers.BoundInitializers = BindFieldInitializers(
                compilation,
                scriptInitializerOpt,
                fieldInitializers,
                diagsForInstanceInitializers,
                out firstImportChain
                );
            processedInitializers.HasErrors        = diagsForInstanceInitializers.HasAnyErrors();
            processedInitializers.FirstImportChain = firstImportChain;
            diagnostics.AddRange(diagsForInstanceInitializers);
            diagsForInstanceInitializers.Free();
        }
Пример #3
0
        internal static void BindFieldInitializers(
            SourceMemberContainerTypeSymbol typeSymbol,
            MethodSymbol scriptCtor,
            ImmutableArray <ImmutableArray <FieldInitializer> > fieldInitializers,
            bool generateDebugInfo,
            DiagnosticBag diagnostics,
            ref ProcessedFieldInitializers processedInitializers) //by ref so that we can store the results of lowering
        {
            DiagnosticBag diagsForInstanceInitializers = DiagnosticBag.GetInstance();

            try
            {
                ConsList <Imports> firstDebugImports;

                processedInitializers.BoundInitializers = BindFieldInitializers(typeSymbol, scriptCtor, fieldInitializers,
                                                                                diagsForInstanceInitializers, generateDebugInfo, out firstDebugImports);

                processedInitializers.HasErrors         = diagsForInstanceInitializers.HasAnyErrors();
                processedInitializers.FirstDebugImports = firstDebugImports;
            }
            finally
            {
                diagnostics.AddRange(diagsForInstanceInitializers);
                diagsForInstanceInitializers.Free();
            }
        }
Пример #4
0
        internal static void BindFieldInitializers(
            SourceMemberContainerTypeSymbol typeSymbol,
            MethodSymbol scriptCtor,
            ImmutableArray<FieldInitializers> fieldInitializers,
            bool generateDebugInfo,
            DiagnosticBag diagnostics,
            ref ProcessedFieldInitializers processedInitializers) //by ref so that we can store the results of lowering
        {
            DiagnosticBag diagsForInstanceInitializers = DiagnosticBag.GetInstance();
            try
            {
                ConsList<Imports> firstDebugImports;

                processedInitializers.BoundInitializers = BindFieldInitializers(typeSymbol, scriptCtor, fieldInitializers,
                    diagsForInstanceInitializers, generateDebugInfo, out firstDebugImports);

                processedInitializers.HasErrors = diagsForInstanceInitializers.HasAnyErrors();
                processedInitializers.FirstDebugImports = firstDebugImports;
            }
            finally
            {
                diagnostics.AddRange(diagsForInstanceInitializers);
                diagsForInstanceInitializers.Free();
            }
        }
Пример #5
0
 internal static void BindFieldInitializers(
     CSharpCompilation compilation,
     SynthesizedInteractiveInitializerMethod scriptInitializerOpt,
     ImmutableArray<ImmutableArray<FieldOrPropertyInitializer>> fieldInitializers,
     DiagnosticBag diagnostics,
     ref ProcessedFieldInitializers processedInitializers)
 {
     var diagsForInstanceInitializers = DiagnosticBag.GetInstance();
     ImportChain firstImportChain;
     processedInitializers.BoundInitializers = BindFieldInitializers(compilation, scriptInitializerOpt, fieldInitializers, diagsForInstanceInitializers, out firstImportChain);
     processedInitializers.HasErrors = diagsForInstanceInitializers.HasAnyErrors();
     processedInitializers.FirstImportChain = firstImportChain;
     diagnostics.AddRange(diagsForInstanceInitializers);
     diagsForInstanceInitializers.Free();
 }
Пример #6
0
        internal static void BindFieldInitializers(
            CSharpCompilation compilation,
            SynthesizedInteractiveInitializerMethod scriptInitializerOpt,
            ImmutableArray<ImmutableArray<FieldOrPropertyInitializer>> fieldInitializers,
            DiagnosticBag diagnostics,
            bool setReturnType, // Remove once static fields are errors in submissions.
            ref ProcessedFieldInitializers processedInitializers)
        {
            if (setReturnType && ((object)scriptInitializerOpt != null))
            {
                SetScriptInitializerReturnType(compilation, scriptInitializerOpt, fieldInitializers, diagnostics);
            }

            var diagsForInstanceInitializers = DiagnosticBag.GetInstance();
            ImportChain firstImportChain;
            processedInitializers.BoundInitializers = BindFieldInitializers(compilation, scriptInitializerOpt, fieldInitializers, diagsForInstanceInitializers, out firstImportChain);
            processedInitializers.HasErrors = diagsForInstanceInitializers.HasAnyErrors();
            processedInitializers.FirstImportChain = firstImportChain;
            diagnostics.AddRange(diagsForInstanceInitializers);
            diagsForInstanceInitializers.Free();
        }
Пример #7
0
        internal static void BindFieldInitializers(
            CSharpCompilation compilation,
            SynthesizedInteractiveInitializerMethod scriptInitializerOpt,
            ImmutableArray <ImmutableArray <FieldOrPropertyInitializer> > fieldInitializers,
            DiagnosticBag diagnostics,
            bool setReturnType, // Remove once static fields are errors in submissions.
            ref ProcessedFieldInitializers processedInitializers)
        {
            if (setReturnType && ((object)scriptInitializerOpt != null))
            {
                SetScriptInitializerReturnType(compilation, scriptInitializerOpt, fieldInitializers, diagnostics);
            }

            var         diagsForInstanceInitializers = DiagnosticBag.GetInstance();
            ImportChain firstImportChain;

            processedInitializers.BoundInitializers = BindFieldInitializers(compilation, scriptInitializerOpt, fieldInitializers, diagsForInstanceInitializers, out firstImportChain);
            processedInitializers.HasErrors         = diagsForInstanceInitializers.HasAnyErrors();
            processedInitializers.FirstImportChain  = firstImportChain;
            diagnostics.AddRange(diagsForInstanceInitializers);
            diagsForInstanceInitializers.Free();
        }
Пример #8
0
        internal static void BindFieldInitializers(
            SourceMemberContainerTypeSymbol typeSymbol,
            MethodSymbol scriptCtor,
            ImmutableArray<ImmutableArray<FieldOrPropertyInitializer>> fieldInitializers,
            DiagnosticBag diagnostics,
            ref ProcessedFieldInitializers processedInitializers) //by ref so that we can store the results of lowering
        {
            DiagnosticBag diagsForInstanceInitializers = DiagnosticBag.GetInstance();
            try
            {
                ImportChain firstImportChain;

                processedInitializers.BoundInitializers = BindFieldInitializers(typeSymbol, scriptCtor, fieldInitializers,
                    diagsForInstanceInitializers, out firstImportChain);

                processedInitializers.HasErrors = diagsForInstanceInitializers.HasAnyErrors();
                processedInitializers.FirstImportChain = firstImportChain;
            }
            finally
            {
                diagnostics.AddRange(diagsForInstanceInitializers);
                diagsForInstanceInitializers.Free();
            }
        }
Пример #9
0
        //TODO: it might be nice to make this a static method on Compiler
        private void CompileMethod(
            MethodSymbol methodSymbol,
            ref ProcessedFieldInitializers processedInitializers,
            SynthesizedSubmissionFields previousSubmissionFields,
            TypeCompilationState compilationState)
        {
            cancellationToken.ThrowIfCancellationRequested();
            SourceMethodSymbol sourceMethod = methodSymbol as SourceMethodSymbol;

            if (methodSymbol.IsAbstract)
            {
                if ((object)sourceMethod != null)
                {
                    bool diagsWritten;
                    sourceMethod.SetDiagnostics(ImmutableArray <Diagnostic> .Empty, out diagsWritten);
                    if (diagsWritten && !methodSymbol.IsImplicitlyDeclared && compilation.EventQueue != null)
                    {
                        compilation.SymbolDeclaredEvent(methodSymbol);
                    }
                }

                return;
            }

            // get cached diagnostics if not building and we have 'em
            bool calculateDiagnosticsOnly = moduleBeingBuilt == null;

            if (calculateDiagnosticsOnly && ((object)sourceMethod != null))
            {
                var cachedDiagnostics = sourceMethod.Diagnostics;

                if (!cachedDiagnostics.IsDefault)
                {
                    this.diagnostics.AddRange(cachedDiagnostics);
                    return;
                }
            }

            ConsList <Imports> oldDebugImports = compilationState.CurrentDebugImports;

            // In order to avoid generating code for methods with errors, we create a diagnostic bag just for this method.
            DiagnosticBag diagsForCurrentMethod = DiagnosticBag.GetInstance();

            try
            {
                bool       includeInitializersInBody;
                BoundBlock body;

                // if synthesized method returns its body in lowered form
                if (methodSymbol.SynthesizesLoweredBoundBody)
                {
                    if (moduleBeingBuilt != null)
                    {
                        methodSymbol.GenerateMethodBody(compilationState, diagsForCurrentMethod);
                        this.diagnostics.AddRange(diagsForCurrentMethod);
                    }

                    return;
                }

                //EDMAURER initializers that have been analyzed but not yet lowered.
                BoundStatementList analyzedInitializers = null;

                ConsList <Imports> debugImports;

                if (methodSymbol.IsScriptConstructor)
                {
                    // rewrite top-level statements and script variable declarations to a list of statements and assignments, respectively:
                    BoundStatementList initializerStatements = InitializerRewriter.Rewrite(processedInitializers.BoundInitializers, methodSymbol);

                    // the lowered script initializers should not be treated as initializers anymore but as a method body:
                    body = new BoundBlock(initializerStatements.Syntax, ImmutableArray <LocalSymbol> .Empty, initializerStatements.Statements)
                    {
                        WasCompilerGenerated = true
                    };
                    includeInitializersInBody = false;

                    debugImports = null;
                }
                else
                {
                    // do not emit initializers if we are invoking another constructor of this class:
                    includeInitializersInBody = !processedInitializers.BoundInitializers.IsDefaultOrEmpty && !HasThisConstructorInitializer(methodSymbol);

                    // lower initializers just once. the lowered tree will be reused when emitting all constructors
                    // with field initializers. Once lowered, these initializers will be stashed in processedInitializers.LoweredInitializers
                    // (see later in this method). Don't bother lowering _now_ if this particular ctor won't have the initializers
                    // appended to its body.
                    if (includeInitializersInBody && processedInitializers.LoweredInitializers == null)
                    {
                        analyzedInitializers            = InitializerRewriter.Rewrite(processedInitializers.BoundInitializers, methodSymbol);
                        processedInitializers.HasErrors = processedInitializers.HasErrors || analyzedInitializers.HasAnyErrors;

                        // These analyses check for diagnostics in lambdas.
                        // Control flow analysis and implicit return insertion are unnecessary.
                        DataFlowPass.Analyze(compilation, methodSymbol, analyzedInitializers, diagsForCurrentMethod, requireOutParamsAssigned: false);
                        DiagnosticsPass.IssueDiagnostics(compilation, analyzedInitializers, diagsForCurrentMethod, methodSymbol);
                    }

                    body = Compiler.BindMethodBody(methodSymbol, diagsForCurrentMethod, this.generateDebugInfo, out debugImports);
                }

#if DEBUG
                // If the method is a synthesized static or instance constructor, then debugImports will be null and we will use the value
                // from the first field initializer.
                if (this.generateDebugInfo)
                {
                    if ((methodSymbol.MethodKind == MethodKind.Constructor || methodSymbol.MethodKind == MethodKind.StaticConstructor) && methodSymbol.IsImplicitlyDeclared)
                    {
                        // There was no body to bind, so we didn't get anything from Compiler.BindMethodBody.
                        Debug.Assert(debugImports == null);
                        // Either there were no field initializers or we grabbed debug imports from the first one.
                        Debug.Assert(processedInitializers.BoundInitializers.IsDefaultOrEmpty || processedInitializers.FirstDebugImports != null);
                    }
                }
#endif

                debugImports = debugImports ?? processedInitializers.FirstDebugImports;

                // Associate these debug imports with all methods generated from this one.
                compilationState.CurrentDebugImports = debugImports;

                if (body != null && methodSymbol is SourceMethodSymbol)
                {
                    // TODO: Do we need to issue warnings for non-SourceMethodSymbol methods, like synthesized ctors?
                    DiagnosticsPass.IssueDiagnostics(compilation, body, diagsForCurrentMethod, methodSymbol);
                }

                BoundBlock flowAnalyzedBody = null;
                if (body != null)
                {
                    flowAnalyzedBody = FlowAnalysisPass.Rewrite(methodSymbol, body, diagsForCurrentMethod);
                }

                bool hasErrors = hasDeclarationErrors || diagsForCurrentMethod.HasAnyErrors() || processedInitializers.HasErrors;

                // Record whether or not the bound tree for the lowered method body (including any initializers) contained any
                // errors (note: errors, not diagnostics).
                SetGlobalErrorIfTrue(hasErrors);

                bool diagsWritten      = false;
                var  actualDiagnostics = diagsForCurrentMethod.ToReadOnly();
                if (sourceMethod != null)
                {
                    actualDiagnostics = sourceMethod.SetDiagnostics(actualDiagnostics, out diagsWritten);
                }
                if (diagsWritten && !methodSymbol.IsImplicitlyDeclared && compilation.EventQueue != null)
                {
                    var lazySemanticModel = body == null ? null : new Lazy <SemanticModel>(() =>
                    {
                        var syntax        = body.Syntax;
                        var semanticModel = (CSharpSemanticModel)compilation.GetSemanticModel(syntax.SyntaxTree);
                        var memberModel   = semanticModel.GetMemberModel(syntax);
                        if (memberModel != null)
                        {
                            memberModel.AddBoundTreeForStandaloneSyntax(syntax, body);
                        }
                        return(semanticModel);
                    });
                    compilation.EventQueue.Enqueue(new CompilationEvent.SymbolDeclared(compilation, methodSymbol, lazySemanticModel));
                }

                // Don't lower if we're not emitting or if there were errors.
                // Methods that had binding errors are considered too broken to be lowered reliably.
                if (calculateDiagnosticsOnly || hasErrors)
                {
                    this.diagnostics.AddRange(actualDiagnostics);
                    return;
                }

                // ############################
                // LOWERING AND EMIT
                // Any errors generated below here are considered Emit diagnostics
                // and will not be reported to callers Compilation.GetDiagnostics()

                BoundStatement loweredBody = (flowAnalyzedBody == null) ? null :
                                             Compiler.LowerStatement(this.generateDebugInfo, methodSymbol, flowAnalyzedBody, previousSubmissionFields, compilationState, diagsForCurrentMethod);

                bool hasBody = loweredBody != null;

                hasErrors = hasErrors || (hasBody && loweredBody.HasErrors) || diagsForCurrentMethod.HasAnyErrors();
                SetGlobalErrorIfTrue(hasErrors);

                // don't emit if the resulting method would contain initializers with errors
                if (!hasErrors && (hasBody || includeInitializersInBody))
                {
                    // Fields must be initialized before constructor initializer (which is the first statement of the analyzed body, if specified),
                    // so that the initialization occurs before any method overridden by the declaring class can be invoked from the base constructor
                    // and access the fields.

                    ImmutableArray <BoundStatement> boundStatements;

                    if (methodSymbol.IsScriptConstructor)
                    {
                        boundStatements = MethodBodySynthesizer.ConstructScriptConstructorBody(loweredBody, methodSymbol, previousSubmissionFields, compilation);
                    }
                    else
                    {
                        boundStatements = ImmutableArray <BoundStatement> .Empty;

                        if (analyzedInitializers != null)
                        {
                            processedInitializers.LoweredInitializers = (BoundStatementList)Compiler.LowerStatement(
                                this.generateDebugInfo,
                                methodSymbol,
                                analyzedInitializers,
                                previousSubmissionFields,
                                compilationState,
                                diagsForCurrentMethod);

                            Debug.Assert(!hasErrors);
                            hasErrors = processedInitializers.LoweredInitializers.HasAnyErrors || diagsForCurrentMethod.HasAnyErrors();
                            SetGlobalErrorIfTrue(hasErrors);

                            if (hasErrors)
                            {
                                this.diagnostics.AddRange(diagsForCurrentMethod);
                                return;
                            }
                        }

                        // initializers for global code have already been included in the body
                        if (includeInitializersInBody)
                        {
                            //TODO: rewrite any BoundThis and BoundBase nodes in the initializers to have the correct ThisParameter symbol
                            if (compilation.Options.Optimize)
                            {
                                // TODO: this part may conflict with InitializerRewriter.Rewrite in how it handles
                                //       the first field initializer (see 'if (i == 0)'...) which seems suspicious
                                ArrayBuilder <BoundStatement> statements = ArrayBuilder <BoundStatement> .GetInstance();

                                statements.AddRange(boundStatements);
                                bool anyNonDefault = false;

                                foreach (var initializer in processedInitializers.LoweredInitializers.Statements)
                                {
                                    if (ShouldOptimizeOutInitializer(initializer))
                                    {
                                        if (methodSymbol.IsStatic)
                                        {
                                            // NOTE: Dev11 removes static initializers if ONLY all of them are optimized out
                                            statements.Add(initializer);
                                        }
                                    }
                                    else
                                    {
                                        statements.Add(initializer);
                                        anyNonDefault = true;
                                    }
                                }

                                if (anyNonDefault)
                                {
                                    boundStatements = statements.ToImmutableAndFree();
                                }
                                else
                                {
                                    statements.Free();
                                }
                            }
                            else
                            {
                                boundStatements = boundStatements.Concat(processedInitializers.LoweredInitializers.Statements);
                            }
                        }

                        if (hasBody)
                        {
                            boundStatements = boundStatements.Concat(ImmutableArray.Create(loweredBody));
                        }
                    }

                    CSharpSyntaxNode syntax = methodSymbol.GetNonNullSyntaxNode();

                    var boundBody = BoundStatementList.Synthesized(syntax, boundStatements);

                    var emittedBody = Compiler.GenerateMethodBody(
                        compilationState,
                        methodSymbol,
                        boundBody,
                        diagsForCurrentMethod,
                        optimize,
                        debugDocumentProvider,
                        GetNamespaceScopes(methodSymbol, debugImports));

                    moduleBeingBuilt.SetMethodBody(methodSymbol, emittedBody);
                }

                this.diagnostics.AddRange(diagsForCurrentMethod);
            }
            finally
            {
                diagsForCurrentMethod.Free();
                compilationState.CurrentDebugImports = oldDebugImports;
            }
        }
Пример #10
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();
        }