public override BoundNode VisitLabeledStatement(BoundLabeledStatement node)
        {
            Debug.Assert(node != null);

            var rewrittenBody = (BoundStatement)Visit(node.Body);

            BoundStatement labelStatement = new BoundLabelStatement(node.Syntax, node.Label);

            if (this.Instrument)
            {
                var labeledSyntax = node.Syntax as LabeledStatementSyntax;
                if (labeledSyntax != null)
                {
                    labelStatement = _instrumenter.InstrumentLabelStatement(node, labelStatement);
                }
            }

            if (rewrittenBody == null)
            {
                // Body may be null if the body has no associated IL
                // (declaration with no initializer for instance.)
                return(labelStatement);
            }

            return(BoundStatementList.Synthesized(node.Syntax, labelStatement, rewrittenBody));
        }
        private BoundNode VisitMultipleLocalDeclarationsBase(BoundMultipleLocalDeclarationsBase node)
        {
            ArrayBuilder <BoundStatement> inits = null;

            foreach (var decl in node.LocalDeclarations)
            {
                var init = VisitLocalDeclaration(decl);

                if (init != null)
                {
                    if (inits == null)
                    {
                        inits = ArrayBuilder <BoundStatement> .GetInstance();
                    }

                    inits.Add((BoundStatement)init);
                }
            }

            if (inits != null)
            {
                return(BoundStatementList.Synthesized(node.Syntax, node.HasErrors, inits.ToImmutableAndFree()));
            }
            else
            {
                // no initializers
                return(null); // TODO: but what if hasErrors?  Have we lost that?
            }
        }
        public override BoundNode VisitLabeledStatement(BoundLabeledStatement node)
        {
            Debug.Assert(node != null);

            var rewrittenBody = (BoundStatement)Visit(node.Body);

            BoundStatement labelStatement = new BoundLabelStatement(node.Syntax, node.Label);

            if (this.GenerateDebugInfo)
            {
                var labeledSyntax = node.Syntax as LabeledStatementSyntax;
                if (labeledSyntax != null)
                {
                    var span = TextSpan.FromBounds(labeledSyntax.Identifier.SpanStart, labeledSyntax.ColonToken.Span.End);
                    labelStatement = factory.SequencePointWithSpan(labeledSyntax, span, labelStatement);
                }
            }

            if (rewrittenBody == null)
            {
                // Body may be null if the body has no associated IL
                // (declaration with no initializer for instance.)
                return(labelStatement);
            }

            return(BoundStatementList.Synthesized(node.Syntax, labelStatement, rewrittenBody));
        }
        private BoundStatement MakeLabeledStatement(
            BoundLabeledStatement node,
            BoundStatement?rewrittenBody
            )
        {
            BoundStatement labelStatement = new BoundLabelStatement(node.Syntax, node.Label);

            if (this.Instrument)
            {
                var labeledSyntax = node.Syntax as LabeledStatementSyntax;
                if (labeledSyntax != null)
                {
                    labelStatement = _instrumenter.InstrumentLabelStatement(node, labelStatement);
                }
            }

            if (rewrittenBody == null)
            {
                // Body may be null if the body has no associated IL
                // (declaration with no initializer for instance.)
                return(labelStatement);
            }

            return(BoundStatementList.Synthesized(node.Syntax, labelStatement, rewrittenBody));
        }
Beispiel #5
0
        private BoundStatement RewriteWhileStatement(
            BoundLoopStatement loop,
            BoundExpression rewrittenCondition,
            BoundStatement rewrittenBody,
            GeneratedLabelSymbol breakLabel,
            GeneratedLabelSymbol continueLabel,
            bool hasErrors)
        {
            Debug.Assert(loop.Kind == BoundKind.WhileStatement || loop.Kind == BoundKind.ForEachStatement);

            // while (condition)
            //   body;
            //
            // becomes
            //
            // goto continue;
            // start:
            // {
            //     body
            //     continue:
            //     GotoIfTrue condition start;
            // }
            // break:

            SyntaxNode     syntax               = loop.Syntax;
            var            startLabel           = new GeneratedLabelSymbol("start");
            BoundStatement ifConditionGotoStart = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, true, startLabel);
            BoundStatement gotoContinue         = new BoundGotoStatement(syntax, continueLabel);

            if (this.Instrument && !loop.WasCompilerGenerated)
            {
                switch (loop.Kind)
                {
                case BoundKind.WhileStatement:
                    ifConditionGotoStart = _instrumenter.InstrumentWhileStatementConditionalGotoStartOrBreak((BoundWhileStatement)loop, ifConditionGotoStart);
                    break;

                case BoundKind.ForEachStatement:
                    ifConditionGotoStart = _instrumenter.InstrumentForEachStatementConditionalGotoStart((BoundForEachStatement)loop, ifConditionGotoStart);
                    break;

                default:
                    throw ExceptionUtilities.UnexpectedValue(loop.Kind);
                }

                // mark the initial jump as hidden. We do it to tell that this is not a part of previous statement. This
                // jump may be a target of another jump (for example if loops are nested) and that would give the
                // impression that the previous statement is being re-executed.
                gotoContinue = new BoundSequencePoint(null, gotoContinue);
            }

            return(BoundStatementList.Synthesized(syntax, hasErrors,
                                                  gotoContinue,
                                                  new BoundLabelStatement(syntax, startLabel),
                                                  rewrittenBody,
                                                  new BoundLabelStatement(syntax, continueLabel),
                                                  ifConditionGotoStart,
                                                  new BoundLabelStatement(syntax, breakLabel)));
        }
Beispiel #6
0
        public override BoundNode VisitDoStatement(BoundDoStatement node)
        {
            Debug.Assert(node != null);

            var rewrittenCondition = (BoundExpression)Visit(node.Condition);
            var rewrittenBody      = (BoundStatement)Visit(node.Body);
            var startLabel         = new GeneratedLabelSymbol("start");

            var syntax = node.Syntax;

            // EnC: We need to insert a hidden sequence point to handle function remapping in case
            // the containing method is edited while methods invoked in the condition are being executed.
            if (!node.WasCompilerGenerated && this.Instrument)
            {
                rewrittenCondition = _instrumenter.InstrumentDoStatementCondition(node, rewrittenCondition, _factory);
            }

            BoundStatement ifConditionGotoStart = new BoundConditionalGoto(syntax, rewrittenCondition, true, startLabel);

            if (!node.WasCompilerGenerated && this.Instrument)
            {
                ifConditionGotoStart = _instrumenter.InstrumentDoStatementConditionalGotoStart(node, ifConditionGotoStart);
            }

            // do
            //   body
            // while (condition);
            //
            // becomes
            //
            // start:
            // {
            //   body
            //   continue:
            //   sequence point
            //   GotoIfTrue condition start;
            // }
            // break:

            if (node.Locals.IsEmpty)
            {
                return(BoundStatementList.Synthesized(syntax, node.HasErrors,
                                                      new BoundLabelStatement(syntax, startLabel),
                                                      rewrittenBody,
                                                      new BoundLabelStatement(syntax, node.ContinueLabel),
                                                      ifConditionGotoStart,
                                                      new BoundLabelStatement(syntax, node.BreakLabel)));
            }

            return(BoundStatementList.Synthesized(syntax, node.HasErrors,
                                                  new BoundLabelStatement(syntax, startLabel),
                                                  new BoundBlock(syntax,
                                                                 node.Locals,
                                                                 ImmutableArray.Create <BoundStatement>(rewrittenBody,
                                                                                                        new BoundLabelStatement(syntax, node.ContinueLabel),
                                                                                                        ifConditionGotoStart)),
                                                  new BoundLabelStatement(syntax, node.BreakLabel)));
        }
        public override BoundNode VisitDoStatement(BoundDoStatement node)
        {
            Debug.Assert(node != null);

            var rewrittenCondition = (BoundExpression)Visit(node.Condition);
            var rewrittenBody      = (BoundStatement)Visit(node.Body);
            var startLabel         = new GeneratedLabelSymbol("start");

            var syntax = node.Syntax;

            BoundStatement ifConditionGotoStart = new BoundConditionalGoto(syntax, rewrittenCondition, true, startLabel);

            if (this.generateDebugInfo)
            {
                var doSyntax = (DoStatementSyntax)syntax;
                var span     = TextSpan.FromBounds(
                    doSyntax.WhileKeyword.SpanStart,
                    doSyntax.SemicolonToken.Span.End);

                ifConditionGotoStart = new BoundSequencePointWithSpan(doSyntax, ifConditionGotoStart, span);
            }

            // do
            //   body
            // while (condition);
            //
            // becomes
            //
            // start:
            // {
            //   body
            //   continue:
            //   sequence point
            //   GotoIfTrue condition start;
            // }
            // break:

            if (!node.InnerLocals.IsDefaultOrEmpty)
            {
                return(BoundStatementList.Synthesized(syntax, node.HasErrors,
                                                      new BoundLabelStatement(syntax, startLabel),
                                                      new BoundBlock(syntax,
                                                                     node.InnerLocals,
                                                                     ImmutableArray.Create <BoundStatement>(rewrittenBody,
                                                                                                            new BoundLabelStatement(syntax, node.ContinueLabel),
                                                                                                            ifConditionGotoStart)),
                                                      new BoundLabelStatement(syntax, node.BreakLabel)));
            }

            return(BoundStatementList.Synthesized(syntax, node.HasErrors,
                                                  new BoundLabelStatement(syntax, startLabel),
                                                  rewrittenBody,
                                                  new BoundLabelStatement(syntax, node.ContinueLabel),
                                                  ifConditionGotoStart,
                                                  new BoundLabelStatement(syntax, node.BreakLabel)));
        }
Beispiel #8
0
        private BoundStatement RewriteWhileStatement(
            BoundWhileStatement loop,
            ImmutableArray <LocalSymbol> locals,
            BoundExpression rewrittenCondition,
            BoundStatement rewrittenBody,
            GeneratedLabelSymbol breakLabel,
            GeneratedLabelSymbol continueLabel,
            bool hasErrors)
        {
            if (locals.IsEmpty)
            {
                return(RewriteWhileStatement(loop, rewrittenCondition, rewrittenBody, breakLabel, continueLabel, hasErrors));
            }

            // We need to enter scope-block from the top, that is where an instance of a display class will be created
            // if any local is captured within a lambda.

            // while (condition)
            //   body;
            //
            // becomes
            //
            // continue:
            // {
            //     GotoIfFalse condition break;
            //     body
            //     goto continue;
            // }
            // break:

            SyntaxNode     syntax = loop.Syntax;
            BoundStatement continueLabelStatement  = new BoundLabelStatement(syntax, continueLabel);
            BoundStatement ifNotConditionGotoBreak = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, false, breakLabel);

            if (this.Instrument && !loop.WasCompilerGenerated)
            {
                ifNotConditionGotoBreak = _instrumenter.InstrumentWhileStatementConditionalGotoStartOrBreak(loop, ifNotConditionGotoBreak);
                continueLabelStatement  = new BoundSequencePoint(null, continueLabelStatement);
            }

            return(BoundStatementList.Synthesized(syntax, hasErrors,
                                                  continueLabelStatement,
                                                  new BoundBlock(syntax,
                                                                 locals,
                                                                 ImmutableArray.Create(
                                                                     ifNotConditionGotoBreak,
                                                                     rewrittenBody,
                                                                     new BoundGotoStatement(syntax, continueLabel))),
                                                  new BoundLabelStatement(syntax, breakLabel)));
        }
Beispiel #9
0
        private static BoundStatement RewriteIfStatement(
            CSharpSyntaxNode syntax,
            BoundExpression rewrittenCondition,
            BoundStatement rewrittenConsequence,
            BoundStatement rewrittenAlternativeOpt,
            bool hasErrors)
        {
            var afterif = new GeneratedLabelSymbol("afterif");

            // if (condition)
            //   consequence;
            //
            // becomes
            //
            // GotoIfFalse condition afterif;
            // consequence;
            // afterif:

            if (rewrittenAlternativeOpt == null)
            {
                return(BoundStatementList.Synthesized(syntax,
                                                      new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, false, afterif),
                                                      rewrittenConsequence,
                                                      new BoundLabelStatement(syntax, afterif)));
            }

            // if (condition)
            //     consequence;
            // else
            //     alternative
            //
            // becomes
            //
            // GotoIfFalse condition alt;
            // consequence
            // goto afterif;
            // alt:
            // alternative;
            // afterif:

            var alt = new GeneratedLabelSymbol("alternative");

            return(BoundStatementList.Synthesized(syntax, hasErrors,
                                                  new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, false, alt),
                                                  rewrittenConsequence,
                                                  new BoundGotoStatement(syntax, afterif),
                                                  new BoundLabelStatement(syntax, alt),
                                                  rewrittenAlternativeOpt,
                                                  new BoundLabelStatement(syntax, afterif)));
        }
        private BoundStatement RewriteWhileStatement(
            CSharpSyntaxNode syntax,
            BoundExpression rewrittenCondition,
            TextSpan conditionSequencePointSpan,
            BoundStatement rewrittenBody,
            GeneratedLabelSymbol breakLabel,
            GeneratedLabelSymbol continueLabel,
            bool hasErrors)
        {
            var            startLabel           = new GeneratedLabelSymbol("start");
            BoundStatement ifConditionGotoStart = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, true, startLabel);

            if (this.GenerateDebugInfo)
            {
                ifConditionGotoStart = new BoundSequencePointWithSpan(syntax, ifConditionGotoStart, conditionSequencePointSpan);
            }

            // while (condition)
            //   body;
            //
            // becomes
            //
            // goto continue;
            // start:
            // {
            //     body
            //     continue:
            //     GotoIfTrue condition start;
            // }
            // break:

            BoundStatement gotoContinue = new BoundGotoStatement(syntax, continueLabel);

            if (this.GenerateDebugInfo)
            {
                // mark the initial jump as hidden. We do it to tell that this is not a part of previous statement. This
                // jump may be a target of another jump (for example if loops are nested) and that would give the
                // impression that the previous statement is being re-executed.
                gotoContinue = new BoundSequencePoint(null, gotoContinue);
            }

            return(BoundStatementList.Synthesized(syntax, hasErrors,
                                                  gotoContinue,
                                                  new BoundLabelStatement(syntax, startLabel),
                                                  rewrittenBody,
                                                  new BoundLabelStatement(syntax, continueLabel),
                                                  ifConditionGotoStart,
                                                  new BoundLabelStatement(syntax, breakLabel)));
        }
        public override BoundNode VisitExpressionStatement(BoundExpressionStatement node)
        {
            var syntax            = node.Syntax;
            var loweredExpression = VisitUnusedExpression(node.Expression);

            if (loweredExpression == null)
            {
                // NOTE: not using a BoundNoOpStatement, since we don't want a nop to be emitted.
                // CONSIDER: could use a BoundNoOpStatement (DevDiv #12943).
                return(BoundStatementList.Synthesized(syntax));
            }
            else
            {
                return(AddSequencePoint(node.Update(loweredExpression)));
            }
        }
Beispiel #12
0
        public override BoundNode VisitDoStatement(BoundDoStatement node)
        {
            Debug.Assert(node != null);

            var rewrittenCondition = (BoundExpression)Visit(node.Condition);
            var rewrittenBody      = (BoundStatement)Visit(node.Body);
            var startLabel         = new GeneratedLabelSymbol("start");

            var syntax = node.Syntax;

            // EnC: We need to insert a hidden sequence point to handle function remapping in case
            // the containing method is edited while methods invoked in the condition are being executed.
            BoundStatement ifConditionGotoStart = new BoundConditionalGoto(syntax, AddConditionSequencePoint(rewrittenCondition, node), true, startLabel);

            if (this.GenerateDebugInfo)
            {
                var doSyntax = (DoStatementSyntax)syntax;
                var span     = TextSpan.FromBounds(
                    doSyntax.WhileKeyword.SpanStart,
                    doSyntax.SemicolonToken.Span.End);

                ifConditionGotoStart = new BoundSequencePointWithSpan(doSyntax, ifConditionGotoStart, span);
            }

            // do
            //   body
            // while (condition);
            //
            // becomes
            //
            // start:
            // {
            //   body
            //   continue:
            //   sequence point
            //   GotoIfTrue condition start;
            // }
            // break:

            return(BoundStatementList.Synthesized(syntax, node.HasErrors,
                                                  new BoundLabelStatement(syntax, startLabel),
                                                  rewrittenBody,
                                                  new BoundLabelStatement(syntax, node.ContinueLabel),
                                                  ifConditionGotoStart,
                                                  new BoundLabelStatement(syntax, node.BreakLabel)));
        }
Beispiel #13
0
        public override BoundNode VisitLocalDeconstructionDeclaration(BoundLocalDeconstructionDeclaration node)
        {
            var syntax            = node.Syntax;
            var loweredExpression = VisitUnusedExpression(node.Assignment);

            if (loweredExpression == null)
            {
                // NOTE: not using a BoundNoOpStatement, since we don't want a nop to be emitted.
                // CONSIDER: could use a BoundNoOpStatement (DevDiv #12943).
                return(BoundStatementList.Synthesized(syntax));
            }
            else
            {
                BoundStatement result = new BoundExpressionStatement(loweredExpression.Syntax, loweredExpression, node.HasErrors);
                result.WasCompilerGenerated = node.WasCompilerGenerated;
                if (this.Instrument && !node.WasCompilerGenerated)
                {
                    result = _instrumenter.InstrumentLocalDeconstructionDeclaration(node, result);
                }

                return(result);
            }
        }
 public override BoundNode VisitExpressionStatement(BoundExpressionStatement node)
 {
     // NOTE: not using a BoundNoOpStatement, since we don't want a nop to be emitted.
     // CONSIDER: could use a BoundNoOpStatement (DevDiv #12943).
     return(RewriteExpressionStatement(node) ?? BoundStatementList.Synthesized(node.Syntax));
 }
        private BoundStatement RewriteWhileStatement(
            CSharpSyntaxNode syntax,
            ImmutableArray <LocalSymbol> innerLocals,
            BoundExpression rewrittenCondition,
            TextSpan conditionSequencePointSpan,
            BoundStatement rewrittenBody,
            GeneratedLabelSymbol breakLabel,
            GeneratedLabelSymbol continueLabel,
            bool hasErrors)
        {
            if (!innerLocals.IsDefaultOrEmpty)
            {
                var walker = new AnyLocalCapturedInALambdaWalker(innerLocals);

                if (walker.Analyze(rewrittenCondition) || walker.Analyze(rewrittenBody))
                {
                    // If any inner local is captured within a lambda, we need to enter scope-block
                    // always from the top, that is where an instance of a display class will be created.
                    // The IL will be less optimal, but this shouldn't be a problem, given presence of lambdas.

                    // while (condition)
                    //   body;
                    //
                    // becomes
                    //
                    // continue:
                    // {
                    //     GotoIfFalse condition break;
                    //     body
                    //     goto continue;
                    // }
                    // break:

                    // TODO: We could perform more fine analysis.
                    // If locals declared in condition (the innerLocals) are captured, but not referenced in the body, we could use optimal IL by creating
                    // another block around the condition and use it as a scope for the locals declared in condition.
                    // This optimization can be applied to 'for' as well, while-body === for-body + increment.
                    // Note however that the scope adjusments will likely be observable during debugging, in locals window.

                    BoundStatement ifNotConditionGotoBreak = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, false, breakLabel);

                    if (this.generateDebugInfo)
                    {
                        ifNotConditionGotoBreak = new BoundSequencePointWithSpan(syntax, ifNotConditionGotoBreak, conditionSequencePointSpan);
                    }

                    return(BoundStatementList.Synthesized(syntax, hasErrors,
                                                          new BoundLabelStatement(syntax, continueLabel),
                                                          new BoundBlock(syntax,
                                                                         innerLocals,
                                                                         ImmutableArray.Create <BoundStatement>(
                                                                             ifNotConditionGotoBreak,
                                                                             rewrittenBody,
                                                                             new BoundGotoStatement(syntax, continueLabel))),
                                                          new BoundLabelStatement(syntax, breakLabel)));
                }
            }

            var            startLabel           = new GeneratedLabelSymbol("start");
            BoundStatement ifConditionGotoStart = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, true, startLabel);

            if (this.generateDebugInfo)
            {
                ifConditionGotoStart = new BoundSequencePointWithSpan(syntax, ifConditionGotoStart, conditionSequencePointSpan);
            }

            // while (condition)
            //   body;
            //
            // becomes
            //
            // goto continue;
            // start:
            // {
            //     body
            //     continue:
            //     GotoIfTrue condition start;
            // }
            // break:

            BoundStatement gotoContinue = new BoundGotoStatement(syntax, continueLabel);

            if (this.generateDebugInfo)
            {
                // mark the initial jump as hidden. We do it to tell that this is not a part of previous statement. This
                // jump may be a target of another jump (for example if loops are nested) and that would give the
                // impression that the previous statement is being re-executed.
                gotoContinue = new BoundSequencePoint(null, gotoContinue);
            }

            if (!innerLocals.IsDefaultOrEmpty)
            {
                return(BoundStatementList.Synthesized(syntax, hasErrors,
                                                      gotoContinue,
                                                      new BoundLabelStatement(syntax, startLabel),
                                                      new BoundBlock(syntax,
                                                                     innerLocals,
                                                                     ImmutableArray.Create <BoundStatement>(
                                                                         rewrittenBody,
                                                                         new BoundLabelStatement(syntax, continueLabel),
                                                                         ifConditionGotoStart)),
                                                      new BoundLabelStatement(syntax, breakLabel)));
            }

            return(BoundStatementList.Synthesized(syntax, hasErrors,
                                                  gotoContinue,
                                                  new BoundLabelStatement(syntax, startLabel),
                                                  rewrittenBody,
                                                  new BoundLabelStatement(syntax, continueLabel),
                                                  ifConditionGotoStart,
                                                  new BoundLabelStatement(syntax, breakLabel)));
        }
Beispiel #16
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;
            }
        }