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