/// <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); }
internal static BoundStatement Rewrite(BoundStatement body, MethodSymbol method, TypeCompilationState compilationState, DiagnosticBag diagnostics) { var tempSubstitution = PooledDictionary <LocalSymbol, LocalSymbol> .GetInstance(); var spiller = new SpillSequenceSpiller(method, body.Syntax, compilationState, tempSubstitution, diagnostics); BoundNode result = spiller.Visit(body); result = LocalSubstituter.Rewrite(tempSubstitution, result); tempSubstitution.Free(); return((BoundStatement)result); }