File: Microsoft\CSharp\RuntimeBinder\Semantics\Types\Type.cs
Web Access
Project: src\src\libraries\Microsoft.CSharp\src\Microsoft.CSharp.csproj (Microsoft.CSharp)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Microsoft.CSharp.RuntimeBinder.Syntax;
 
namespace Microsoft.CSharp.RuntimeBinder.Semantics
{
    internal abstract class CType
    {
        private protected CType(TypeKind kind)
        {
            TypeKind = kind;
        }
 
        [ExcludeFromCodeCoverage(Justification = "Should only be called through override")]
        public virtual Type AssociatedSystemType
        {
            [RequiresUnreferencedCode(Binder.TrimmerWarning)]
            get => throw Error.InternalCompilerError();
        }
 
        public TypeKind TypeKind { get; }
 
        public virtual CType BaseOrParameterOrElementType => null;
 
        ////////////////////////////////////////////////////////////////////////////////
        // Given a symbol, determine its fundamental type. This is the type that
        // indicate how the item is stored and what instructions are used to reference
        // if. The fundamental types are:
        // one of the integral/float types (includes enums with that underlying type)
        // reference type
        // struct/value type
        public virtual FUNDTYPE FundamentalType => FUNDTYPE.FT_NONE;
 
        public virtual ConstValKind ConstValKind => ConstValKind.Int;
 
        ////////////////////////////////////////////////////////////////////////////////
        // Strips off ArrayType, ParameterModifierType, PointerType, PinnedType and optionally NullableType
        // and returns the result.
        public CType GetNakedType(bool fStripNub)
        {
            for (CType type = this; ;)
            {
                switch (type.TypeKind)
                {
                    default:
                        return type;
 
                    case TypeKind.TK_NullableType:
                        if (!fStripNub)
                        {
                            goto default;
                        }
 
                        goto case TypeKind.TK_ArrayType;
 
                    case TypeKind.TK_ArrayType:
                    case TypeKind.TK_ParameterModifierType:
                    case TypeKind.TK_PointerType:
                        type = type.BaseOrParameterOrElementType;
                        break;
                }
            }
        }
 
        public virtual CType StripNubs() => this;
 
        public virtual CType StripNubs(out bool wasNullable)
        {
            wasNullable = false;
            return this;
        }
 
        public virtual bool IsDelegateType => false;
 
        ////////////////////////////////////////////////////////////////////////////////
        // A few types are considered "simple" types for purposes of conversions and so
        // on. They are the fundamental types the compiler knows about for operators and
        // conversions.
        public virtual bool IsSimpleType => false;
 
        public virtual bool IsSimpleOrEnum => false;
 
        public virtual bool IsSimpleOrEnumOrString => false;
 
        ////////////////////////////////////////////////////////////////////////////////
        // A few types are considered "numeric" types. They are the fundamental number
        // types the compiler knows about for operators and conversions.
        public virtual bool IsNumericType => false;
 
        public virtual bool IsStructOrEnum => false;
 
        public virtual bool IsStructType => false;
 
        public virtual bool IsEnumType => false;
 
        public virtual bool IsInterfaceType => false;
 
        public virtual bool IsClassType => false;
 
        [ExcludeFromCodeCoverage(Justification = "Should only be called through override")]
        public virtual AggregateType UnderlyingEnumType => throw Error.InternalCompilerError();
 
        // Pointer types (or arrays of them) are the only unsafe types.
        // Note that generics may not be instantiated with pointer types
        public virtual bool IsUnsafe() => false;
 
        public virtual bool IsPredefType(PredefinedType pt) => false;
 
        public virtual bool IsPredefined => false;
 
        [ExcludeFromCodeCoverage(Justification = "Should only be called through override")]
        public virtual PredefinedType PredefinedType => throw Error.InternalCompilerError();
 
        public virtual bool IsStaticClass => false;
 
        // These check for AGGTYPESYMs, TYVARSYMs and others as appropriate.
        public virtual bool IsValueType => false;
 
        public virtual bool IsNonNullableValueType => false;
 
        public virtual bool IsReferenceType => false;
 
        [ExcludeFromCodeCoverage(Justification = "Should only be called through override")]
        [RequiresUnreferencedCode(Binder.TrimmerWarning)]
        public virtual AggregateType GetAts()
        {
            Debug.Fail("Bad type for AsAggregateType");
            return null;
        }
    }
}