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