Beispiel #1
0
        /// <summary>
        /// Lower a block of code by performing local rewritings.
        /// </summary>
        public static BoundStatement Rewrite(
            CSharpCompilation compilation,
            MethodSymbol method,
            int methodOrdinal,
            NamedTypeSymbol containingType,
            BoundStatement statement,
            TypeCompilationState compilationState,
            SynthesizedSubmissionFields previousSubmissionFields,
            bool allowOmissionOfConditionalCalls,
            bool instrumentForDynamicAnalysis,
            ref ImmutableArray <SourceSpan> dynamicAnalysisSpans,
            DebugDocumentProvider debugDocumentProvider,
            BindingDiagnosticBag diagnostics,
            out bool sawLambdas,
            out bool sawLocalFunctions,
            out bool sawAwaitInExceptionHandler)
        {
            Debug.Assert(statement != null);
            Debug.Assert(compilationState != null);

            try
            {
                var factory = new SyntheticBoundNodeFactory(method, statement.Syntax, compilationState, diagnostics);
                DynamicAnalysisInjector?dynamicInstrumenter = instrumentForDynamicAnalysis ? DynamicAnalysisInjector.TryCreate(method, statement, factory, diagnostics, debugDocumentProvider, Instrumenter.NoOp) : null;

                // We don’t want IL to differ based upon whether we write the PDB to a file/stream or not.
                // Presence of sequence points in the tree affects final IL, therefore, we always generate them.
                var localRewriter = new LocalRewriter(compilation, method, methodOrdinal, statement, containingType, factory, previousSubmissionFields, allowOmissionOfConditionalCalls, diagnostics,
                                                      dynamicInstrumenter != null ? new DebugInfoInjector(dynamicInstrumenter) : DebugInfoInjector.Singleton);

                statement.CheckLocalsDefined();
                var loweredStatement = localRewriter.VisitStatement(statement);
                Debug.Assert(loweredStatement is { });
                loweredStatement.CheckLocalsDefined();
                sawLambdas                 = localRewriter._sawLambdas;
                sawLocalFunctions          = localRewriter._availableLocalFunctionOrdinal != 0;
                sawAwaitInExceptionHandler = localRewriter._sawAwaitInExceptionHandler;

                if (localRewriter._needsSpilling && !loweredStatement.HasErrors)
                {
                    // Move spill sequences to a top-level statement. This handles "lifting" await and the switch expression.
                    var spilledStatement = SpillSequenceSpiller.Rewrite(loweredStatement, method, compilationState, diagnostics);
                    spilledStatement.CheckLocalsDefined();
                    loweredStatement = spilledStatement;
                }

                if (dynamicInstrumenter != null)
                {
                    dynamicAnalysisSpans = dynamicInstrumenter.DynamicAnalysisSpans;
                }
#if DEBUG
                LocalRewritingValidator.Validate(loweredStatement);
                localRewriter.AssertNoPlaceholderReplacements();
#endif
                return(loweredStatement);
            }