// //private static bool HasNarrowingConversion(Type fromType, Type toType, NarrowingLevel level) // //{ // // if (level == NarrowingLevel.Three) // // { // // if (toType == CharType && fromType == StringType) return true; // // if (toType == StringType && fromType == CharType) return true; // // //Check if there is an implicit convertor defined on fromType to toType // // if (HasImplicitConversion(fromType, toType)) // // { // // return true; // // } // // } // // if (toType == DoubleType && fromType == DecimalType) return true; // // if (toType == SingleType && fromType == DecimalType) return true; // // //if (toType.IsArray) // // //{ // // // return typeof(PythonTuple).IsAssignableFrom(fromType); // // //} // // if (level == NarrowingLevel.Three) // // { // // if (IsNumeric(fromType) && IsNumeric(toType)) // // { // // if (fromType != typeof(float) && fromType != typeof(double) && fromType != typeof(decimal)) // // { // // return true; // // } // // } // // if (fromType == typeof(bool) && IsNumeric(toType)) return true; // // if (toType == CharType && fromType == StringType) return true; // // if (toType == Int32Type && fromType == BooleanType) return true; // // // Everything can convert to Boolean in Python // // if (toType == BooleanType) return true; // // // TODO: Figure out Clojure equivalent // // //if (DelegateType.IsAssignableFrom(toType) && IsPythonType(fromType)) return true; // // //if (IEnumerableType == toType && IsPythonType(fromType)) return true; // // //if (toType == typeof(IEnumerator)) // // //{ // // // if (IsPythonType(fromType)) return true; // // //} // // //else if (toType.IsGenericType) // // //{ // // // Type genTo = toType.GetGenericTypeDefinition(); // // // if (genTo == IEnumerableOfTType) // // // { // // // return IEnumerableOfObjectType.IsAssignableFrom(fromType) || // // // IEnumerableType.IsAssignableFrom(fromType) || // // // fromType == typeof(OldInstance); // // // } // // // else if (genTo == typeof(System.Collections.Generic.IEnumerator<>)) // // // { // // // if (IsPythonType(fromType)) return true; // // // } // // //} // // } // // if (level == NarrowingLevel.All) // // { // // //__int__, __float__, __long__ // // if (IsNumeric(fromType) && IsNumeric(toType)) return true; // // } // // if (toType.IsGenericType) // // { // // Type genTo = toType.GetGenericTypeDefinition(); // // if (genTo == IListOfTType) // // { // // return IListOfObjectType.IsAssignableFrom(fromType); // // } // // else if (genTo == NullableOfTType) // // { // // if (fromType == typeof(DynamicNull) || CanConvertFrom(fromType, toType.GetGenericArguments()[0], level)) // // { // // return true; // // } // // } // // else if (genTo == IDictOfTType) // // { // // return IDictionaryOfObjectType.IsAssignableFrom(fromType); // // } // // } // // if (fromType == BigIntegerType && toType == Int64Type) return true; // // if (fromType == BigIntType && toType == Int64Type) return true; // // if (toType.IsEnum && fromType == Enum.GetUnderlyingType(toType)) return true; // // return false; // //} // // TODO: Merge with equivalent in clojure.lang.Util // internal static bool IsNumeric(Type t) // { // if (t.IsEnum) return false; // switch (Type.GetTypeCode(t)) // { // case TypeCode.DateTime: // case TypeCode.DBNull: // case TypeCode.Char: // case TypeCode.Empty: // case TypeCode.String: // case TypeCode.Boolean: // return false; // case TypeCode.Object: // return t == BigIntType || t == BigIntegerType || t == BigDecimalType; // default: // return true; // } // } // // ripped off from IPy // private static bool HasImplicitConversion(Type fromType, Type toType) // { // return // HasImplicitConversionWorker(fromType, fromType, toType) || // HasImplicitConversionWorker(toType, fromType, toType); // } // // ripped off from IPy // private static bool HasImplicitConversionWorker(Type lookupType, Type fromType, Type toType) // { // while (lookupType != null) // { // foreach (MethodInfo method in lookupType.GetMethods()) // { // if (method.Name == "op_Implicit" && // method.GetParameters()[0].ParameterType.IsAssignableFrom(fromType) && // toType.IsAssignableFrom(method.ReturnType)) // { // return true; // } // } // lookupType = lookupType.BaseType; // } // return false; // } #endregion #region Delegate creation // TODO: Cache created delegates public static object ConvertToDelegate(object value, Type to) { IFn fn = value as IFn; if (fn == null) { return(null); } return(GenDelegate.Create(to, fn)); }
// //private static bool HasNarrowingConversion(Type fromType, Type toType, NarrowingLevel level) // //{ // // if (level == NarrowingLevel.Three) // // { // // if (toType == CharType && fromType == StringType) return true; // // if (toType == StringType && fromType == CharType) return true; // // //Check if there is an implicit convertor defined on fromType to toType // // if (HasImplicitConversion(fromType, toType)) // // { // // return true; // // } // // } // // if (toType == DoubleType && fromType == DecimalType) return true; // // if (toType == SingleType && fromType == DecimalType) return true; // // //if (toType.IsArray) // // //{ // // // return typeof(PythonTuple).IsAssignableFrom(fromType); // // //} // // if (level == NarrowingLevel.Three) // // { // // if (IsNumeric(fromType) && IsNumeric(toType)) // // { // // if (fromType != typeof(float) && fromType != typeof(double) && fromType != typeof(decimal)) // // { // // return true; // // } // // } // // if (fromType == typeof(bool) && IsNumeric(toType)) return true; // // if (toType == CharType && fromType == StringType) return true; // // if (toType == Int32Type && fromType == BooleanType) return true; // // // Everything can convert to Boolean in Python // // if (toType == BooleanType) return true; // // // TODO: Figure out Clojure equivalent // // //if (DelegateType.IsAssignableFrom(toType) && IsPythonType(fromType)) return true; // // //if (IEnumerableType == toType && IsPythonType(fromType)) return true; // // //if (toType == typeof(IEnumerator)) // // //{ // // // if (IsPythonType(fromType)) return true; // // //} // // //else if (toType.IsGenericType) // // //{ // // // Type genTo = toType.GetGenericTypeDefinition(); // // // if (genTo == IEnumerableOfTType) // // // { // // // return IEnumerableOfObjectType.IsAssignableFrom(fromType) || // // // IEnumerableType.IsAssignableFrom(fromType) || // // // fromType == typeof(OldInstance); // // // } // // // else if (genTo == typeof(System.Collections.Generic.IEnumerator<>)) // // // { // // // if (IsPythonType(fromType)) return true; // // // } // // //} // // } // // if (level == NarrowingLevel.All) // // { // // //__int__, __float__, __long__ // // if (IsNumeric(fromType) && IsNumeric(toType)) return true; // // } // // if (toType.IsGenericType) // // { // // Type genTo = toType.GetGenericTypeDefinition(); // // if (genTo == IListOfTType) // // { // // return IListOfObjectType.IsAssignableFrom(fromType); // // } // // else if (genTo == NullableOfTType) // // { // // if (fromType == typeof(DynamicNull) || CanConvertFrom(fromType, toType.GetGenericArguments()[0], level)) // // { // // return true; // // } // // } // // else if (genTo == IDictOfTType) // // { // // return IDictionaryOfObjectType.IsAssignableFrom(fromType); // // } // // } // // if (fromType == BigIntegerType && toType == Int64Type) return true; // // if (fromType == BigIntType && toType == Int64Type) return true; // // if (toType.IsEnum && fromType == Enum.GetUnderlyingType(toType)) return true; // // return false; // //} // // TODO: Merge with equivalent in clojure.lang.Util // internal static bool IsNumeric(Type t) // { // if (t.IsEnum) return false; // switch (Type.GetTypeCode(t)) // { // case TypeCode.DateTime: // case TypeCode.DBNull: // case TypeCode.Char: // case TypeCode.Empty: // case TypeCode.String: // case TypeCode.Boolean: // return false; // case TypeCode.Object: // return t == BigIntType || t == BigIntegerType || t == BigDecimalType; // default: // return true; // } // } // // ripped off from IPy // private static bool HasImplicitConversion(Type fromType, Type toType) // { // return // HasImplicitConversionWorker(fromType, fromType, toType) || // HasImplicitConversionWorker(toType, fromType, toType); // } // // ripped off from IPy // private static bool HasImplicitConversionWorker(Type lookupType, Type fromType, Type toType) // { // while (lookupType != null) // { // foreach (MethodInfo method in lookupType.GetMethods()) // { // if (method.Name == "op_Implicit" && // method.GetParameters()[0].ParameterType.IsAssignableFrom(fromType) && // toType.IsAssignableFrom(method.ReturnType)) // { // return true; // } // } // lookupType = lookupType.BaseType; // } // return false; // } #endregion #region Delegate creation // TODO: Cache created delegates public static object ConvertToDelegate(object value, Type to) { return(value is IFn fn ? (object)GenDelegate.Create(to, fn) : null); }