예제 #1
0
            internal AsyncMethodToClassRewriter(
                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, GeneratedNames.AsyncExprRetValueFieldName())
                    : null;

                this.dynamicFactory = new LoweredDynamicOperationFactory(F);
            }
예제 #2
0
        internal AsyncIteratorMethodToStateMachineRewriter(MethodSymbol method,
                                                           int methodOrdinal,
                                                           AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection,
                                                           AsyncIteratorInfo asyncIteratorInfo,
                                                           SyntheticBoundNodeFactory F,
                                                           FieldSymbol state,
                                                           FieldSymbol builder,
                                                           IReadOnlySet <Symbol> hoistedVariables,
                                                           IReadOnlyDictionary <Symbol, CapturedSymbolReplacement> nonReusableLocalProxies,
                                                           SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals,
                                                           ArrayBuilder <StateMachineStateDebugInfo> stateMachineStateDebugInfoBuilder,
                                                           VariableSlotAllocator slotAllocatorOpt,
                                                           int nextFreeHoistedLocalSlot,
                                                           BindingDiagnosticBag diagnostics)
            : base(method, methodOrdinal, asyncMethodBuilderMemberCollection, F,
                   state, builder, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals,
                   stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics)
        {
            Debug.Assert(asyncIteratorInfo != null);

            _asyncIteratorInfo    = asyncIteratorInfo;
            _currentDisposalLabel = _exprReturnLabel;
            _exprReturnLabelTrue  = F.GenerateLabel("yieldReturn");

            _iteratorStateAllocator = new ResumableStateMachineStateAllocator(
                slotAllocatorOpt,
                firstState: StateMachineStates.FirstResumableAsyncIteratorState,
                increasing: false);
        }
예제 #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 AsyncMethodToStateMachineRewriter(
            MethodSymbol method,
            int methodOrdinal,
            AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection,
            SyntheticBoundNodeFactory F,
            FieldSymbol state,
            FieldSymbol builder,
            IReadOnlySet <Symbol> hoistedVariables,
            IReadOnlyDictionary <Symbol, CapturedSymbolReplacement> nonReusableLocalProxies,
            SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals,
            ArrayBuilder <StateMachineStateDebugInfo> stateMachineStateDebugInfoBuilder,
            VariableSlotAllocator slotAllocatorOpt,
            int nextFreeHoistedLocalSlot,
            BindingDiagnosticBag diagnostics)
            : base(F, method, state, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics)
        {
            _method = method;
            _asyncMethodBuilderMemberCollection = asyncMethodBuilderMemberCollection;
            _asyncMethodBuilderField            = builder;
            _exprReturnLabel = F.GenerateLabel("exprReturn");
            _exitLabel       = F.GenerateLabel("exitLabel");

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

            _dynamicFactory = new LoweredDynamicOperationFactory(F, methodOrdinal);
            _awaiterFields  = new Dictionary <TypeSymbol, FieldSymbol>(Symbols.SymbolEqualityComparer.IgnoringDynamicTupleNamesAndNullability);
            _nextAwaiterId  = slotAllocatorOpt?.PreviousAwaiterSlotCount ?? 0;

            _placeholderMap = new Dictionary <BoundValuePlaceholderBase, BoundExpression>();
        }
        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;
        }
        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.EqualsIgnoringDynamicComparer);
            _nextAwaiterId = slotAllocatorOpt?.PreviousAwaiterSlotCount ?? 0;
        }
예제 #7
0
        protected override BoundStatement GenerateStateMachineCreation(LocalSymbol stateMachineVariable, NamedTypeSymbol frameType)
        {
            try
            {
                var bodyBuilder = ArrayBuilder <BoundStatement> .GetInstance();

                // If the async method's result type is a type parameter of the method, then the AsyncTaskMethodBuilder<T>
                // needs to use the method's type parameters inside the rewritten method body. All other methods generated
                // during async rewriting are members of the synthesized state machine struct, and use the type parameters
                // structs type parameters.
                AsyncMethodBuilderMemberCollection methodScopeAsyncMethodBuilderMemberCollection;
                if (!AsyncMethodBuilderMemberCollection.TryCreate(F, method, null, out methodScopeAsyncMethodBuilderMemberCollection))
                {
                    return(new BoundBadStatement(F.Syntax, ImmutableArray <BoundNode> .Empty, hasErrors: true));
                }

                var builderVariable = F.SynthesizedLocal(methodScopeAsyncMethodBuilderMemberCollection.BuilderType, null);

                // local.$builder = System.Runtime.CompilerServices.AsyncTaskMethodBuilder<typeArgs>.Create();
                bodyBuilder.Add(
                    F.Assignment(
                        F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)),
                        F.StaticCall(_ignoreAccessibility ? BinderFlags.IgnoreAccessibility : BinderFlags.None, methodScopeAsyncMethodBuilderMemberCollection.BuilderType, "Create", ImmutableArray <TypeSymbol> .Empty)));

                // local.$stateField = NotStartedStateMachine
                bodyBuilder.Add(
                    F.Assignment(
                        F.Field(F.Local(stateMachineVariable), stateField.AsMember(frameType)),
                        F.Literal(StateMachineStates.NotStartedStateMachine)));

                bodyBuilder.Add(
                    F.Assignment(
                        F.Local(builderVariable),
                        F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType))));

                // local.$builder.Start(ref local) -- binding to the method AsyncTaskMethodBuilder<typeArgs>.Start()
                bodyBuilder.Add(
                    F.ExpressionStatement(
                        F.Call(
                            F.Local(builderVariable),
                            methodScopeAsyncMethodBuilderMemberCollection.Start.Construct(frameType),
                            ImmutableArray.Create <BoundExpression>(F.Local(stateMachineVariable)))));

                bodyBuilder.Add(method.IsVoidReturningAsync()
                    ? F.Return()
                    : F.Return(F.Property(F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)), "Task")));

                return(F.Block(
                           ImmutableArray.Create(builderVariable),
                           bodyBuilder.ToImmutableAndFree()));
            }
            catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
            {
                F.Diagnostics.Add(ex.Diagnostic);
                return(new BoundBadStatement(F.Syntax, ImmutableArray <BoundNode> .Empty, hasErrors: true));
            }
        }
예제 #8
0
        protected override BoundStatement GenerateStateMachineCreation(LocalSymbol stateMachineVariable, NamedTypeSymbol frameType, IReadOnlyDictionary <Symbol, CapturedSymbolReplacement> proxies)
        {
            // If the async method's result type is a type parameter of the method, then the AsyncTaskMethodBuilder<T>
            // needs to use the method's type parameters inside the rewritten method body. All other methods generated
            // during async rewriting are members of the synthesized state machine struct, and use the type parameters
            // structs type parameters.
            AsyncMethodBuilderMemberCollection methodScopeAsyncMethodBuilderMemberCollection;

            if (!AsyncMethodBuilderMemberCollection.TryCreate(F, method, null, out methodScopeAsyncMethodBuilderMemberCollection))
            {
                return(new BoundBadStatement(F.Syntax, ImmutableArray <BoundNode> .Empty, hasErrors: true));
            }

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

            // local.$builder = System.Runtime.CompilerServices.AsyncTaskMethodBuilder<typeArgs>.Create();
            bodyBuilder.Add(
                F.Assignment(
                    F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)),
                    F.StaticCall(
                        null,
                        methodScopeAsyncMethodBuilderMemberCollection.CreateBuilder)));

            bodyBuilder.Add(GenerateParameterStorage(stateMachineVariable, proxies));

            // local.$stateField = NotStartedStateMachine
            bodyBuilder.Add(
                F.Assignment(
                    F.Field(F.Local(stateMachineVariable), stateField.AsMember(frameType)),
                    F.Literal(StateMachineStates.NotStartedStateMachine)));

            // local.$builder.Start(ref local) -- binding to the method AsyncTaskMethodBuilder<typeArgs>.Start()
            var startMethod = methodScopeAsyncMethodBuilderMemberCollection.Start.Construct(frameType);

            if (methodScopeAsyncMethodBuilderMemberCollection.CheckGenericMethodConstraints)
            {
                startMethod.CheckConstraints(new ConstraintsHelper.CheckConstraintsArgs(F.Compilation, F.Compilation.Conversions, includeNullability: false, F.Syntax.Location, diagnostics));
            }
            bodyBuilder.Add(
                F.ExpressionStatement(
                    F.Call(
                        F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)),
                        startMethod,
                        ImmutableArray.Create <BoundExpression>(F.Local(stateMachineVariable)))));

            bodyBuilder.Add(method.IsAsyncReturningVoid()
                ? F.Return()
                : F.Return(
                                F.Property(
                                    F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)),
                                    methodScopeAsyncMethodBuilderMemberCollection.Task)));

            return(F.Block(bodyBuilder.ToImmutableAndFree()));
        }
예제 #9
0
            protected override void GenerateConstructor()
            {
                // Produces:
                // .ctor(int state)
                // {
                //     this.state = state;
                //     this.initialThreadId = {managedThreadId};
                //     this.builder = System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create();
                //     this.valueOrEndPromise = new ManualResetValueTaskSourceLogic<bool>(this);
                // }
                Debug.Assert(stateMachineType.Constructor is IteratorConstructor);

                F.CurrentFunction = stateMachineType.Constructor;
                var bodyBuilder = ArrayBuilder <BoundStatement> .GetInstance();

                bodyBuilder.Add(F.BaseInitialization());
                bodyBuilder.Add(F.Assignment(F.Field(F.This(), stateField), F.Parameter(F.CurrentFunction.Parameters[0]))); // this.state = state;

                var managedThreadId = MakeCurrentThreadId();

                if (managedThreadId != null && (object)initialThreadIdField != null)
                {
                    // this.initialThreadId = {managedThreadId};
                    bodyBuilder.Add(F.Assignment(F.Field(F.This(), initialThreadIdField), managedThreadId));
                }

                // this.builder = System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create();
                AsyncMethodBuilderMemberCollection methodScopeAsyncMethodBuilderMemberCollection;
                bool found = AsyncMethodBuilderMemberCollection.TryCreate(F, method, typeMap: null, out methodScopeAsyncMethodBuilderMemberCollection);

                Debug.Assert(found);

                bodyBuilder.Add(
                    F.Assignment(
                        F.Field(F.This(), _builderField),
                        F.StaticCall(
                            null,
                            methodScopeAsyncMethodBuilderMemberCollection.CreateBuilder)));

                // this._valueOrEndPromise = new ManualResetValueTaskSourceLogic<bool>(this);
                MethodSymbol mrvtslCtor =
                    F.WellKnownMethod(WellKnownMember.System_Threading_Tasks_ManualResetValueTaskSourceLogic_T__ctor)
                    .AsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type.TypeSymbol);

                bodyBuilder.Add(
                    F.Assignment(
                        F.Field(F.This(), _promiseOfValueOrEndField),
                        F.New(mrvtslCtor, F.This())));

                bodyBuilder.Add(F.Return());
                F.CloseMethod(F.Block(bodyBuilder.ToImmutableAndFree()));
                bodyBuilder = null;
            }
예제 #10
0
 private AsyncRewriter(
     BoundStatement body,
     MethodSymbol method,
     int methodOrdinal,
     AsyncStateMachine stateMachineType,
     VariableSlotAllocator slotAllocatorOpt,
     TypeCompilationState compilationState,
     BindingDiagnosticBag diagnostics)
     : base(body, method, stateMachineType, slotAllocatorOpt, compilationState, diagnostics)
 {
     _constructedSuccessfully = AsyncMethodBuilderMemberCollection.TryCreate(F, method, this.stateMachineType.TypeMap, out _asyncMethodBuilderMemberCollection);
     _methodOrdinal           = methodOrdinal;
 }
        private static bool TryCreate(
            SyntheticBoundNodeFactory F,
            bool customBuilder,
            NamedTypeSymbol builderType,
            TypeSymbol resultType,
            MethodSymbol createBuilderMethod,
            PropertySymbol taskProperty,
            WellKnownMember setException,
            WellKnownMember setResult,
            WellKnownMember awaitOnCompleted,
            WellKnownMember awaitUnsafeOnCompleted,
            WellKnownMember start,
            WellKnownMember setStateMachine,
            out AsyncMethodBuilderMemberCollection collection)
        {
            MethodSymbol setExceptionMethod;
            MethodSymbol setResultMethod;
            MethodSymbol awaitOnCompletedMethod;
            MethodSymbol awaitUnsafeOnCompletedMethod;
            MethodSymbol startMethod;
            MethodSymbol setStateMachineMethod;

            if (TryGetBuilderMember(F, setException, builderType, customBuilder, out setExceptionMethod) &&
                TryGetBuilderMember(F, setResult, builderType, customBuilder, out setResultMethod) &&
                TryGetBuilderMember(F, awaitOnCompleted, builderType, customBuilder, out awaitOnCompletedMethod) &&
                TryGetBuilderMember(F, awaitUnsafeOnCompleted, builderType, customBuilder, out awaitUnsafeOnCompletedMethod) &&
                TryGetBuilderMember(F, start, builderType, customBuilder, out startMethod) &&
                TryGetBuilderMember(F, setStateMachine, builderType, customBuilder, out setStateMachineMethod))
            {
                collection = new AsyncMethodBuilderMemberCollection(
                    builderType,
                    resultType,
                    createBuilderMethod,
                    setExceptionMethod,
                    setResultMethod,
                    awaitOnCompletedMethod,
                    awaitUnsafeOnCompletedMethod,
                    startMethod,
                    setStateMachineMethod,
                    taskProperty,
                    checkGenericMethodConstraints: customBuilder);

                return(true);
            }

            collection = default(AsyncMethodBuilderMemberCollection);
            return(false);
        }
            /// <summary>
            /// Generates the body of the replacement method, which initializes the state machine. Unlike regular async methods, we won't start it.
            /// </summary>
            protected override BoundStatement GenerateStateMachineCreation(LocalSymbol stateMachineVariable, NamedTypeSymbol frameType)
            {
                // If the async method's result type is a type parameter of the method, then the AsyncTaskMethodBuilder<T>
                // needs to use the method's type parameters inside the rewritten method body. All other methods generated
                // during async rewriting are members of the synthesized state machine struct, and use the type parameters
                // from the struct.
                AsyncMethodBuilderMemberCollection methodScopeAsyncMethodBuilderMemberCollection;

                if (!AsyncMethodBuilderMemberCollection.TryCreate(F, method, null, out methodScopeAsyncMethodBuilderMemberCollection))
                {
                    return(new BoundBadStatement(F.Syntax, ImmutableArray <BoundNode> .Empty, hasErrors: true));
                }

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

                // local.$builder = System.Runtime.CompilerServices.AsyncTaskMethodBuilder<typeArgs>.Create();
                bodyBuilder.Add(
                    F.Assignment(
                        F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)),
                        F.StaticCall(
                            null,
                            methodScopeAsyncMethodBuilderMemberCollection.CreateBuilder)));

                // local.$stateField = NotStartedStateMachine;
                bodyBuilder.Add(
                    F.Assignment(
                        F.Field(F.Local(stateMachineVariable), stateField.AsMember(frameType)),
                        F.Literal(StateMachineStates.NotStartedStateMachine)));

                // local._valueOrEndPromise = new ManualResetValueTaskSourceLogic<bool>(stateMachine);
                MethodSymbol mrvtslCtor =
                    F.WellKnownMethod(WellKnownMember.System_Threading_Tasks_ManualResetValueTaskSourceLogic_T__ctor)
                    .AsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type.TypeSymbol);

                bodyBuilder.Add(
                    F.Assignment(
                        F.Field(F.Local(stateMachineVariable), _promiseOfValueOrEndField.AsMember(frameType)),
                        F.New(mrvtslCtor, F.Local(stateMachineVariable))));

                // return local;
                bodyBuilder.Add(F.Return(F.Local(stateMachineVariable)));

                return(F.Block(
                           bodyBuilder.ToImmutableAndFree()));
            }
예제 #13
0
 private AsyncRewriter(
     BoundStatement body,
     MethodSymbol method,
     AsyncStateMachine stateMachineType,
     VariableSlotAllocator variableSlotAllocatorOpt,
     TypeCompilationState compilationState,
     DiagnosticBag diagnostics)
     : base(body, method, stateMachineType, variableSlotAllocatorOpt, compilationState, diagnostics)
 {
     try
     {
         constructedSuccessfully = AsyncMethodBuilderMemberCollection.TryCreate(F, method, this.stateMachineType.TypeMap, out this.asyncMethodBuilderMemberCollection);
     }
     catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
     {
         diagnostics.Add(ex.Diagnostic);
         constructedSuccessfully = false;
     }
 }
예제 #14
0
 private AsyncRewriter(
     BoundStatement body,
     MethodSymbol method,
     AsyncStateMachine stateMachineClass,
     TypeCompilationState compilationState,
     DiagnosticBag diagnostics,
     bool generateDebugInfo)
     : base(body, method, stateMachineClass, compilationState, diagnostics, generateDebugInfo)
 {
     try
     {
         constructedSuccessfully = AsyncMethodBuilderMemberCollection.TryCreate(F, method, this.stateMachineClass.TypeMap, out this.asyncMethodBuilderMemberCollection);
     }
     catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
     {
         diagnostics.Add(ex.Diagnostic);
         constructedSuccessfully = false;
     }
 }
예제 #15
0
            protected override void GenerateConstructor()
            {
                // Produces:
                // .ctor(int state)
                // {
                //     this.state = state;
                //     this.initialThreadId = {managedThreadId};
                //     this.builder = System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create();
                // }
                Debug.Assert(stateMachineType.Constructor is IteratorConstructor);

                F.CurrentFunction = stateMachineType.Constructor;
                var bodyBuilder = ArrayBuilder <BoundStatement> .GetInstance();

                bodyBuilder.Add(F.BaseInitialization());
                bodyBuilder.Add(F.Assignment(F.Field(F.This(), stateField), F.Parameter(F.CurrentFunction.Parameters[0]))); // this.state = state;

                var managedThreadId = MakeCurrentThreadId();

                if (managedThreadId != null && (object)initialThreadIdField != null)
                {
                    // this.initialThreadId = {managedThreadId};
                    bodyBuilder.Add(F.Assignment(F.Field(F.This(), initialThreadIdField), managedThreadId));
                }

                // this.builder = System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create();
                AsyncMethodBuilderMemberCollection methodScopeAsyncMethodBuilderMemberCollection;
                bool found = AsyncMethodBuilderMemberCollection.TryCreate(F, method, typeMap: null, out methodScopeAsyncMethodBuilderMemberCollection);

                Debug.Assert(found);

                bodyBuilder.Add(
                    F.Assignment(
                        F.Field(F.This(), _builderField),
                        F.StaticCall(
                            null,
                            methodScopeAsyncMethodBuilderMemberCollection.CreateBuilder)));

                bodyBuilder.Add(F.Return());
                F.CloseMethod(F.Block(bodyBuilder.ToImmutableAndFree()));
                bodyBuilder = null;
            }
예제 #16
0
            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);
            }
예제 #17
0
            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);
            }
예제 #18
0
        private AsyncRewriter(
            BoundStatement body,
            MethodSymbol method,
            int methodOrdinal,
            AsyncStateMachine stateMachineType,
            VariableSlotAllocator slotAllocatorOpt,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics)
            : base(body, method, stateMachineType, slotAllocatorOpt, compilationState, diagnostics)
        {
            try
            {
                _constructedSuccessfully = AsyncMethodBuilderMemberCollection.TryCreate(F, method, this.stateMachineType.TypeMap, out _asyncMethodBuilderMemberCollection);
            }
            catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
            {
                diagnostics.Add(ex.Diagnostic);
                _constructedSuccessfully = false;
            }

            _methodOrdinal       = methodOrdinal;
            _ignoreAccessibility = compilationState.ModuleBuilderOpt.IgnoreAccessibility;
        }
예제 #19
0
        private int _nextYieldReturnState = StateMachineStates.InitialAsyncIteratorStateMachine;  // -3

        internal AsyncIteratorMethodToStateMachineRewriter(MethodSymbol method,
                                                           int methodOrdinal,
                                                           AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection,
                                                           AsyncIteratorInfo asyncIteratorInfo,
                                                           SyntheticBoundNodeFactory F,
                                                           FieldSymbol state,
                                                           FieldSymbol builder,
                                                           IReadOnlySet <Symbol> hoistedVariables,
                                                           IReadOnlyDictionary <Symbol, CapturedSymbolReplacement> nonReusableLocalProxies,
                                                           SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals,
                                                           VariableSlotAllocator slotAllocatorOpt,
                                                           int nextFreeHoistedLocalSlot,
                                                           DiagnosticBag diagnostics)
            : base(method, methodOrdinal, asyncMethodBuilderMemberCollection, F,
                   state, builder, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals,
                   slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics)
        {
            Debug.Assert(asyncIteratorInfo != null);

            _asyncIteratorInfo           = asyncIteratorInfo;
            _enclosingFinallyOrExitLabel = _exprReturnLabel;
            _exprReturnLabelTrue         = F.GenerateLabel("yieldReturn");
        }
        internal AsyncMethodToStateMachineRewriter(
            MethodSymbol method,
            AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection,
            SyntheticBoundNodeFactory F,
            FieldSymbol state,
            FieldSymbol builder,
            IReadOnlySet<Symbol> variablesCaptured,
            IReadOnlyDictionary<Symbol, CapturedSymbolReplacement> nonReusableLocalProxies,
            DiagnosticBag diagnostics)
            : base(F, method, state, variablesCaptured, nonReusableLocalProxies, diagnostics, useFinalizerBookkeeping: false)
        {
            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);
        }
예제 #21
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);
        }
        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);
        }
        private static bool TryCreate(
            SyntheticBoundNodeFactory F,
            NamedTypeSymbol builderType,
            TypeSymbol resultType,
            WellKnownMember setException,
            WellKnownMember setResult,
            WellKnownMember awaitOnCompleted,
            WellKnownMember awaitUnsafeOnCompleted,
            WellKnownMember start,
            WellKnownMember setStateMachine,
            PropertySymbol task,
            out AsyncMethodBuilderMemberCollection collection)
        {
            MethodSymbol setExceptionMethod;
            MethodSymbol setResultMethod;
            MethodSymbol awaitOnCompletedMethod;
            MethodSymbol awaitUnsafeOnCompletedMethod;
            MethodSymbol startMethod;
            MethodSymbol setStateMachineMethod;

            if (TryGetWellKnownMethodAsMember(F, setException, builderType, out setExceptionMethod) &&
                TryGetWellKnownMethodAsMember(F, setResult, builderType, out setResultMethod) &&
                TryGetWellKnownMethodAsMember(F, awaitOnCompleted, builderType, out awaitOnCompletedMethod) &&
                TryGetWellKnownMethodAsMember(F, awaitUnsafeOnCompleted, builderType, out awaitUnsafeOnCompletedMethod) &&
                TryGetWellKnownMethodAsMember(F, start, builderType, out startMethod) &&
                TryGetWellKnownMethodAsMember(F, setStateMachine, builderType, out setStateMachineMethod))
            {
                collection = new AsyncMethodBuilderMemberCollection(
                    builderType,
                    resultType,
                    setExceptionMethod,
                    setResultMethod,
                    awaitOnCompletedMethod,
                    awaitUnsafeOnCompletedMethod,
                    startMethod,
                    setStateMachineMethod,
                    task);

                return true;
            }

            collection = default(AsyncMethodBuilderMemberCollection);
            return false;
        }
        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).Type;
                }

                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);
        }