Skip to content

Commit 00d2928

Browse files
committed
[Painless] Add def to boxed type casts (#36506)
This adds casts for the def type to all standard boxed types. Prior to this certain casts such as def [long/Long] -> Double would fail which does not follow the goals of the Painless casting model to remove the need for explicit boxing. This also creates symmetry with the casts for the newly created bridge methods being called at run-time.
1 parent 7d1cf23 commit 00d2928

File tree

5 files changed

+547
-55
lines changed

5 files changed

+547
-55
lines changed

modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,37 @@ public static PainlessCast getLegalCast(Location location, Class<?> actual, Clas
4141

4242
if (actual == def.class) {
4343
if (expected == boolean.class) {
44-
return PainlessCast.unboxTargetType(def.class, Boolean.class, explicit, boolean.class);
44+
return PainlessCast.originalTypetoTargetType(def.class, boolean.class, explicit);
4545
} else if (expected == byte.class) {
46-
return PainlessCast.unboxTargetType(def.class, Byte.class, explicit, byte.class);
46+
return PainlessCast.originalTypetoTargetType(def.class, byte.class, explicit);
4747
} else if (expected == short.class) {
48-
return PainlessCast.unboxTargetType(def.class, Short.class, explicit, short.class);
48+
return PainlessCast.originalTypetoTargetType(def.class, short.class, explicit);
4949
} else if (expected == char.class) {
50-
return PainlessCast.unboxTargetType(def.class, Character.class, explicit, char.class);
50+
return PainlessCast.originalTypetoTargetType(def.class, char.class, explicit);
5151
} else if (expected == int.class) {
52-
return PainlessCast.unboxTargetType(def.class, Integer.class, explicit, int.class);
52+
return PainlessCast.originalTypetoTargetType(def.class, int.class, explicit);
5353
} else if (expected == long.class) {
54-
return PainlessCast.unboxTargetType(def.class, Long.class, explicit, long.class);
54+
return PainlessCast.originalTypetoTargetType(def.class, long.class, explicit);
5555
} else if (expected == float.class) {
56-
return PainlessCast.unboxTargetType(def.class, Float.class, explicit, float.class);
56+
return PainlessCast.originalTypetoTargetType(def.class, float.class, explicit);
5757
} else if (expected == double.class) {
58-
return PainlessCast.unboxTargetType(def.class, Double.class, explicit, double.class);
58+
return PainlessCast.originalTypetoTargetType(def.class, double.class, explicit);
59+
} else if (expected == Boolean.class) {
60+
return PainlessCast.originalTypetoTargetType(def.class, Boolean.class, explicit);
61+
} else if (expected == Byte.class) {
62+
return PainlessCast.originalTypetoTargetType(def.class, Byte.class, explicit);
63+
} else if (expected == Short.class) {
64+
return PainlessCast.originalTypetoTargetType(def.class, Short.class, explicit);
65+
} else if (expected == Character.class) {
66+
return PainlessCast.originalTypetoTargetType(def.class, Character.class, explicit);
67+
} else if (expected == Integer.class) {
68+
return PainlessCast.originalTypetoTargetType(def.class, Integer.class, explicit);
69+
} else if (expected == Long.class) {
70+
return PainlessCast.originalTypetoTargetType(def.class, Long.class, explicit);
71+
} else if (expected == Float.class) {
72+
return PainlessCast.originalTypetoTargetType(def.class, Float.class, explicit);
73+
} else if (expected == Double.class) {
74+
return PainlessCast.originalTypetoTargetType(def.class, Double.class, explicit);
5975
}
6076
} else if (actual == Object.class) {
6177
if (expected == byte.class && explicit && internal) {

modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java

Lines changed: 124 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ static MethodHandle lookupIterator(Class<?> receiverClass) {
623623

624624
public static boolean defToboolean(final Object value) {
625625
if (value instanceof Boolean) {
626-
return (boolean) value;
626+
return (boolean)value;
627627
} else {
628628
throw new ClassCastException(
629629
"cannot cast def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to boolean");
@@ -853,11 +853,27 @@ public static double defTodoubleExplicit(final Object value) {
853853

854854
// Conversion methods for def to boxed types.
855855

856-
public static Byte defToByteImplicit(final Object value) {
856+
public static Boolean defToBoolean(final Object value) {
857857
if (value == null) {
858858
return null;
859+
} else if (value instanceof Boolean) {
860+
return (Boolean)value;
859861
} else {
862+
throw new ClassCastException("cannot implicitly cast " +
863+
"def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to " +
864+
Boolean.class.getCanonicalName());
865+
}
866+
}
867+
868+
public static Byte defToByteImplicit(final Object value) {
869+
if (value == null) {
870+
return null;
871+
} else if (value instanceof Byte) {
860872
return (Byte)value;
873+
} else {
874+
throw new ClassCastException("cannot implicitly cast " +
875+
"def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to " +
876+
Byte.class.getCanonicalName());
861877
}
862878
}
863879

@@ -866,16 +882,24 @@ public static Short defToShortImplicit(final Object value) {
866882
return null;
867883
} else if (value instanceof Byte) {
868884
return (short)(byte)value;
869-
} else {
885+
} else if (value instanceof Short) {
870886
return (Short)value;
887+
} else {
888+
throw new ClassCastException("cannot implicitly cast " +
889+
"def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to " +
890+
Short.class.getCanonicalName());
871891
}
872892
}
873893

874894
public static Character defToCharacterImplicit(final Object value) {
875895
if (value == null) {
876896
return null;
877-
} else {
897+
} else if (value instanceof Character) {
878898
return (Character)value;
899+
} else {
900+
throw new ClassCastException("cannot implicitly cast " +
901+
"def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to " +
902+
Character.class.getCanonicalName());
879903
}
880904
}
881905

@@ -888,8 +912,12 @@ public static Integer defToIntegerImplicit(final Object value) {
888912
return (int)(short)value;
889913
} else if (value instanceof Character) {
890914
return (int)(char)value;
891-
} else {
915+
} else if (value instanceof Integer) {
892916
return (Integer)value;
917+
} else {
918+
throw new ClassCastException("cannot implicitly cast " +
919+
"def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to " +
920+
Integer.class.getCanonicalName());
893921
}
894922
}
895923

@@ -904,8 +932,12 @@ public static Long defToLongImplicit(final Object value) {
904932
return (long)(char)value;
905933
} else if (value instanceof Integer) {
906934
return (long)(int)value;
907-
} else {
935+
} else if (value instanceof Long) {
908936
return (Long)value;
937+
} else {
938+
throw new ClassCastException("cannot implicitly cast " +
939+
"def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to " +
940+
Long.class.getCanonicalName());
909941
}
910942
}
911943

@@ -922,8 +954,12 @@ public static Float defToFloatImplicit(final Object value) {
922954
return (float)(int)value;
923955
} else if (value instanceof Long) {
924956
return (float)(long)value;
925-
} else {
957+
} else if (value instanceof Float) {
926958
return (Float)value;
959+
} else {
960+
throw new ClassCastException("cannot implicitly cast " +
961+
"def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to " +
962+
Float.class.getCanonicalName());
927963
}
928964
}
929965

@@ -942,8 +978,11 @@ public static Double defToDoubleImplicit(final Object value) {
942978
return (double)(long)value;
943979
} else if (value instanceof Float) {
944980
return (double)(float)value;
945-
} else {
981+
} else if (value instanceof Double) {
946982
return (Double)value;
983+
} else {
984+
throw new ClassCastException("cannot implicitly cast " +
985+
"def [" + value.getClass().getCanonicalName() + "] to " + Double.class.getCanonicalName());
947986
}
948987
}
949988

@@ -952,8 +991,18 @@ public static Byte defToByteExplicit(final Object value) {
952991
return null;
953992
} else if (value instanceof Character) {
954993
return (byte)(char)value;
955-
} else {
994+
} else if (
995+
value instanceof Byte ||
996+
value instanceof Short ||
997+
value instanceof Integer ||
998+
value instanceof Long ||
999+
value instanceof Float ||
1000+
value instanceof Double
1001+
) {
9561002
return ((Number)value).byteValue();
1003+
} else {
1004+
throw new ClassCastException("cannot explicitly cast " +
1005+
"def [" + value.getClass().getCanonicalName() + "] to " + Byte.class.getCanonicalName());
9571006
}
9581007
}
9591008

@@ -962,8 +1011,18 @@ public static Short defToShortExplicit(final Object value) {
9621011
return null;
9631012
} else if (value instanceof Character) {
9641013
return (short)(char)value;
965-
} else {
1014+
} else if (
1015+
value instanceof Byte ||
1016+
value instanceof Short ||
1017+
value instanceof Integer ||
1018+
value instanceof Long ||
1019+
value instanceof Float ||
1020+
value instanceof Double
1021+
) {
9661022
return ((Number)value).shortValue();
1023+
} else {
1024+
throw new ClassCastException("cannot explicitly cast " +
1025+
"def [" + value.getClass().getCanonicalName() + "] to " + Short.class.getCanonicalName());
9671026
}
9681027
}
9691028

@@ -972,8 +1031,18 @@ public static Character defToCharacterExplicit(final Object value) {
9721031
return null;
9731032
} else if (value instanceof Character) {
9741033
return (Character)value;
975-
} else {
1034+
} else if (
1035+
value instanceof Byte ||
1036+
value instanceof Short ||
1037+
value instanceof Integer ||
1038+
value instanceof Long ||
1039+
value instanceof Float ||
1040+
value instanceof Double
1041+
) {
9761042
return (char)((Number)value).intValue();
1043+
} else {
1044+
throw new ClassCastException("cannot explicitly cast " +
1045+
"def [" + value.getClass().getCanonicalName() + "] to " + Character.class.getCanonicalName());
9771046
}
9781047
}
9791048

@@ -982,8 +1051,18 @@ public static Integer defToIntegerExplicit(final Object value) {
9821051
return null;
9831052
} else if (value instanceof Character) {
9841053
return (int)(char)value;
985-
} else {
1054+
} else if (
1055+
value instanceof Byte ||
1056+
value instanceof Short ||
1057+
value instanceof Integer ||
1058+
value instanceof Long ||
1059+
value instanceof Float ||
1060+
value instanceof Double
1061+
) {
9861062
return ((Number)value).intValue();
1063+
} else {
1064+
throw new ClassCastException("cannot explicitly cast " +
1065+
"def [" + value.getClass().getCanonicalName() + "] to " + Integer.class.getCanonicalName());
9871066
}
9881067
}
9891068

@@ -992,8 +1071,18 @@ public static Long defToLongExplicit(final Object value) {
9921071
return null;
9931072
} else if (value instanceof Character) {
9941073
return (long)(char)value;
995-
} else {
1074+
} else if (
1075+
value instanceof Byte ||
1076+
value instanceof Short ||
1077+
value instanceof Integer ||
1078+
value instanceof Long ||
1079+
value instanceof Float ||
1080+
value instanceof Double
1081+
) {
9961082
return ((Number)value).longValue();
1083+
} else {
1084+
throw new ClassCastException("cannot explicitly cast " +
1085+
"def [" + value.getClass().getCanonicalName() + "] to " + Long.class.getCanonicalName());
9971086
}
9981087
}
9991088

@@ -1002,8 +1091,18 @@ public static Float defToFloatExplicit(final Object value) {
10021091
return null;
10031092
} else if (value instanceof Character) {
10041093
return (float)(char)value;
1005-
} else {
1094+
} else if (
1095+
value instanceof Byte ||
1096+
value instanceof Short ||
1097+
value instanceof Integer ||
1098+
value instanceof Long ||
1099+
value instanceof Float ||
1100+
value instanceof Double
1101+
) {
10061102
return ((Number)value).floatValue();
1103+
} else {
1104+
throw new ClassCastException("cannot explicitly cast " +
1105+
"def [" + value.getClass().getCanonicalName() + "] to " + Float.class.getCanonicalName());
10071106
}
10081107
}
10091108

@@ -1012,8 +1111,18 @@ public static Double defToDoubleExplicit(final Object value) {
10121111
return null;
10131112
} else if (value instanceof Character) {
10141113
return (double)(char)value;
1015-
} else {
1114+
} else if (
1115+
value instanceof Byte ||
1116+
value instanceof Short ||
1117+
value instanceof Integer ||
1118+
value instanceof Long ||
1119+
value instanceof Float ||
1120+
value instanceof Double
1121+
) {
10161122
return ((Number)value).doubleValue();
1123+
} else {
1124+
throw new ClassCastException("cannot explicitly cast " +
1125+
"def [" + value.getClass().getCanonicalName() + "] to " + Double.class.getCanonicalName());
10171126
}
10181127
}
10191128

0 commit comments

Comments
 (0)