protected virtual BoundStatement GenerateSetResultCall()
 {
     // builder.SetResult([RetVal])
     return(F.ExpressionStatement(
                F.Call(
                    F.Field(F.This(), _asyncMethodBuilderField),
                    _asyncMethodBuilderMemberCollection.SetResult,
                    _method.IsGenericTaskReturningAsync(F.Compilation)
                 ? ImmutableArray.Create <BoundExpression>(F.Local(_exprRetValue))
                 : ImmutableArray <BoundExpression> .Empty)));
 }
        internal AsyncMethodToStateMachineRewriter(
            MethodSymbol method,
            int methodOrdinal,
            AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection,
            SyntheticBoundNodeFactory F,
            FieldSymbol state,
            FieldSymbol builder,
            IReadOnlySet <Symbol> hoistedVariables,
            IReadOnlyDictionary <Symbol, CapturedSymbolReplacement> nonReusableLocalProxies,
            SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals,
            VariableSlotAllocator slotAllocatorOpt,
            int nextFreeHoistedLocalSlot,
            DiagnosticBag diagnostics)
            : base(F, method, state, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics, useFinalizerBookkeeping: false)
        {
            _method = method;
            _asyncMethodBuilderMemberCollection = asyncMethodBuilderMemberCollection;
            _asyncMethodBuilderField            = builder;
            _exprReturnLabel = F.GenerateLabel("exprReturn");
            _exitLabel       = F.GenerateLabel("exitLabel");

            _exprRetValue = method.IsGenericTaskReturningAsync(F.Compilation)
                ? F.SynthesizedLocal(asyncMethodBuilderMemberCollection.ResultType, syntax: F.Syntax, kind: SynthesizedLocalKind.AsyncMethodReturnValue)
                : null;

            _dynamicFactory = new LoweredDynamicOperationFactory(F, methodOrdinal);
            _awaiterFields  = new Dictionary <TypeSymbol, FieldSymbol>(TypeSymbol.EqualsIgnoringDynamicAndTupleNamesComparer);
            _nextAwaiterId  = slotAllocatorOpt?.PreviousAwaiterSlotCount ?? 0;
        }
Exemple #3
0
        internal AsyncMethodToStateMachineRewriter(
            MethodSymbol method,
            AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection,
            SyntheticBoundNodeFactory F,
            FieldSymbol state,
            FieldSymbol builder,
            HashSet <Symbol> variablesCaptured,
            Dictionary <Symbol, CapturedSymbolReplacement> initialProxies,
            DiagnosticBag diagnostics,
            bool generateDebugInfo)
            : base(F, method, state, variablesCaptured, initialProxies, diagnostics,
                   useFinalizerBookkeeping: false,
                   generateDebugInfo: generateDebugInfo)
        {
            this.method = method;
            this.asyncMethodBuilderMemberCollection = asyncMethodBuilderMemberCollection;
            this.asyncMethodBuilderField            = builder;
            this.exprReturnLabel = F.GenerateLabel("exprReturn");
            this.exitLabel       = F.GenerateLabel("exitLabel");

            this.exprRetValue = method.IsGenericTaskReturningAsync(F.Compilation)
                ? F.SynthesizedLocal(asyncMethodBuilderMemberCollection.ResultType, kind: SynthesizedLocalKind.AsyncMethodReturnValue)
                : null;

            this.dynamicFactory = new LoweredDynamicOperationFactory(F);
        }
            internal AsyncMethodToClassRewriter(
                MethodSymbol method,
                AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection,
                SyntheticBoundNodeFactory factory,
                FieldSymbol state,
                FieldSymbol builder,
                Dictionary <Symbol, CapturedSymbol> localProxies,
                DiagnosticBag diagnostics)
                : base(factory, state, localProxies, diagnostics)
            {
                this.method = method;
                this.asyncMethodBuilderMemberCollection = asyncMethodBuilderMemberCollection;
                this.asyncMethodBuilderField            = builder;
                this.exprReturnLabel = factory.GenerateLabel("exprReturn");

                this.exprRetValue = method.IsGenericTaskReturningAsync()
                    ? factory.SynthesizedLocal(asyncMethodBuilderMemberCollection.ResultType, GeneratedNames.AsyncExprRetValueFieldName())
                    : null;

                this.dynamicFactory = new LoweredDynamicOperationFactory(factory);
            }
        /// <summary>
        /// Generate the body for <c>MoveNext()</c>.
        /// </summary>
        internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod)
        {
            F.CurrentMethod = moveNextMethod;

            BoundStatement rewrittenBody = (BoundStatement)Visit(body);

            ImmutableArray <StateMachineFieldSymbol> rootScopeHoistedLocals;

            TryUnwrapBoundStateMachineScope(ref rewrittenBody, out rootScopeHoistedLocals);

            var bodyBuilder = ArrayBuilder <BoundStatement> .GetInstance();

            bodyBuilder.Add(F.HiddenSequencePoint());
            bodyBuilder.Add(F.Assignment(F.Local(cachedState), F.Field(F.This(), stateField)));
            bodyBuilder.Add(CacheThisIfNeeded());

            var exceptionLocal = F.SynthesizedLocal(F.WellKnownType(WellKnownType.System_Exception));

            bodyBuilder.Add(
                F.Try(
                    F.Block(ImmutableArray <LocalSymbol> .Empty,
                            // switch (state) ...
                            F.HiddenSequencePoint(),
                            Dispatch(),
                            // [body]
                            rewrittenBody
                            ),
                    F.CatchBlocks(
                        new BoundCatchBlock(
                            F.Syntax,
                            ImmutableArray.Create(exceptionLocal),
                            F.Local(exceptionLocal),
                            exceptionLocal.Type,
                            exceptionFilterOpt: null,
                            body: F.Block(
                                // this.state = finishedState
                                F.Assignment(F.Field(F.This(), stateField), F.Literal(StateMachineStates.FinishedStateMachine)),
                                // builder.SetException(ex)
                                F.ExpressionStatement(
                                    F.Call(
                                        F.Field(F.This(), _asyncMethodBuilderField),
                                        _asyncMethodBuilderMemberCollection.SetException,
                                        F.Local(exceptionLocal))),
                                GenerateReturn(false)),
                            isSynthesizedAsyncCatchAll: true)
                        )
                    )
                );

            // ReturnLabel (for the rewritten return expressions in the user's method body)
            bodyBuilder.Add(F.Label(_exprReturnLabel));

            // this.state = finishedState
            var stateDone = F.Assignment(F.Field(F.This(), stateField), F.Literal(StateMachineStates.FinishedStateMachine));
            var block     = body.Syntax as BlockSyntax;

            if (block == null)
            {
                // this happens, for example, in (async () => await e) where there is no block syntax
                bodyBuilder.Add(stateDone);
            }
            else
            {
                bodyBuilder.Add(F.SequencePointWithSpan(block, block.CloseBraceToken.Span, stateDone));
                bodyBuilder.Add(F.HiddenSequencePoint());
                // The remaining code is hidden to hide the fact that it can run concurrently with the task's continuation
            }

            // builder.SetResult([RetVal])
            bodyBuilder.Add(
                F.ExpressionStatement(
                    F.Call(
                        F.Field(F.This(), _asyncMethodBuilderField),
                        _asyncMethodBuilderMemberCollection.SetResult,
                        _method.IsGenericTaskReturningAsync(F.Compilation)
                            ? ImmutableArray.Create <BoundExpression>(F.Local(_exprRetValue))
                            : ImmutableArray <BoundExpression> .Empty)));

            // this code is hidden behind a hidden sequence point.
            bodyBuilder.Add(F.Label(_exitLabel));
            bodyBuilder.Add(F.Return());

            var newStatements = bodyBuilder.ToImmutableAndFree();

            var locals = ArrayBuilder <LocalSymbol> .GetInstance();

            locals.Add(cachedState);
            if ((object)cachedThis != null)
            {
                locals.Add(cachedThis);
            }

            if ((object)_exprRetValue != null)
            {
                locals.Add(_exprRetValue);
            }

            var newBody =
                F.SequencePoint(
                    body.Syntax,
                    F.Block(
                        locals.ToImmutableAndFree(),
                        newStatements));

            if (rootScopeHoistedLocals.Length > 0)
            {
                newBody = MakeStateMachineScope(rootScopeHoistedLocals, newBody);
            }

            F.CloseMethod(newBody);
        }
        internal static bool TryCreate(SyntheticBoundNodeFactory F, MethodSymbol method, TypeMap typeMap, out AsyncMethodBuilderMemberCollection collection)
        {
            if (method.IsVoidReturningAsync())
            {
                var builderType = F.WellKnownType(WellKnownType.System_Runtime_CompilerServices_AsyncVoidMethodBuilder);
                Debug.Assert((object)builderType != null);
                MethodSymbol createBuilderMethod;
                bool         customBuilder = false;
                TryGetBuilderMember <MethodSymbol>(
                    F,
                    WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__Create,
                    builderType,
                    customBuilder,
                    out createBuilderMethod);
                if ((object)createBuilderMethod == null)
                {
                    collection = default(AsyncMethodBuilderMemberCollection);
                    return(false);
                }
                return(TryCreate(
                           F,
                           customBuilder: customBuilder,
                           builderType: builderType,
                           resultType: F.SpecialType(SpecialType.System_Void),
                           createBuilderMethod: createBuilderMethod,
                           taskProperty: null,
                           setException: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__SetException,
                           setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__SetResult,
                           awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__AwaitOnCompleted,
                           awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__AwaitUnsafeOnCompleted,
                           start: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__Start_T,
                           setStateMachine: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__SetStateMachine,
                           collection: out collection));
            }

            if (method.IsTaskReturningAsync(F.Compilation))
            {
                var             returnType = (NamedTypeSymbol)method.ReturnType.TypeSymbol;
                NamedTypeSymbol builderType;
                MethodSymbol    createBuilderMethod = null;
                PropertySymbol  taskProperty        = null;

                object builderArgument;
                bool   customBuilder = returnType.IsCustomTaskType(out builderArgument);
                if (customBuilder)
                {
                    builderType = ValidateBuilderType(F, builderArgument, returnType.DeclaredAccessibility, isGeneric: false);
                    if ((object)builderType != null)
                    {
                        taskProperty        = GetCustomTaskProperty(F, builderType, returnType);
                        createBuilderMethod = GetCustomCreateMethod(F, builderType);
                    }
                }
                else
                {
                    builderType = F.WellKnownType(WellKnownType.System_Runtime_CompilerServices_AsyncTaskMethodBuilder);
                    Debug.Assert((object)builderType != null);
                    TryGetBuilderMember <MethodSymbol>(
                        F,
                        WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__Create,
                        builderType,
                        customBuilder,
                        out createBuilderMethod);
                    TryGetBuilderMember <PropertySymbol>(
                        F,
                        WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__Task,
                        builderType,
                        customBuilder,
                        out taskProperty);
                }
                if ((object)builderType == null ||
                    (object)createBuilderMethod == null ||
                    (object)taskProperty == null)
                {
                    collection = default(AsyncMethodBuilderMemberCollection);
                    return(false);
                }
                return(TryCreate(
                           F,
                           customBuilder: customBuilder,
                           builderType: builderType,
                           resultType: F.SpecialType(SpecialType.System_Void),
                           createBuilderMethod: createBuilderMethod,
                           taskProperty: taskProperty,
                           setException: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__SetException,
                           setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__SetResult,
                           awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__AwaitOnCompleted,
                           awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__AwaitUnsafeOnCompleted,
                           start: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__Start_T,
                           setStateMachine: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__SetStateMachine,
                           collection: out collection));
            }

            if (method.IsGenericTaskReturningAsync(F.Compilation))
            {
                var returnType = (NamedTypeSymbol)method.ReturnType.TypeSymbol;
                var resultType = returnType.TypeArgumentsNoUseSiteDiagnostics.Single().TypeSymbol;
                if (resultType.IsDynamic())
                {
                    resultType = F.SpecialType(SpecialType.System_Object);
                }
                if (typeMap != null)
                {
                    resultType = typeMap.SubstituteType(resultType).TypeSymbol;
                }
                returnType = returnType.ConstructedFrom.Construct(resultType);
                NamedTypeSymbol builderType;
                MethodSymbol    createBuilderMethod = null;
                PropertySymbol  taskProperty        = null;

                object builderArgument;
                bool   customBuilder = returnType.IsCustomTaskType(out builderArgument);
                if (customBuilder)
                {
                    builderType = ValidateBuilderType(F, builderArgument, returnType.DeclaredAccessibility, isGeneric: true);
                    if ((object)builderType != null)
                    {
                        builderType         = builderType.ConstructedFrom.Construct(resultType);
                        taskProperty        = GetCustomTaskProperty(F, builderType, returnType);
                        createBuilderMethod = GetCustomCreateMethod(F, builderType);
                    }
                }
                else
                {
                    builderType = F.WellKnownType(WellKnownType.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T);
                    Debug.Assert((object)builderType != null);
                    builderType = builderType.Construct(resultType);
                    TryGetBuilderMember <MethodSymbol>(
                        F,
                        WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__Create,
                        builderType,
                        customBuilder,
                        out createBuilderMethod);
                    TryGetBuilderMember <PropertySymbol>(
                        F,
                        WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__Task,
                        builderType,
                        customBuilder,
                        out taskProperty);
                }
                if ((object)builderType == null ||
                    (object)taskProperty == null ||
                    (object)createBuilderMethod == null)
                {
                    collection = default(AsyncMethodBuilderMemberCollection);
                    return(false);
                }
                return(TryCreate(
                           F,
                           customBuilder: customBuilder,
                           builderType: builderType,
                           resultType: resultType,
                           createBuilderMethod: createBuilderMethod,
                           taskProperty: taskProperty,
                           setException: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__SetException,
                           setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__SetResult,
                           awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__AwaitOnCompleted,
                           awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__AwaitUnsafeOnCompleted,
                           start: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__Start_T,
                           setStateMachine: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__SetStateMachine,
                           collection: out collection));
            }

            throw ExceptionUtilities.UnexpectedValue(method);
        }
Exemple #7
0
        /// <summary>
        /// Generate the body for <c>MoveNext()</c>.
        /// </summary>
        internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod)
        {
            F.CurrentMethod = moveNextMethod;

            int initialState;
            GeneratedLabelSymbol initialLabel;

            AddState(out initialState, out initialLabel);

            var exceptionLocal = F.SynthesizedLocal(F.WellKnownType(WellKnownType.System_Exception));

            var bodyBuilder = ArrayBuilder <BoundStatement> .GetInstance();

            bodyBuilder.Add(F.HiddenSequencePoint());
            bodyBuilder.Add(F.Assignment(F.Local(cachedState), F.Field(F.This(), stateField)));

            BoundStatement rewrittenBody = (BoundStatement)Visit(body);

            bodyBuilder.Add(
                F.Try(
                    F.Block(ImmutableArray <LocalSymbol> .Empty,
                            // switch (state) ...
                            F.HiddenSequencePoint(),
                            Dispatch(),
                            F.Label(initialLabel),
                            // [body]
                            rewrittenBody
                            ),
                    F.CatchBlocks(
                        F.Catch(
                            exceptionLocal,
                            F.Block(
                                F.NoOp(method.ReturnsVoid ? NoOpStatementFlavor.AsyncMethodCatchHandler : NoOpStatementFlavor.Default),
                                // this.state = finishedState
                                F.Assignment(F.Field(F.This(), stateField), F.Literal(StateMachineStates.FinishedStateMachine)),
                                // builder.SetException(ex)
                                F.ExpressionStatement(
                                    F.Call(
                                        F.Field(F.This(), asyncMethodBuilderField),
                                        asyncMethodBuilderMemberCollection.SetException,
                                        F.Local(exceptionLocal))),
                                GenerateReturn(false)
                                )
                            )
                        )
                    ));

            // ReturnLabel (for the rewritten return expressions in the user's method body)
            bodyBuilder.Add(F.Label(exprReturnLabel));

            // this.state = finishedState
            var stateDone = F.Assignment(F.Field(F.This(), stateField), F.Literal(StateMachineStates.FinishedStateMachine));
            var block     = body.Syntax as BlockSyntax;

            if (block == null)
            {
                // this happens, for example, in (async () => await e) where there is no block syntax
                bodyBuilder.Add(stateDone);
            }
            else
            {
                bodyBuilder.Add(F.SequencePointWithSpan(block, block.CloseBraceToken.Span, stateDone));
                bodyBuilder.Add(F.HiddenSequencePoint());
                // The remaining code is hidden to hide the fact that it can run concurrently with the task's continuation
            }

            // builder.SetResult([RetVal])
            bodyBuilder.Add(
                F.ExpressionStatement(
                    F.Call(
                        F.Field(F.This(), asyncMethodBuilderField),
                        asyncMethodBuilderMemberCollection.SetResult,
                        method.IsGenericTaskReturningAsync(F.Compilation)
                            ? ImmutableArray.Create <BoundExpression>(F.Local(exprRetValue))
                            : ImmutableArray <BoundExpression> .Empty)));

            // this code is hidden behind a hidden sequence point.
            bodyBuilder.Add(F.Label(this.exitLabel));
            bodyBuilder.Add(F.Return());

            var newBody = bodyBuilder.ToImmutableAndFree();

            var locals = ArrayBuilder <LocalSymbol> .GetInstance();

            locals.Add(cachedState);
            if ((object)exprRetValue != null)
            {
                locals.Add(exprRetValue);
            }

            F.CloseMethod(
                F.SequencePoint(
                    body.Syntax,
                    F.Block(
                        locals.ToImmutableAndFree(),
                        newBody)));
        }
            /// <summary>
            /// Generate the body for MoveNext()
            /// </summary>
            internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod)
            {
                F.CurrentMethod = moveNextMethod;

                int initialState;
                GeneratedLabelSymbol initialLabel;

                AddState(out initialState, out initialLabel);

                var exceptionLocal = F.SynthesizedLocal(F.WellKnownType(WellKnownType.System_Exception), GeneratedNames.AsyncExceptionFieldName());

                BoundStatement rewrittenBody = (BoundStatement)Visit(body);

                rewrittenBody = (BoundStatement) new AwaitLoweringRewriterPass1(F).Visit(rewrittenBody);
                rewrittenBody = (BoundStatement) new AwaitLoweringRewriterPass2(F, CompilationState).Visit(rewrittenBody);

                UnloweredSpillNodeVerifier.Verify(rewrittenBody);

                var bodyBuilder = ArrayBuilder <BoundStatement> .GetInstance();

                bodyBuilder.Add(
                    F.Try(
                        F.Block(
                            ReadOnlyArray <LocalSymbol> .Empty,
                            // switch (state) ...
                            Dispatch(),
                            // TODO(t-liam) - debugging support...
                            // dev11(LanguageAnalysis\Compiler\ResumableRewriter.cpp:325) does codegen here to add a
                            // debug nop and the 'NoCullNormalExit' label
                            F.Label(initialLabel),
                            // [body]
                            rewrittenBody
                            ),
                        F.CatchBlocks(
                            // TODO(t-liam) - debugging support...
                            // dev11(LanguageAnalysis\Compiler\ResumableRewriter.cpp:391)
                            // // Async void method generated catch handlers have their IL start offset
                            // // recorded to the PDB for special exception handling in the debugger.
                            // // Mark the EXPRHANDLER as such so we know to record its offset later.
                            F.Catch(
                                F.WellKnownType(WellKnownType.System_Exception),
                                exceptionLocal,
                                F.Block(
                                    // state = finishedState
                                    F.Assignment(F.Field(F.This(), state), F.Literal(StateMachineStates.FinishedStateMachine)),
                                    // builder.SetException(ex)
                                    F.ExpressionStatement(
                                        F.Call(
                                            F.Field(F.This(), asyncMethodBuilderField),
                                            asyncMethodBuilderMemberCollection.SetException,
                                            ReadOnlyArray <BoundExpression> .CreateFrom(F.Local(exceptionLocal)))),
                                    F.Return()
                                    )
                                )
                            )
                        ));

                // ReturnLabel (for the rewritten return expressions in the user's method body)
                bodyBuilder.Add(F.Label(exprReturnLabel));

                // state = finishedState
                bodyBuilder.Add(F.Assignment(F.Field(F.This(), state), F.Literal(StateMachineStates.FinishedStateMachine)));

                // builder.SetResult([RetVal])
                bodyBuilder.Add(
                    F.ExpressionStatement(
                        F.Call(
                            F.Field(F.This(), asyncMethodBuilderField),
                            asyncMethodBuilderMemberCollection.SetResult,
                            method.IsGenericTaskReturningAsync()
                                ? ReadOnlyArray <BoundExpression> .CreateFrom(F.Local(exprRetValue))
                                : ReadOnlyArray <BoundExpression> .Empty)));

                bodyBuilder.Add(F.Return());

                var newBody = bodyBuilder.ToReadOnlyAndFree();

                F.CloseMethod(
                    F.SequencePoint(
                        body.Syntax,
                        F.Block(
                            exprRetValue != null ? ReadOnlyArray <LocalSymbol> .CreateFrom(exprRetValue) : ReadOnlyArray <LocalSymbol> .Empty,
                            newBody)));
            }
Exemple #9
0
        internal static bool TryCreate(SyntheticBoundNodeFactory F, MethodSymbol method, TypeMap typeMap, out AsyncMethodBuilderMemberCollection collection)
        {
            if (method.IsVoidReturningAsync())
            {
                return(TryCreate(
                           F: F,

                           builderType: F.WellKnownType(WellKnownType.System_Runtime_CompilerServices_AsyncVoidMethodBuilder),
                           resultType: F.SpecialType(SpecialType.System_Void),

                           setException: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__SetException,
                           setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__SetResult,
                           awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__AwaitOnCompleted,
                           awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__AwaitUnsafeOnCompleted,
                           start: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__Start_T,
                           setStateMachine: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__SetStateMachine,
                           task: null,
                           collection: out collection));
            }

            if (method.IsTaskReturningAsync(F.Compilation))
            {
                NamedTypeSymbol builderType = F.WellKnownType(WellKnownType.System_Runtime_CompilerServices_AsyncTaskMethodBuilder);

                PropertySymbol task;
                if (!TryGetWellKnownPropertyAsMember(F, WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__Task, builderType, out task))
                {
                    collection = default(AsyncMethodBuilderMemberCollection);
                    return(false);
                }

                return(TryCreate(
                           F: F,

                           builderType: F.WellKnownType(WellKnownType.System_Runtime_CompilerServices_AsyncTaskMethodBuilder),
                           resultType: F.SpecialType(SpecialType.System_Void),

                           setException: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__SetException,
                           setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__SetResult,
                           awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__AwaitOnCompleted,
                           awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__AwaitUnsafeOnCompleted,
                           start: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__Start_T,
                           setStateMachine: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__SetStateMachine,
                           task: task,
                           collection: out collection));
            }

            if (method.IsGenericTaskReturningAsync(F.Compilation))
            {
                TypeSymbol resultType = method.ReturnType.GetMemberTypeArgumentsNoUseSiteDiagnostics().Single();

                if (resultType.IsDynamic())
                {
                    resultType = F.SpecialType(SpecialType.System_Object);
                }

                if (typeMap != null)
                {
                    resultType = typeMap.SubstituteType(resultType);
                }

                NamedTypeSymbol builderType = F.WellKnownType(WellKnownType.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T).Construct(resultType);

                PropertySymbol task;
                if (!TryGetWellKnownPropertyAsMember(F, WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__Task, builderType, out task))
                {
                    collection = default(AsyncMethodBuilderMemberCollection);
                    return(false);
                }

                return(TryCreate(
                           F: F,

                           builderType: builderType,
                           resultType: resultType,

                           setException: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__SetException,
                           setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__SetResult,
                           awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__AwaitOnCompleted,
                           awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__AwaitUnsafeOnCompleted,
                           start: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__Start_T,
                           setStateMachine: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__SetStateMachine,
                           task: task,
                           collection: out collection));
            }

            throw ExceptionUtilities.UnexpectedValue(method);
        }