Esempio n. 1
0
        /// <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);
            }
        }
    }
Esempio n. 2
0
        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);
        }