예제 #1
0
        internal readonly TypeSymbol IteratorElementType; // only for async-iterators

        public AsyncStateMachine(VariableSlotAllocator variableAllocatorOpt, TypeCompilationState compilationState, MethodSymbol asyncMethod, int asyncMethodOrdinal, TypeKind typeKind)
            : base(variableAllocatorOpt, compilationState, asyncMethod, asyncMethodOrdinal)
        {
            _typeKind = typeKind;
            CSharpCompilation compilation = asyncMethod.DeclaringCompilation;
            var interfaces = ArrayBuilder <NamedTypeSymbol> .GetInstance();

            bool isIterator = asyncMethod.IsIterator;

            if (isIterator)
            {
                var elementType = TypeMap.SubstituteType(asyncMethod.IteratorElementType).TypeSymbol;
                this.IteratorElementType = elementType;

                // IAsyncEnumerable<TResult>
                interfaces.Add(compilation.GetWellKnownType(WellKnownType.System_Collections_Generic_IAsyncEnumerable_T).Construct(elementType));

                // IAsyncEnumerator<TResult>
                interfaces.Add(compilation.GetWellKnownType(WellKnownType.System_Collections_Generic_IAsyncEnumerator_T).Construct(elementType));

                // IValueTaskSource<bool>
                interfaces.Add(compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Sources_IValueTaskSource_T).Construct(compilation.GetSpecialType(SpecialType.System_Boolean)));

                // IStrongBox<ManualResetValueTaskSourceLogic<bool>>
                interfaces.Add(compilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IStrongBox_T).Construct(
                                   compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_ManualResetValueTaskSourceLogic_T)
                                   .Construct(compilation.GetSpecialType(SpecialType.System_Boolean))));

                // IAsyncDisposable
                interfaces.Add(compilation.GetWellKnownType(WellKnownType.System_IAsyncDisposable));
            }

            interfaces.Add(compilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IAsyncStateMachine));
            _interfaces = interfaces.ToImmutableAndFree();

            _constructor = isIterator ? (MethodSymbol) new IteratorConstructor(this) : new AsyncConstructor(this);
        }
        /// <remarks>
        /// Based on OutputContext::IsNonAgileField.
        /// </remarks>
        internal static bool IsNonAgileFieldAccess(BoundFieldAccess fieldAccess, CSharpCompilation compilation)
        {
            // Warn if taking the address of a non-static field with a receiver other than this (possibly cast)
            // and a type that descends from System.MarshalByRefObject.
            if (IsInstanceFieldAccessWithNonThisReceiver(fieldAccess))
            {
                // NOTE: We're only trying to produce a warning, so there's no point in producing an
                // error if the well-known type we need for the check is missing.
                NamedTypeSymbol marshalByRefType = compilation.GetWellKnownType(WellKnownType.System_MarshalByRefObject);

                TypeSymbol baseType = fieldAccess.FieldSymbol.ContainingType;
                while ((object)baseType != null)
                {
                    if (baseType == marshalByRefType)
                    {
                        return true;
                    }

                    // NOTE: We're only trying to produce a warning, so there's no point in producing a
                    // use site diagnostic if we can't walk up the base type hierarchy.
                    baseType = baseType.BaseTypeNoUseSiteDiagnostics;
                }
            }

            return false;
        }
예제 #3
0
        private static void SetScriptInitializerReturnType(
            CSharpCompilation compilation,
            SynthesizedInteractiveInitializerMethod scriptInitializer,
            ImmutableArray<ImmutableArray<FieldOrPropertyInitializer>> fieldInitializers,
            DiagnosticBag diagnostics)
        {
            bool isAsync = scriptInitializer.IsSubmissionInitializer && fieldInitializers.Any(i => i.Any(ContainsAwaitsVisitor.ContainsAwait));
            var resultType = scriptInitializer.ResultType;
            TypeSymbol returnType;

            if ((object)resultType == null)
            {
                Debug.Assert(!isAsync);
                returnType = compilation.GetSpecialType(SpecialType.System_Void);
            }
            else if (!isAsync)
            {
                returnType = resultType;
            }
            else
            {
                var taskT = compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task_T);
                var useSiteDiagnostic = taskT.GetUseSiteDiagnostic();
                if (useSiteDiagnostic != null)
                {
                    diagnostics.Add(useSiteDiagnostic, NoLocation.Singleton);
                }
                returnType = taskT.Construct(resultType);
            }

            scriptInitializer.SetReturnType(isAsync, returnType);
        }