internal AsyncIteratorRewriter( BoundStatement body, MethodSymbol method, int methodOrdinal, AsyncStateMachine stateMachineType, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics ) : base( body, method, methodOrdinal, stateMachineType, slotAllocatorOpt, compilationState, diagnostics ) { Debug.Assert( !TypeSymbol.Equals( method.IteratorElementTypeWithAnnotations.Type, null, TypeCompareKind.ConsiderEverything2 ) ); _isEnumerable = method.IsAsyncReturningIAsyncEnumerable( method.DeclaringCompilation ); Debug.Assert( _isEnumerable != method.IsAsyncReturningIAsyncEnumerator(method.DeclaringCompilation) ); }
internal static BoundStatement Rewrite( BoundStatement bodyWithAwaitLifted, MethodSymbol method, int methodOrdinal, ArrayBuilder <StateMachineStateDebugInfo> stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics, out AsyncStateMachine stateMachineType) { if (!method.IsAsync) { stateMachineType = null; return(bodyWithAwaitLifted); } CSharpCompilation compilation = method.DeclaringCompilation; bool isAsyncEnumerableOrEnumerator = method.IsAsyncReturningIAsyncEnumerable(compilation) || method.IsAsyncReturningIAsyncEnumerator(compilation); if (isAsyncEnumerableOrEnumerator && !method.IsIterator) { bool containsAwait = AwaitDetector.ContainsAwait(bodyWithAwaitLifted); diagnostics.Add(containsAwait ? ErrorCode.ERR_PossibleAsyncIteratorWithoutYield : ErrorCode.ERR_PossibleAsyncIteratorWithoutYieldOrAwait, method.Locations[0]); stateMachineType = null; return(bodyWithAwaitLifted); } // The CLR doesn't support adding fields to structs, so in order to enable EnC in an async method we need to generate a class. // For async-iterators, we also need to generate a class. var typeKind = (compilationState.Compilation.Options.EnableEditAndContinue || method.IsIterator) ? TypeKind.Class : TypeKind.Struct; stateMachineType = new AsyncStateMachine(slotAllocatorOpt, compilationState, method, methodOrdinal, typeKind); compilationState.ModuleBuilderOpt.CompilationState.SetStateMachineType(method, stateMachineType); AsyncRewriter rewriter = isAsyncEnumerableOrEnumerator ? new AsyncIteratorRewriter(bodyWithAwaitLifted, method, methodOrdinal, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics) : new AsyncRewriter(bodyWithAwaitLifted, method, methodOrdinal, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics); if (!rewriter.VerifyPresenceOfRequiredAPIs()) { return(bodyWithAwaitLifted); } try { return(rewriter.Rewrite()); } catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex) { diagnostics.Add(ex.Diagnostic); return(new BoundBadStatement(bodyWithAwaitLifted.Syntax, ImmutableArray.Create <BoundNode>(bodyWithAwaitLifted), hasErrors: true)); } }