File: Microsoft\CSharp\RuntimeBinder\Semantics\Types\PredefinedTypes.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.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CSharp.RuntimeBinder.Syntax;
 
namespace Microsoft.CSharp.RuntimeBinder.Semantics
{
    internal static class PredefinedTypes
    {
        private static readonly AggregateSymbol[] s_predefSymbols = new AggregateSymbol[(int)PredefinedType.PT_COUNT];
 
        // We want to delay load the predefined symbols as needed.
        [RequiresUnreferencedCode(Binder.TrimmerWarning)]
        private static AggregateSymbol DelayLoadPredefSym(PredefinedType pt)
        {
            AggregateType type = (AggregateType)SymbolTable.GetCTypeFromType(PredefinedTypeFacts.GetAssociatedSystemType(pt));
            AggregateSymbol sym = type.OwningAggregate;
            return InitializePredefinedType(sym, pt);
        }
 
        internal static AggregateSymbol InitializePredefinedType(AggregateSymbol sym, PredefinedType pt)
        {
            sym.SetPredefined(true);
            sym.SetPredefType(pt);
            sym.SetSkipUDOps(pt <= PredefinedType.PT_ENUM && pt != PredefinedType.PT_INTPTR && pt != PredefinedType.PT_UINTPTR && pt != PredefinedType.PT_TYPE);
 
            return sym;
        }
 
        [RequiresUnreferencedCode(Binder.TrimmerWarning)]
        public static AggregateSymbol GetPredefinedAggregate(PredefinedType pt) =>
            s_predefSymbols[(int)pt] ??= DelayLoadPredefSym(pt);
 
        ////////////////////////////////////////////////////////////////////////////////
        // Some of the predefined types have built-in names, like "int" or "string" or
        // "object". This return the nice name if one exists; otherwise null is
        // returned.
 
        private static string GetNiceName(PredefinedType pt) => PredefinedTypeFacts.GetNiceName(pt);
 
        public static string GetNiceName(AggregateSymbol type) =>
            type.IsPredefined() ? GetNiceName(type.GetPredefType()) : null;
    }
 
    internal static class PredefinedTypeFacts
    {
        internal static FUNDTYPE GetFundType(PredefinedType type) => s_types[(int)type].FundType;
 
        internal static Type GetAssociatedSystemType(PredefinedType type) => s_types[(int)type].AssociatedSystemType;
 
        internal static bool IsSimpleType(PredefinedType type) => type < PredefinedType.FirstNonSimpleType;
 
        internal static bool IsNumericType(PredefinedType type)
        {
            switch (type)
            {
                case PredefinedType.PT_BYTE:
                case PredefinedType.PT_SHORT:
                case PredefinedType.PT_INT:
                case PredefinedType.PT_LONG:
                case PredefinedType.PT_FLOAT:
                case PredefinedType.PT_DOUBLE:
                case PredefinedType.PT_DECIMAL:
                case PredefinedType.PT_SBYTE:
                case PredefinedType.PT_USHORT:
                case PredefinedType.PT_UINT:
                case PredefinedType.PT_ULONG:
                    return true;
                default:
                    return false;
            }
        }
 
        internal static string GetNiceName(PredefinedType type) =>
            type switch
            {
                PredefinedType.PT_BYTE => "byte",
                PredefinedType.PT_SHORT => "short",
                PredefinedType.PT_INT => "int",
                PredefinedType.PT_LONG => "long",
                PredefinedType.PT_FLOAT => "float",
                PredefinedType.PT_DOUBLE => "double",
                PredefinedType.PT_DECIMAL => "decimal",
                PredefinedType.PT_CHAR => "char",
                PredefinedType.PT_BOOL => "bool",
                PredefinedType.PT_SBYTE => "sbyte",
                PredefinedType.PT_USHORT => "ushort",
                PredefinedType.PT_UINT => "uint",
                PredefinedType.PT_ULONG => "ulong",
                PredefinedType.PT_OBJECT => "object",
                PredefinedType.PT_STRING => "string",
                _ => null,
            };
 
        public static PredefinedType TryGetPredefTypeIndex(string name) =>
            s_typesByName.TryGetValue(name, out PredefinedType type) ? type : PredefinedType.PT_UNDEFINEDINDEX;
 
        private sealed class PredefinedTypeInfo
        {
#if DEBUG
            public readonly PredefinedType Type;
#endif
            public readonly string Name;
            public readonly FUNDTYPE FundType;
            public readonly Type AssociatedSystemType;
 
            internal PredefinedTypeInfo(PredefinedType type, Type associatedSystemType, string name, FUNDTYPE fundType)
            {
#if DEBUG
                Type = type;
#endif
                Name = name;
                FundType = fundType;
                AssociatedSystemType = associatedSystemType;
            }
 
            internal PredefinedTypeInfo(PredefinedType type, Type associatedSystemType, string name)
                : this(type, associatedSystemType, name, FUNDTYPE.FT_REF)
            {
            }
        }
 
        private static readonly PredefinedTypeInfo[] s_types = {
            new PredefinedTypeInfo(PredefinedType.PT_BYTE,   typeof(byte), "System.Byte", FUNDTYPE.FT_U1),
            new PredefinedTypeInfo(PredefinedType.PT_SHORT,  typeof(short), "System.Int16", FUNDTYPE.FT_I2),
            new PredefinedTypeInfo(PredefinedType.PT_INT,    typeof(int), "System.Int32", FUNDTYPE.FT_I4),
            new PredefinedTypeInfo(PredefinedType.PT_LONG,   typeof(long), "System.Int64", FUNDTYPE.FT_I8),
            new PredefinedTypeInfo(PredefinedType.PT_FLOAT,  typeof(float), "System.Single", FUNDTYPE.FT_R4),
            new PredefinedTypeInfo(PredefinedType.PT_DOUBLE, typeof(double), "System.Double", FUNDTYPE.FT_R8),
            new PredefinedTypeInfo(PredefinedType.PT_DECIMAL, typeof(decimal), "System.Decimal", FUNDTYPE.FT_STRUCT),
            new PredefinedTypeInfo(PredefinedType.PT_CHAR,   typeof(char), "System.Char", FUNDTYPE.FT_U2),
            new PredefinedTypeInfo(PredefinedType.PT_BOOL,   typeof(bool), "System.Boolean", FUNDTYPE.FT_I1),
            new PredefinedTypeInfo(PredefinedType.PT_SBYTE,  typeof(sbyte), "System.SByte", FUNDTYPE.FT_I1),
            new PredefinedTypeInfo(PredefinedType.PT_USHORT, typeof(ushort), "System.UInt16", FUNDTYPE.FT_U2),
            new PredefinedTypeInfo(PredefinedType.PT_UINT,   typeof(uint), "System.UInt32", FUNDTYPE.FT_U4),
            new PredefinedTypeInfo(PredefinedType.PT_ULONG,  typeof(ulong), "System.UInt64", FUNDTYPE.FT_U8),
            new PredefinedTypeInfo(PredefinedType.PT_INTPTR,  typeof(IntPtr), "System.IntPtr", FUNDTYPE.FT_STRUCT),
            new PredefinedTypeInfo(PredefinedType.PT_UINTPTR, typeof(UIntPtr), "System.UIntPtr", FUNDTYPE.FT_STRUCT),
            new PredefinedTypeInfo(PredefinedType.PT_OBJECT, typeof(object), "System.Object"),
            new PredefinedTypeInfo(PredefinedType.PT_STRING, typeof(string), "System.String"),
            new PredefinedTypeInfo(PredefinedType.PT_DELEGATE, typeof(Delegate), "System.Delegate"),
            new PredefinedTypeInfo(PredefinedType.PT_MULTIDEL, typeof(MulticastDelegate), "System.MulticastDelegate"),
            new PredefinedTypeInfo(PredefinedType.PT_ARRAY,   typeof(Array), "System.Array"),
            new PredefinedTypeInfo(PredefinedType.PT_TYPE, typeof(Type), "System.Type"),
            new PredefinedTypeInfo(PredefinedType.PT_VALUE,   typeof(ValueType), "System.ValueType"),
            new PredefinedTypeInfo(PredefinedType.PT_ENUM,    typeof(Enum), "System.Enum"),
            new PredefinedTypeInfo(PredefinedType.PT_DATETIME,    typeof(DateTime), "System.DateTime", FUNDTYPE.FT_STRUCT),
            new PredefinedTypeInfo(PredefinedType.PT_IENUMERABLE, typeof(System.Collections.IEnumerable), "System.Collections.IEnumerable"),
            new PredefinedTypeInfo(PredefinedType.PT_G_IENUMERABLE, typeof(IEnumerable<>), "System.Collections.Generic.IEnumerable`1"),
            new PredefinedTypeInfo(PredefinedType.PT_G_OPTIONAL, typeof(Nullable<>), "System.Nullable`1", FUNDTYPE.FT_STRUCT),
            new PredefinedTypeInfo(PredefinedType.PT_G_IQUERYABLE, typeof(System.Linq.IQueryable<>), "System.Linq.IQueryable`1"),
            new PredefinedTypeInfo(PredefinedType.PT_G_ICOLLECTION, typeof(ICollection<>), "System.Collections.Generic.ICollection`1"),
            new PredefinedTypeInfo(PredefinedType.PT_G_ILIST, typeof(IList<>), "System.Collections.Generic.IList`1"),
            new PredefinedTypeInfo(PredefinedType.PT_G_EXPRESSION, typeof(System.Linq.Expressions.Expression<>), "System.Linq.Expressions.Expression`1"),
            new PredefinedTypeInfo(PredefinedType.PT_EXPRESSION, typeof(System.Linq.Expressions.Expression), "System.Linq.Expressions.Expression"),
            new PredefinedTypeInfo(PredefinedType.PT_BINARYEXPRESSION, typeof(System.Linq.Expressions.BinaryExpression), "System.Linq.Expressions.BinaryExpression"),
            new PredefinedTypeInfo(PredefinedType.PT_UNARYEXPRESSION, typeof(System.Linq.Expressions.UnaryExpression), "System.Linq.Expressions.UnaryExpression"),
            new PredefinedTypeInfo(PredefinedType.PT_CONSTANTEXPRESSION, typeof(System.Linq.Expressions.ConstantExpression), "System.Linq.Expressions.ConstantExpression"),
            new PredefinedTypeInfo(PredefinedType.PT_PARAMETEREXPRESSION, typeof(System.Linq.Expressions.ParameterExpression), "System.Linq.Expressions.ParameterExpression"),
            new PredefinedTypeInfo(PredefinedType.PT_MEMBEREXPRESSION, typeof(System.Linq.Expressions.MemberExpression), "System.Linq.Expressions.MemberExpression"),
            new PredefinedTypeInfo(PredefinedType.PT_METHODCALLEXPRESSION, typeof(System.Linq.Expressions.MethodCallExpression), "System.Linq.Expressions.MethodCallExpression"),
            new PredefinedTypeInfo(PredefinedType.PT_NEWEXPRESSION, typeof(System.Linq.Expressions.NewExpression), "System.Linq.Expressions.NewExpression"),
            new PredefinedTypeInfo(PredefinedType.PT_NEWARRAYEXPRESSION, typeof(System.Linq.Expressions.NewArrayExpression), "System.Linq.Expressions.NewArrayExpression"),
            new PredefinedTypeInfo(PredefinedType.PT_INVOCATIONEXPRESSION, typeof(System.Linq.Expressions.InvocationExpression), "System.Linq.Expressions.InvocationExpression"),
            new PredefinedTypeInfo(PredefinedType.PT_FIELDINFO, typeof(System.Reflection.FieldInfo), "System.Reflection.FieldInfo"),
            new PredefinedTypeInfo(PredefinedType.PT_METHODINFO, typeof(System.Reflection.MethodInfo), "System.Reflection.MethodInfo"),
            new PredefinedTypeInfo(PredefinedType.PT_CONSTRUCTORINFO, typeof(System.Reflection.ConstructorInfo), "System.Reflection.ConstructorInfo"),
            new PredefinedTypeInfo(PredefinedType.PT_PROPERTYINFO, typeof(System.Reflection.PropertyInfo), "System.Reflection.PropertyInfo"),
            new PredefinedTypeInfo(PredefinedType.PT_MISSING, typeof(System.Reflection.Missing), "System.Reflection.Missing"),
            new PredefinedTypeInfo(PredefinedType.PT_G_IREADONLYLIST, typeof(IReadOnlyList<>), "System.Collections.Generic.IReadOnlyList`1"),
            new PredefinedTypeInfo(PredefinedType.PT_G_IREADONLYCOLLECTION, typeof(IReadOnlyCollection<>), "System.Collections.Generic.IReadOnlyCollection`1"),
            new PredefinedTypeInfo(PredefinedType.PT_FUNC, typeof(Func<>), "System.Func`1")
        };
 
        private static readonly Dictionary<string, PredefinedType> s_typesByName = CreatePredefinedTypeFacts();
 
        private static Dictionary<string, PredefinedType> CreatePredefinedTypeFacts()
        {
            var typesByName = new Dictionary<string, PredefinedType>((int)PredefinedType.PT_COUNT);
            for (int i = 0; i < (int)PredefinedType.PT_COUNT; i++)
            {
#if DEBUG
                Debug.Assert(s_types[i].Type == (PredefinedType)i);
#endif
                typesByName.Add(s_types[i].Name, (PredefinedType)i);
            }
 
            return typesByName;
        }
    }
}