From fd0bcdfcfbc5d92b2a9aa64b53ef0986fd8bfe7a Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Mon, 10 Dec 2018 13:40:00 -0800 Subject: [PATCH 1/2] [Painless] Add extensive tests for def to primitive casts. --- .../java/org/elasticsearch/painless/Def.java | 132 ++++++- .../painless/BasicExpressionTests.java | 4 +- .../elasticsearch/painless/DefCastTests.java | 338 ++++++++++++++++++ 3 files changed, 457 insertions(+), 17 deletions(-) create mode 100644 modules/lang-painless/src/test/java/org/elasticsearch/painless/DefCastTests.java diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java index 867b481a2a4d7..454229f8dc2f6 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java @@ -622,23 +622,41 @@ static MethodHandle lookupIterator(Class receiverClass) { // Conversion methods for def to primitive types. public static boolean defToboolean(final Object value) { - return (boolean)value; + if (value instanceof Boolean) { + return (boolean) value; + } else { + throw new ClassCastException( + "cannot cast def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to boolean"); + } } public static byte defTobyteImplicit(final Object value) { - return (byte)value; + if (value instanceof Byte) { + return (byte)value; + } else { + throw new ClassCastException("cannot implicitly cast " + + "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to byte"); + } } public static short defToshortImplicit(final Object value) { if (value instanceof Byte) { return (byte)value; - } else { + } else if (value instanceof Short) { return (short)value; + } else { + throw new ClassCastException("cannot implicitly cast " + + "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to short"); } } public static char defTocharImplicit(final Object value) { - return (char)value; + if (value instanceof Character) { + return (char)value; + } else { + throw new ClassCastException("cannot implicitly cast " + + "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to char"); + } } public static int defTointImplicit(final Object value) { @@ -648,8 +666,11 @@ public static int defTointImplicit(final Object value) { return (short)value; } else if (value instanceof Character) { return (char)value; - } else { + } else if (value instanceof Integer) { return (int)value; + } else { + throw new ClassCastException("cannot implicitly cast " + + "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to int"); } } @@ -662,8 +683,12 @@ public static long defTolongImplicit(final Object value) { return (char)value; } else if (value instanceof Integer) { return (int)value; - } else { + } else if (value instanceof Long) { return (long)value; + } else { + throw new ClassCastException( + "cannot implicitly cast " + + "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to long"); } } @@ -678,8 +703,12 @@ public static float defTofloatImplicit(final Object value) { return (int)value; } else if (value instanceof Long) { return (long)value; - } else { + } else if (value instanceof Float) { return (float)value; + } else { + throw new ClassCastException( + "cannot implicitly cast " + + "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to float"); } } @@ -696,64 +725,137 @@ public static double defTodoubleImplicit(final Object value) { return (long)value; } else if (value instanceof Float) { return (float)value; - } else { + } else if (value instanceof Double) { return (double)value; + } else { + throw new ClassCastException("cannot implicitly " + + "cast def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to double"); } } public static byte defTobyteExplicit(final Object value) { if (value instanceof Character) { return (byte)(char)value; - } else { + } else if ( + value instanceof Byte || + value instanceof Short || + value instanceof Integer || + value instanceof Long || + value instanceof Float || + value instanceof Double + ) { return ((Number)value).byteValue(); + } else { + throw new ClassCastException("cannot explicitly cast " + + "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to byte"); } } public static short defToshortExplicit(final Object value) { if (value instanceof Character) { return (short)(char)value; - } else { + } else if ( + value instanceof Byte || + value instanceof Short || + value instanceof Integer || + value instanceof Long || + value instanceof Float || + value instanceof Double + ) { return ((Number)value).shortValue(); + } else { + throw new ClassCastException("cannot explicitly cast " + + "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to short"); } } public static char defTocharExplicit(final Object value) { if (value instanceof Character) { return (char)value; - } else { + } else if ( + value instanceof Byte || + value instanceof Short || + value instanceof Integer || + value instanceof Long || + value instanceof Float || + value instanceof Double + ) { return (char)((Number)value).intValue(); + } else { + throw new ClassCastException("cannot explicitly cast " + + "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to char"); } } public static int defTointExplicit(final Object value) { if (value instanceof Character) { return (char)value; - } else { + } else if ( + value instanceof Byte || + value instanceof Short || + value instanceof Integer || + value instanceof Long || + value instanceof Float || + value instanceof Double + ) { return ((Number)value).intValue(); + } else { + throw new ClassCastException("cannot explicitly cast " + + "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to int"); } } public static long defTolongExplicit(final Object value) { if (value instanceof Character) { return (char)value; - } else { + } else if ( + value instanceof Byte || + value instanceof Short || + value instanceof Integer || + value instanceof Long || + value instanceof Float || + value instanceof Double + ) { return ((Number)value).longValue(); + } else { + throw new ClassCastException("cannot explicitly cast " + + "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to long"); } } public static float defTofloatExplicit(final Object value) { if (value instanceof Character) { return (char)value; - } else { + } else if ( + value instanceof Byte || + value instanceof Short || + value instanceof Integer || + value instanceof Long || + value instanceof Float || + value instanceof Double + ) { return ((Number)value).floatValue(); + } else { + throw new ClassCastException("cannot explicitly cast " + + "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to float"); } } public static double defTodoubleExplicit(final Object value) { if (value instanceof Character) { return (char)value; - } else { + } else if ( + value instanceof Byte || + value instanceof Short || + value instanceof Integer || + value instanceof Long || + value instanceof Float || + value instanceof Double + ) { return ((Number)value).doubleValue(); + } else { + throw new ClassCastException("cannot explicitly cast " + + "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to double"); } } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicExpressionTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicExpressionTests.java index 6ff727d987cdd..b729c6769c50c 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicExpressionTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicExpressionTests.java @@ -115,12 +115,12 @@ public void testIllegalDefCast() { Exception exception = expectScriptThrows(ClassCastException.class, () -> { exec("def x = 1.0; int y = x; return y;"); }); - assertTrue(exception.getMessage().contains("cannot be cast")); + assertTrue(exception.getMessage().contains("cannot implicitly cast")); exception = expectScriptThrows(ClassCastException.class, () -> { exec("def x = (short)1; byte y = x; return y;"); }); - assertTrue(exception.getMessage().contains("cannot be cast")); + assertTrue(exception.getMessage().contains("cannot implicitly cast")); } public void testCat() { diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefCastTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefCastTests.java new file mode 100644 index 0000000000000..2add69989b1b8 --- /dev/null +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefCastTests.java @@ -0,0 +1,338 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.painless; + +public class DefCastTests extends ScriptTestCase { + + public void testdefTobooleanImplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; boolean b = d;")); + assertEquals(true, exec("def d = true; boolean b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (byte)0; boolean b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (short)0; boolean b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (char)0; boolean b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (int)0; boolean b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (long)0; boolean b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (float)0; boolean b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (double)0; boolean b = d;")); + assertEquals(false, exec("def d = Boolean.valueOf(false); boolean b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Byte.valueOf(0); boolean b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Short.valueOf(0); boolean b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Character.valueOf(0); boolean b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Integer.valueOf(0); boolean b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Long.valueOf(0); boolean b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Float.valueOf(0); boolean b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Double.valueOf(0); boolean b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); boolean b = d;")); + } + + public void testdefTobyteImplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; byte b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = true; byte b = d;")); + assertEquals((byte)0, exec("def d = (byte)0; byte b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (short)0; byte b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (char)0; byte b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (int)0; byte b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (long)0; byte b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (float)0; byte b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (double)0; byte b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Boolean.valueOf(true); byte b = d;")); + assertEquals((byte)0, exec("def d = Byte.valueOf(0); byte b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Short.valueOf(0); byte b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Character.valueOf(0); byte b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Integer.valueOf(0); byte b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Long.valueOf(0); byte b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Float.valueOf(0); byte b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Double.valueOf(0); byte b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); byte b = d;")); + } + + public void testdefToshortImplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; short b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = true; short b = d;")); + assertEquals((short)0, exec("def d = (byte)0; short b = d; b")); + assertEquals((short)0, exec("def d = (short)0; short b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (char)0; short b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (int)0; short b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (long)0; short b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (float)0; short b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (double)0; short b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Boolean.valueOf(true); short b = d;")); + assertEquals((short)0, exec("def d = Byte.valueOf(0); short b = d; b")); + assertEquals((short)0, exec("def d = Short.valueOf(0); short b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Character.valueOf(0); short b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Integer.valueOf(0); short b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Long.valueOf(0); short b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Float.valueOf(0); short b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Double.valueOf(0); short b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); short b = d;")); + } + + public void testdefTocharImplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; char b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = true; char b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (byte)0; char b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (short)0; char b = d;")); + assertEquals((char)0, exec("def d = (char)0; char b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (int)0; char b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (long)0; char b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (float)0; char b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (double)0; char b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Boolean.valueOf(true); char b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Byte.valueOf(0); char b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Short.valueOf(0); char b = d;")); + assertEquals((char)0, exec("def d = Character.valueOf(0); char b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Integer.valueOf(0); char b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Long.valueOf(0); char b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Float.valueOf(0); char b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Double.valueOf(0); char b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); char b = d;")); + } + + public void testdefTointImplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; int b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = true; int b = d;")); + assertEquals(0, exec("def d = (byte)0; int b = d; b")); + assertEquals(0, exec("def d = (short)0; int b = d; b")); + assertEquals(0, exec("def d = (char)0; int b = d; b")); + assertEquals(0, exec("def d = 0; int b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (long)0; int b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (float)0; int b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (double)0; int b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Boolean.valueOf(true); int b = d;")); + assertEquals(0, exec("def d = Byte.valueOf(0); int b = d; b")); + assertEquals(0, exec("def d = Short.valueOf(0); int b = d; b")); + assertEquals(0, exec("def d = Character.valueOf(0); int b = d; b")); + assertEquals(0, exec("def d = Integer.valueOf(0); int b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Long.valueOf(0); int b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Float.valueOf(0); int b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Double.valueOf(0); int b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); int b = d;")); + } + + public void testdefTolongImplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; long b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = true; long b = d;")); + assertEquals((long)0, exec("def d = (byte)0; long b = d; b")); + assertEquals((long)0, exec("def d = (short)0; long b = d; b")); + assertEquals((long)0, exec("def d = (char)0; long b = d; b")); + assertEquals((long)0, exec("def d = 0; long b = d; b")); + assertEquals((long)0, exec("def d = (long)0; long b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (float)0; long b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (double)0; long b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Boolean.valueOf(true); long b = d;")); + assertEquals((long)0, exec("def d = Byte.valueOf(0); long b = d; b")); + assertEquals((long)0, exec("def d = Short.valueOf(0); long b = d; b")); + assertEquals((long)0, exec("def d = Character.valueOf(0); long b = d; b")); + assertEquals((long)0, exec("def d = Integer.valueOf(0); long b = d; b")); + assertEquals((long)0, exec("def d = Long.valueOf(0); long b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Float.valueOf(0); long b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Double.valueOf(0); long b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); long b = d;")); + } + + public void testdefTodoubleImplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; double b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = true; double b = d;")); + assertEquals((double)0, exec("def d = (byte)0; double b = d; b")); + assertEquals((double)0, exec("def d = (short)0; double b = d; b")); + assertEquals((double)0, exec("def d = (char)0; double b = d; b")); + assertEquals((double)0, exec("def d = 0; double b = d; b")); + assertEquals((double)0, exec("def d = (long)0; double b = d; b")); + assertEquals((double)0, exec("def d = (float)0; double b = d; b")); + assertEquals((double)0, exec("def d = (double)0; double b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Boolean.valueOf(true); double b = d;")); + assertEquals((double)0, exec("def d = Byte.valueOf(0); double b = d; b")); + assertEquals((double)0, exec("def d = Short.valueOf(0); double b = d; b")); + assertEquals((double)0, exec("def d = Character.valueOf(0); double b = d; b")); + assertEquals((double)0, exec("def d = Integer.valueOf(0); double b = d; b")); + assertEquals((double)0, exec("def d = Long.valueOf(0); double b = d; b")); + assertEquals((double)0, exec("def d = Float.valueOf(0); double b = d; b")); + assertEquals((double)0, exec("def d = Double.valueOf(0); double b = d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); double b = d;")); + } + + public void testdefTobooleanExplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; boolean b = (boolean)d;")); + assertEquals(true, exec("def d = true; boolean b = (boolean)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (byte)0; boolean b = (boolean)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (short)0; boolean b = (boolean)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (char)0; boolean b = (boolean)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (int)0; boolean b = (boolean)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (long)0; boolean b = (boolean)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (float)0; boolean b = (boolean)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = (double)0; boolean b = (boolean)d;")); + assertEquals(false, exec("def d = Boolean.valueOf(false); boolean b = (boolean)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Byte.valueOf(0); boolean b = (boolean)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Short.valueOf(0); boolean b = (boolean)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Character.valueOf(0); boolean b = (boolean)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Integer.valueOf(0); boolean b = (boolean)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Long.valueOf(0); boolean b = (boolean)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Float.valueOf(0); boolean b = (boolean)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Double.valueOf(0); boolean b = (boolean)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); boolean b = (boolean)d;")); + } + + public void testdefTobyteExplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; byte b = (byte)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = true; byte b = (byte)d;")); + assertEquals((byte)0, exec("def d = (byte)0; byte b = (byte)d; b")); + assertEquals((byte)0, exec("def d = (short)0; byte b = (byte)d; b")); + assertEquals((byte)0, exec("def d = (char)0; byte b = (byte)d; b")); + assertEquals((byte)0, exec("def d = 0; byte b = (byte)d; b")); + assertEquals((byte)0, exec("def d = (long)0; byte b = (byte)d; b")); + assertEquals((byte)0, exec("def d = (float)0; byte b = (byte)d; b")); + assertEquals((byte)0, exec("def d = (double)0; byte b = (byte)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Boolean.valueOf(true); byte b = d;")); + assertEquals((byte)0, exec("def d = Byte.valueOf(0); byte b = (byte)d; b")); + assertEquals((byte)0, exec("def d = Short.valueOf(0); byte b = (byte)d; b")); + assertEquals((byte)0, exec("def d = Character.valueOf(0); byte b = (byte)d; b")); + assertEquals((byte)0, exec("def d = Integer.valueOf(0); byte b = (byte)d; b")); + assertEquals((byte)0, exec("def d = Long.valueOf(0); byte b = (byte)d; b")); + assertEquals((byte)0, exec("def d = Float.valueOf(0); byte b = (byte)d; b")); + assertEquals((byte)0, exec("def d = Double.valueOf(0); byte b = (byte)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); byte b = (byte)d;")); + } + + public void testdefToshortExplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; short b = (short)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = true; short b = (short)d;")); + assertEquals((short)0, exec("def d = (byte)0; short b = (short)d; b")); + assertEquals((short)0, exec("def d = (short)0; short b = (short)d; b")); + assertEquals((short)0, exec("def d = (char)0; short b = (short)d; b")); + assertEquals((short)0, exec("def d = 0; short b = (short)d; b")); + assertEquals((short)0, exec("def d = (long)0; short b = (short)d; b")); + assertEquals((short)0, exec("def d = (float)0; short b = (short)d; b")); + assertEquals((short)0, exec("def d = (double)0; short b = (short)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Boolean.valueOf(true); short b = d;")); + assertEquals((short)0, exec("def d = Byte.valueOf(0); short b = (short)d; b")); + assertEquals((short)0, exec("def d = Short.valueOf(0); short b = (short)d; b")); + assertEquals((short)0, exec("def d = Character.valueOf(0); short b = (short)d; b")); + assertEquals((short)0, exec("def d = Integer.valueOf(0); short b = (short)d; b")); + assertEquals((short)0, exec("def d = Long.valueOf(0); short b = (short)d; b")); + assertEquals((short)0, exec("def d = Float.valueOf(0); short b = (short)d; b")); + assertEquals((short)0, exec("def d = Double.valueOf(0); short b = (short)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); short b = (short)d;")); + } + + public void testdefTocharExplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; char b = (char)d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = true; char b = (char)d;")); + assertEquals((char)0, exec("def d = (byte)0; char b = (char)d; b")); + assertEquals((char)0, exec("def d = (short)0; char b = (char)d; b")); + assertEquals((char)0, exec("def d = (char)0; char b = (char)d; b")); + assertEquals((char)0, exec("def d = 0; char b = (char)d; b")); + assertEquals((char)0, exec("def d = (long)0; char b = (char)d; b")); + assertEquals((char)0, exec("def d = (float)0; char b = (char)d; b")); + assertEquals((char)0, exec("def d = (double)0; char b = (char)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Boolean.valueOf(true); char b = d;")); + assertEquals((char)0, exec("def d = Byte.valueOf(0); char b = (char)d; b")); + assertEquals((char)0, exec("def d = Short.valueOf(0); char b = (char)d; b")); + assertEquals((char)0, exec("def d = Character.valueOf(0); char b = (char)d; b")); + assertEquals((char)0, exec("def d = Integer.valueOf(0); char b = (char)d; b")); + assertEquals((char)0, exec("def d = Long.valueOf(0); char b = (char)d; b")); + assertEquals((char)0, exec("def d = Float.valueOf(0); char b = (char)d; b")); + assertEquals((char)0, exec("def d = Double.valueOf(0); char b = (char)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); char b = (char)d;")); + } + + public void testdefTointExplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; int b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = true; int b = (int)d;")); + assertEquals(0, exec("def d = (byte)0; int b = (int)d; b")); + assertEquals(0, exec("def d = (short)0; int b = (int)d; b")); + assertEquals(0, exec("def d = (char)0; int b = (int)d; b")); + assertEquals(0, exec("def d = 0; int b = (int)d; b")); + assertEquals(0, exec("def d = (long)0; int b = (int)d; b")); + assertEquals(0, exec("def d = (float)0; int b = (int)d; b")); + assertEquals(0, exec("def d = (double)0; int b = (int)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Boolean.valueOf(true); int b = d;")); + assertEquals(0, exec("def d = Byte.valueOf(0); int b = (int)d; b")); + assertEquals(0, exec("def d = Short.valueOf(0); int b = (int)d; b")); + assertEquals(0, exec("def d = Character.valueOf(0); int b = (int)d; b")); + assertEquals(0, exec("def d = Integer.valueOf(0); int b = (int)d; b")); + assertEquals(0, exec("def d = Long.valueOf(0); int b = (int)d; b")); + assertEquals(0, exec("def d = Float.valueOf(0); int b = (int)d; b")); + assertEquals(0, exec("def d = Double.valueOf(0); int b = (int)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); int b = (int)d;")); + } + + public void testdefTolongExplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; long b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = true; long b = (long)d;")); + assertEquals((long)0, exec("def d = (byte)0; long b = (long)d; b")); + assertEquals((long)0, exec("def d = (short)0; long b = (long)d; b")); + assertEquals((long)0, exec("def d = (char)0; long b = (long)d; b")); + assertEquals((long)0, exec("def d = 0; long b = (long)d; b")); + assertEquals((long)0, exec("def d = (long)0; long b = (long)d; b")); + assertEquals((long)0, exec("def d = (float)0; long b = (long)d; b")); + assertEquals((long)0, exec("def d = (double)0; long b = (long)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Boolean.valueOf(true); long b = d;")); + assertEquals((long)0, exec("def d = Byte.valueOf(0); long b = (long)d; b")); + assertEquals((long)0, exec("def d = Short.valueOf(0); long b = (long)d; b")); + assertEquals((long)0, exec("def d = Character.valueOf(0); long b = (long)d; b")); + assertEquals((long)0, exec("def d = Integer.valueOf(0); long b = (long)d; b")); + assertEquals((long)0, exec("def d = Long.valueOf(0); long b = (long)d; b")); + assertEquals((long)0, exec("def d = Float.valueOf(0); long b = (long)d; b")); + assertEquals((long)0, exec("def d = Double.valueOf(0); long b = (long)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); long b = (long)d;")); + } + + public void testdefTofloatExplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; float b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = true; float b = (float)d;")); + assertEquals((float)0, exec("def d = (byte)0; float b = (float)d; b")); + assertEquals((float)0, exec("def d = (short)0; float b = (float)d; b")); + assertEquals((float)0, exec("def d = (char)0; float b = (float)d; b")); + assertEquals((float)0, exec("def d = 0; float b = (float)d; b")); + assertEquals((float)0, exec("def d = (long)0; float b = (float)d; b")); + assertEquals((float)0, exec("def d = (float)0; float b = (float)d; b")); + assertEquals((float)0, exec("def d = (double)0; float b = (float)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Boolean.valueOf(true); float b = d;")); + assertEquals((float)0, exec("def d = Byte.valueOf(0); float b = (float)d; b")); + assertEquals((float)0, exec("def d = Short.valueOf(0); float b = (float)d; b")); + assertEquals((float)0, exec("def d = Character.valueOf(0); float b = (float)d; b")); + assertEquals((float)0, exec("def d = Integer.valueOf(0); float b = (float)d; b")); + assertEquals((float)0, exec("def d = Long.valueOf(0); float b = (float)d; b")); + assertEquals((float)0, exec("def d = Float.valueOf(0); float b = (float)d; b")); + assertEquals((float)0, exec("def d = Double.valueOf(0); float b = (float)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); float b = (float)d;")); + } + + public void testdefTodoubleExplicit() { + expectScriptThrows(ClassCastException.class, () -> exec("def d = 'string'; double b = d;")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = true; double b = (double)d;")); + assertEquals((double)0, exec("def d = (byte)0; double b = (double)d; b")); + assertEquals((double)0, exec("def d = (short)0; double b = (double)d; b")); + assertEquals((double)0, exec("def d = (char)0; double b = (double)d; b")); + assertEquals((double)0, exec("def d = 0; double b = (double)d; b")); + assertEquals((double)0, exec("def d = (long)0; double b = (double)d; b")); + assertEquals((double)0, exec("def d = (float)0; double b = (double)d; b")); + assertEquals((double)0, exec("def d = (double)0; double b = (double)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = Boolean.valueOf(true); double b = d;")); + assertEquals((double)0, exec("def d = Byte.valueOf(0); double b = (double)d; b")); + assertEquals((double)0, exec("def d = Short.valueOf(0); double b = (double)d; b")); + assertEquals((double)0, exec("def d = Character.valueOf(0); double b = (double)d; b")); + assertEquals((double)0, exec("def d = Integer.valueOf(0); double b = (double)d; b")); + assertEquals((double)0, exec("def d = Long.valueOf(0); double b = (double)d; b")); + assertEquals((double)0, exec("def d = Float.valueOf(0); double b = (double)d; b")); + assertEquals((double)0, exec("def d = Double.valueOf(0); double b = (double)d; b")); + expectScriptThrows(ClassCastException.class, () -> exec("def d = new ArrayList(); double b = (double)d;")); + } +} From 0d2f0e990d7d95f4308b43edcca86ea08a4355e7 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Mon, 10 Dec 2018 15:38:28 -0800 Subject: [PATCH 2/2] Removed unnecessary unbox in error messages. --- .../java/org/elasticsearch/painless/Def.java | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java index 454229f8dc2f6..496c2702a8ba8 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java @@ -728,8 +728,7 @@ public static double defTodoubleImplicit(final Object value) { } else if (value instanceof Double) { return (double)value; } else { - throw new ClassCastException("cannot implicitly " + - "cast def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to double"); + throw new ClassCastException("cannot implicitly cast def [" + value.getClass().getCanonicalName() + "] to double"); } } @@ -746,8 +745,7 @@ public static byte defTobyteExplicit(final Object value) { ) { return ((Number)value).byteValue(); } else { - throw new ClassCastException("cannot explicitly cast " + - "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to byte"); + throw new ClassCastException("cannot explicitly cast def [" + value.getClass().getCanonicalName() + "] to byte"); } } @@ -764,8 +762,7 @@ public static short defToshortExplicit(final Object value) { ) { return ((Number)value).shortValue(); } else { - throw new ClassCastException("cannot explicitly cast " + - "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to short"); + throw new ClassCastException("cannot explicitly cast def [" + value.getClass().getCanonicalName() + "] to short"); } } @@ -782,8 +779,7 @@ public static char defTocharExplicit(final Object value) { ) { return (char)((Number)value).intValue(); } else { - throw new ClassCastException("cannot explicitly cast " + - "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to char"); + throw new ClassCastException("cannot explicitly cast def [" + value.getClass().getCanonicalName() + "] to char"); } } @@ -800,8 +796,7 @@ public static int defTointExplicit(final Object value) { ) { return ((Number)value).intValue(); } else { - throw new ClassCastException("cannot explicitly cast " + - "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to int"); + throw new ClassCastException("cannot explicitly cast def [" + value.getClass().getCanonicalName() + "] to int"); } } @@ -818,8 +813,7 @@ public static long defTolongExplicit(final Object value) { ) { return ((Number)value).longValue(); } else { - throw new ClassCastException("cannot explicitly cast " + - "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to long"); + throw new ClassCastException("cannot explicitly cast def [" + value.getClass().getCanonicalName() + "] to long"); } } @@ -836,8 +830,7 @@ public static float defTofloatExplicit(final Object value) { ) { return ((Number)value).floatValue(); } else { - throw new ClassCastException("cannot explicitly cast " + - "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to float"); + throw new ClassCastException("cannot explicitly cast def [" + value.getClass().getCanonicalName() + "] to float"); } } @@ -854,8 +847,7 @@ public static double defTodoubleExplicit(final Object value) { ) { return ((Number)value).doubleValue(); } else { - throw new ClassCastException("cannot explicitly cast " + - "def [" + PainlessLookupUtility.typeToUnboxedType(value.getClass()).getCanonicalName() + "] to double"); + throw new ClassCastException("cannot explicitly cast def [" + value.getClass().getCanonicalName() + "] to double"); } }