/// <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, DiagnosticBag 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 = (BoundStatement)localRewriter.Visit(statement); loweredStatement.CheckLocalsDefined(); sawLambdas = localRewriter._sawLambdas; sawLocalFunctions = localRewriter._sawLocalFunctions; 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); #endif return(loweredStatement); } catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex) { diagnostics.Add(ex.Diagnostic); sawLambdas = sawLocalFunctions = sawAwaitInExceptionHandler = false; return(new BoundBadStatement(statement.Syntax, ImmutableArray.Create <BoundNode>(statement), hasErrors: true)); } }
private SpillSequenceSpiller(MethodSymbol method, SyntaxNode syntaxNode, TypeCompilationState compilationState, PooledDictionary <LocalSymbol, LocalSymbol> tempSubstitution, DiagnosticBag diagnostics) { _F = new SyntheticBoundNodeFactory(method, syntaxNode, compilationState, diagnostics); _F.CurrentFunction = method; _tempSubstitution = tempSubstitution; }
private static string MakeName(VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, MethodSymbol kickoffMethod, int kickoffMethodOrdinal) { return(slotAllocatorOpt?.PreviousStateMachineTypeName ?? GeneratedNames.MakeStateMachineTypeName(kickoffMethod.Name, kickoffMethodOrdinal, compilationState.ModuleBuilderOpt.CurrentGenerationOrdinal)); }
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); }
public StateMachineTypeSymbol(VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, MethodSymbol kickoffMethod, int kickoffMethodOrdinal) : base(MakeName(slotAllocatorOpt, compilationState, kickoffMethod, kickoffMethodOrdinal), kickoffMethod) { Debug.Assert(kickoffMethod != null); this.KickoffMethod = kickoffMethod; }