Skip to content

Commit 1ca3b36

Browse files
authored
Use type cache in Converter where applicable (#1462)
1 parent a4aeeda commit 1ca3b36

1 file changed

Lines changed: 27 additions & 22 deletions

File tree

Src/IronPython/Runtime/Converter.cs

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ internal static object Convert(object value, Type to) {
294294

295295
object res = site.Target(site, value);
296296
if (to.IsValueType && res == null &&
297-
(!to.IsGenericType || to.GetGenericTypeDefinition() != typeof(Nullable<>))) {
297+
(!to.IsGenericType || to.GetGenericTypeDefinition() != NullableOfTType)) {
298298
throw MakeTypeError(to, value);
299299
}
300300
return res;
@@ -408,26 +408,31 @@ private static Exception MakeTypeError(string expectedType, object o) {
408408
private static readonly Type Int32Type = typeof(int);
409409
private static readonly Type DoubleType = typeof(double);
410410
private static readonly Type DecimalType = typeof(decimal);
411-
private static readonly Type Int64Type = typeof(long);
412-
private static readonly Type UInt64Type = typeof(ulong);
413411
private static readonly Type CharType = typeof(char);
414412
private static readonly Type SingleType = typeof(float);
415413
private static readonly Type BooleanType = typeof(bool);
416414
private static readonly Type BigIntegerType = typeof(BigInteger);
417415
private static readonly Type ComplexType = typeof(Complex);
418416
private static readonly Type ExtensibleBigIntegerType = typeof(Extensible<BigInteger>);
417+
private static readonly Type ExtensibleStringType = typeof(Extensible<string>);
419418
private static readonly Type ExtensibleDoubleType = typeof(Extensible<double>);
420419
private static readonly Type ExtensibleComplexType = typeof(Extensible<Complex>);
421420
private static readonly Type DelegateType = typeof(Delegate);
422421
private static readonly Type IEnumerableType = typeof(IEnumerable);
422+
private static readonly Type IEnumeratorType = typeof(IEnumerator);
423423
private static readonly Type TypeType = typeof(Type);
424+
private static readonly Type PythonTypeType = typeof(PythonType);
425+
private static readonly Type TypeGroupType = typeof(TypeGroup);
424426
private static readonly Type NullableOfTType = typeof(Nullable<>);
425427
private static readonly Type IListOfTType = typeof(IList<>);
426428
private static readonly Type IDictOfTType = typeof(IDictionary<,>);
427429
private static readonly Type IEnumerableOfTType = typeof(IEnumerable<>);
430+
private static readonly Type IEnumeratorOfTType = typeof(IEnumerator<>);
428431
private static readonly Type IListOfObjectType = typeof(IList<object>);
429432
private static readonly Type IEnumerableOfObjectType = typeof(IEnumerable<object>);
430433
private static readonly Type IDictionaryOfObjectType = typeof(IDictionary<object, object>);
434+
private static readonly Type DynamicNullType = typeof(DynamicNull);
435+
private static readonly Type PythonTupleType = typeof(PythonTuple);
431436

432437
#endregion
433438

@@ -485,26 +490,26 @@ public static bool CanConvertFrom(Type fromType, Type toType, NarrowingLevel all
485490

486491
// Handling the hole that Type is the only object that we 'box'
487492
if (toType == TypeType &&
488-
(typeof(PythonType).IsAssignableFrom(fromType) ||
489-
typeof(TypeGroup).IsAssignableFrom(fromType))) return true;
493+
(PythonTypeType.IsAssignableFrom(fromType) ||
494+
TypeGroupType.IsAssignableFrom(fromType))) return true;
490495

491496
// Support extensible types with simple implicit conversions to their base types
492-
if (typeof(Extensible<BigInteger>).IsAssignableFrom(fromType) && CanConvertFrom(BigIntegerType, toType, allowNarrowing)) {
497+
if (ExtensibleBigIntegerType.IsAssignableFrom(fromType) && CanConvertFrom(BigIntegerType, toType, allowNarrowing)) {
493498
return true;
494499
}
495-
if (typeof(ExtensibleString).IsAssignableFrom(fromType) && CanConvertFrom(StringType, toType, allowNarrowing)) {
500+
if (ExtensibleStringType.IsAssignableFrom(fromType) && CanConvertFrom(StringType, toType, allowNarrowing)) {
496501
return true;
497502
}
498-
if (typeof(Extensible<double>).IsAssignableFrom(fromType) && CanConvertFrom(DoubleType, toType, allowNarrowing)) {
503+
if (ExtensibleDoubleType.IsAssignableFrom(fromType) && CanConvertFrom(DoubleType, toType, allowNarrowing)) {
499504
return true;
500505
}
501-
if (typeof(Extensible<Complex>).IsAssignableFrom(fromType) && CanConvertFrom(ComplexType, toType, allowNarrowing)) {
506+
if (ExtensibleComplexType.IsAssignableFrom(fromType) && CanConvertFrom(ComplexType, toType, allowNarrowing)) {
502507
return true;
503508
}
504509

505510
#if FEATURE_CUSTOM_TYPE_DESCRIPTOR
506511
// try available type conversions...
507-
object[] tcas = toType.GetCustomAttributes(typeof(TypeConverterAttribute), true);
512+
var tcas = toType.GetCustomAttributes<TypeConverterAttribute>(inherit: true);
508513
foreach (TypeConverterAttribute tca in tcas) {
509514
TypeConverter tc = GetTypeConverter(tca);
510515

@@ -537,15 +542,15 @@ private static TypeConverter GetTypeConverter(TypeConverterAttribute tca) {
537542
private static bool HasImplicitNumericConversion(Type fromType, Type toType) {
538543
if (fromType.IsEnum) return false;
539544

540-
if (fromType == typeof(BigInteger)) {
541-
if (toType == typeof(double)) return true;
542-
if (toType == typeof(Complex)) return true;
545+
if (fromType == BigIntegerType) {
546+
if (toType == DoubleType) return true;
547+
if (toType == ComplexType) return true;
543548
return false;
544549
}
545550

546-
if (fromType == typeof(bool)) {
547-
if (toType == typeof(int)) return true;
548-
return HasImplicitNumericConversion(typeof(int), toType);
551+
if (fromType == BooleanType) {
552+
if (toType == Int32Type) return true;
553+
return HasImplicitNumericConversion(Int32Type, toType);
549554
}
550555

551556
switch (fromType.GetTypeCode()) {
@@ -691,8 +696,8 @@ private static bool HasImplicitNumericConversion(Type fromType, Type toType) {
691696
}
692697

693698
public static Candidate PreferConvert(Type t1, Type t2) {
694-
if (t1 == typeof(bool) && t2 == typeof(int)) return Candidate.Two;
695-
if (t1 == typeof(decimal) && t2 == typeof(BigInteger)) return Candidate.Two;
699+
if (t1 == BooleanType && t2 == Int32Type) return Candidate.Two;
700+
if (t1 == DecimalType && t2 == BigIntegerType) return Candidate.Two;
696701

697702
switch (t1.GetTypeCode()) {
698703
case TypeCode.SByte:
@@ -761,14 +766,14 @@ private static bool HasNarrowingConversion(Type fromType, Type toType, Narrowing
761766
if (DelegateType.IsAssignableFrom(toType) && IsPythonType(fromType)) return true;
762767
if (IEnumerableType == toType && IsPythonType(fromType)) return true;
763768

764-
if (toType == typeof(IEnumerator)) {
769+
if (toType == IEnumeratorType) {
765770
if (IsPythonType(fromType)) return true;
766771
} else if (toType.IsGenericType) {
767772
Type genTo = toType.GetGenericTypeDefinition();
768773
if (genTo == IEnumerableOfTType) {
769774
return IEnumerableOfObjectType.IsAssignableFrom(fromType) ||
770775
IEnumerableType.IsAssignableFrom(fromType);
771-
} else if (genTo == typeof(System.Collections.Generic.IEnumerator<>)) {
776+
} else if (genTo == IEnumeratorOfTType) {
772777
if (IsPythonType(fromType)) return true;
773778
}
774779
}
@@ -789,7 +794,7 @@ private static bool HasNarrowingConversion(Type fromType, Type toType, Narrowing
789794
if (genTo == IListOfTType) {
790795
return IListOfObjectType.IsAssignableFrom(fromType);
791796
} else if (genTo == NullableOfTType) {
792-
if (fromType == typeof(DynamicNull) || CanConvertFrom(fromType, toType.GetGenericArguments()[0], allowNarrowing)) {
797+
if (fromType == DynamicNullType || CanConvertFrom(fromType, toType.GetGenericArguments()[0], allowNarrowing)) {
793798
return true;
794799
}
795800
} else if (genTo == IDictOfTType) {
@@ -798,7 +803,7 @@ private static bool HasNarrowingConversion(Type fromType, Type toType, Narrowing
798803
}
799804

800805
if (toType.IsArray) {
801-
return typeof(PythonTuple).IsAssignableFrom(fromType);
806+
return PythonTupleType.IsAssignableFrom(fromType);
802807
}
803808
}
804809

0 commit comments

Comments
 (0)