Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
TypeUtils.cs266 linesDownload Raw Back to ComInterop
1// Licensed to the .NET Foundation under one or more agreements.2// The .NET Foundation licenses this file to you under the MIT license.3 4using System;5using System.Reflection;6 7namespace System.Management.Automation.ComInterop8{9    internal static class TypeUtils10    {11        //CONFORMING12        internal static Type GetNonNullableType(Type type)13        {14            if (IsNullableType(type))15            {16                return type.GetGenericArguments()[0];17            }18            return type;19        }20 21        //CONFORMING22        internal static bool IsNullableType(this Type type)23        {24            return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);25        }26 27        //CONFORMING28        internal static bool AreReferenceAssignable(Type dest, Type src)29        {30            // WARNING: This actually implements "Is this identity assignable and/or reference assignable?"31            if (dest == src)32            {33                return true;34            }35            if (!dest.IsValueType && !src.IsValueType && AreAssignable(dest, src))36            {37                return true;38            }39            return false;40        }41 42        //CONFORMING43        internal static bool AreAssignable(Type dest, Type src)44        {45            if (dest == src)46            {47                return true;48            }49            if (dest.IsAssignableFrom(src))50            {51                return true;52            }53            if (dest.IsArray && src.IsArray && dest.GetArrayRank() == src.GetArrayRank() && AreReferenceAssignable(dest.GetElementType(), src.GetElementType()))54            {55                return true;56            }57            if (src.IsArray && dest.IsGenericType &&58                (dest.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IEnumerable<>)59                || dest.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IList<>)60                || dest.GetGenericTypeDefinition() == typeof(System.Collections.Generic.ICollection<>))61                && dest.GetGenericArguments()[0] == src.GetElementType())62            {63                return true;64            }65            return false;66        }67 68        //CONFORMING69        internal static bool IsImplicitlyConvertible(Type source, Type destination)70        {71            return IsIdentityConversion(source, destination) ||72                IsImplicitNumericConversion(source, destination) ||73                IsImplicitReferenceConversion(source, destination) ||74                IsImplicitBoxingConversion(source, destination);75        }76 77        internal static bool IsImplicitlyConvertible(Type source, Type destination, bool considerUserDefined)78        {79            return IsImplicitlyConvertible(source, destination) ||80                (considerUserDefined && GetUserDefinedCoercionMethod(source, destination, true) != null);81        }82 83        //CONFORMING84        internal static MethodInfo GetUserDefinedCoercionMethod(Type convertFrom, Type convertToType, bool implicitOnly)85        {86            // check for implicit coercions first87            Type nnExprType = TypeUtils.GetNonNullableType(convertFrom);88            Type nnConvType = TypeUtils.GetNonNullableType(convertToType);89            // try exact match on types90            MethodInfo[] eMethods = nnExprType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);91            MethodInfo method = FindConversionOperator(eMethods, convertFrom, convertToType, implicitOnly);92            if (method != null)93            {94                return method;95            }96            MethodInfo[] cMethods = nnConvType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);97            method = FindConversionOperator(cMethods, convertFrom, convertToType, implicitOnly);98            if (method != null)99            {100                return method;101            }102            // try lifted conversion103            if (nnExprType != convertFrom || nnConvType != convertToType)104            {105                method =106                    FindConversionOperator(eMethods, nnExprType, nnConvType, implicitOnly) ??107                    FindConversionOperator(cMethods, nnExprType, nnConvType, implicitOnly);108                if (method != null)109                {110                    return method;111                }112            }113            return null;114        }115 116        //CONFORMING117        internal static MethodInfo FindConversionOperator(MethodInfo[] methods, Type typeFrom, Type typeTo, bool implicitOnly)118        {119            foreach (MethodInfo mi in methods)120            {121                if (mi.Name != "op_Implicit" && (implicitOnly || mi.Name != "op_Explicit"))122                    continue;123                if (mi.ReturnType != typeTo)124                    continue;125                ParameterInfo[] pis = mi.GetParameters();126                if (pis[0].ParameterType != typeFrom)127                    continue;128                return mi;129            }130            return null;131        }132 133        //CONFORMING134        private static bool IsIdentityConversion(Type source, Type destination)135        {136            return source == destination;137        }138 139        //CONFORMING140        private static bool IsImplicitNumericConversion(Type source, Type destination)141        {142            TypeCode tcSource = Type.GetTypeCode(source);143            TypeCode tcDest = Type.GetTypeCode(destination);144 145            switch (tcSource)146            {147                case TypeCode.SByte:148                    switch (tcDest)149                    {150                        case TypeCode.Int16:151                        case TypeCode.Int32:152                        case TypeCode.Int64:153                        case TypeCode.Single:154                        case TypeCode.Double:155                        case TypeCode.Decimal:156                            return true;157                    }158                    return false;159                case TypeCode.Byte:160                    switch (tcDest)161                    {162                        case TypeCode.Int16:163                        case TypeCode.UInt16:164                        case TypeCode.Int32:165                        case TypeCode.UInt32:166                        case TypeCode.Int64:167                        case TypeCode.UInt64:168                        case TypeCode.Single:169                        case TypeCode.Double:170                        case TypeCode.Decimal:171                            return true;172                    }173                    return false;174                case TypeCode.Int16:175                    switch (tcDest)176                    {177                        case TypeCode.Int32:178                        case TypeCode.Int64:179                        case TypeCode.Single:180                        case TypeCode.Double:181                        case TypeCode.Decimal:182                            return true;183                    }184                    return false;185                case TypeCode.UInt16:186                    switch (tcDest)187                    {188                        case TypeCode.Int32:189                        case TypeCode.UInt32:190                        case TypeCode.Int64:191                        case TypeCode.UInt64:192                        case TypeCode.Single:193                        case TypeCode.Double:194                        case TypeCode.Decimal:195                            return true;196                    }197                    return false;198                case TypeCode.Int32:199                    switch (tcDest)200                    {201                        case TypeCode.Int64:202                        case TypeCode.Single:203                        case TypeCode.Double:204                        case TypeCode.Decimal:205                            return true;206                    }207                    return false;208                case TypeCode.UInt32:209                    switch (tcDest)210                    {211                        case TypeCode.UInt32:212                        case TypeCode.UInt64:213                        case TypeCode.Single:214                        case TypeCode.Double:215                        case TypeCode.Decimal:216                            return true;217                    }218                    return false;219                case TypeCode.Int64:220                case TypeCode.UInt64:221                    switch (tcDest)222                    {223                        case TypeCode.Single:224                        case TypeCode.Double:225                        case TypeCode.Decimal:226                            return true;227                    }228                    return false;229                case TypeCode.Char:230                    switch (tcDest)231                    {232                        case TypeCode.UInt16:233                        case TypeCode.Int32:234                        case TypeCode.UInt32:235                        case TypeCode.Int64:236                        case TypeCode.UInt64:237                        case TypeCode.Single:238                        case TypeCode.Double:239                        case TypeCode.Decimal:240                            return true;241                    }242                    return false;243                case TypeCode.Single:244                    return (tcDest == TypeCode.Double);245            }246            return false;247        }248 249        //CONFORMING250        private static bool IsImplicitReferenceConversion(Type source, Type destination)251        {252            return AreAssignable(destination, source);253        }254 255        //CONFORMING256        private static bool IsImplicitBoxingConversion(Type source, Type destination)257        {258            if (source.IsValueType && (destination == typeof(object) || destination == typeof(System.ValueType)))259                return true;260            if (source.IsEnum && destination == typeof(System.Enum))261                return true;262            return false;263        }264    }265}266