/// <summary> /// Returns True or False if we can determine whether the type is managed /// without looking at its fields and Unknown otherwise. /// Also returns whether or not the given type is generic. /// </summary> private static (ThreeState isManaged, bool hasGenerics) IsManagedTypeHelper(NamedTypeSymbol type) { // To match dev10, we treat enums as their underlying types. if (type.IsEnumType()) { type = type.GetEnumUnderlyingType(); } // Short-circuit common cases. switch (type.SpecialType) { case SpecialType.System_Void: case SpecialType.System_Boolean: case SpecialType.System_Char: case SpecialType.System_SByte: case SpecialType.System_Byte: case SpecialType.System_Int16: case SpecialType.System_UInt16: case SpecialType.System_Int32: case SpecialType.System_UInt32: case SpecialType.System_Int64: case SpecialType.System_UInt64: case SpecialType.System_Decimal: case SpecialType.System_Single: case SpecialType.System_Double: case SpecialType.System_IntPtr: case SpecialType.System_UIntPtr: case SpecialType.System_TypedReference: case SpecialType.System_ArgIterator: case SpecialType.System_RuntimeArgumentHandle: return(ThreeState.False, false); case SpecialType.None: default: // CONSIDER: could provide cases for other common special types. break; // Proceed with additional checks. } bool hasGenerics = type.TupleUnderlyingTypeOrSelf() is NamedTypeSymbol { IsGenericType : true }; switch (type.TypeKind) { case TypeKind.Enum: return(ThreeState.False, hasGenerics); case TypeKind.Struct: return(ThreeState.Unknown, hasGenerics); default: return(ThreeState.True, hasGenerics); } } }
public static bool CheckConstraints( this NamedTypeSymbol type, CSharpCompilation currentCompilation, ConversionsBase conversions, Location location, DiagnosticBag diagnostics) { // We do not report element locations in method parameters and return types // so we will simply unwrap the type if it was a tuple. We are relying on // TypeSymbolExtensions.VisitType to dig into the "Rest" tuple so that they // will be recursively unwrapped as well. type = (NamedTypeSymbol)type.TupleUnderlyingTypeOrSelf(); if (!RequiresChecking(type)) { return(true); } var diagnosticsBuilder = ArrayBuilder <TypeParameterDiagnosticInfo> .GetInstance(); ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null; var result = CheckTypeConstraints(type, conversions, currentCompilation, diagnosticsBuilder, ref useSiteDiagnosticsBuilder); if (useSiteDiagnosticsBuilder != null) { diagnosticsBuilder.AddRange(useSiteDiagnosticsBuilder); } foreach (var pair in diagnosticsBuilder) { diagnostics.Add(new CSDiagnostic(pair.DiagnosticInfo, location)); } diagnosticsBuilder.Free(); // we only check for distinct interfaces when the type is not from source, as we // trust that types that are from source have already been checked by the compiler // to prevent this from happening in the first place. if (!(currentCompilation != null && type.IsFromCompilation(currentCompilation)) && HasDuplicateInterfaces(type, null)) { result = false; diagnostics.Add(ErrorCode.ERR_BogusType, location, type); } return(result); }